From fc46caa746a09cab3c74000e001db2f116ccba8c Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Thu, 21 Nov 2024 21:43:52 -0500 Subject: [PATCH] fix: bluesky time-bound query issues The `Bluesky` bundle's `Search Post` tool fails to search for posts when the `since` or `until` parameters are set due an error returned by the public bsky search APIs. This isn't well documented, but after some testing it was determined that this only occurs when making unauthenticated requests. To fix this issue, this change updates the Bluesky tools to make authenticated requests with a user handle and [App Password](https://bsky.app/settings/app-passwords) provided by the user via a basic auth credential tool. This change also exposes a `tags` parameter on the `Search Post` tool to make it easier for agents to search by tag. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- bluesky/credential/tool.gpt | 8 ++++++++ bluesky/src/posts.ts | 8 ++++++++ bluesky/src/tools.ts | 19 ++++++++++++++++++- bluesky/tool.gpt | 11 +++++++---- 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 bluesky/credential/tool.gpt diff --git a/bluesky/credential/tool.gpt b/bluesky/credential/tool.gpt new file mode 100644 index 00000000..3276bfb9 --- /dev/null +++ b/bluesky/credential/tool.gpt @@ -0,0 +1,8 @@ +Name: Bluesky Basic Auth Credential +Share Credential: ../../basic-auth as bluesky + with bluesky_handle as username_field and + BLUESKY_HANDLE as username_env and + bluesky_app_password as password_field and + BLUESKY_APP_PASSWORD as password_env and + "Enter your Bluesky handle and app password.\nTo generate a new app password, go to https://bsky.social/settings/app-passwords" as message +Type: credential diff --git a/bluesky/src/posts.ts b/bluesky/src/posts.ts index d239c0b8..41e7e1d2 100644 --- a/bluesky/src/posts.ts +++ b/bluesky/src/posts.ts @@ -6,10 +6,12 @@ export async function searchPosts ( since?: string, until?: string, limit?: string, + tags?: string, ): Promise { let queryParams: AppBskyFeedSearchPosts.QueryParams = { q: query ?? '', sort: 'latest', + limit: 25 } if (!query) { @@ -40,6 +42,12 @@ export async function searchPosts ( } } + if (!!tags) { + queryParams.tag = tags + .split(',') + .map(tag => tag.trim().replace(/^#/, '')) + } + const response = await agent.app.bsky.feed.searchPosts(queryParams) console.log(JSON.stringify(response.data.posts)) diff --git a/bluesky/src/tools.ts b/bluesky/src/tools.ts index f11d27f6..dcd8b45f 100644 --- a/bluesky/src/tools.ts +++ b/bluesky/src/tools.ts @@ -7,11 +7,27 @@ if (process.argv.length !== 3) { process.exit(1) } +const BLUESKY_HANDLE = process.env.BLUESKY_HANDLE +const BLUESKY_APP_PASSWORD = process.env.BLUESKY_APP_PASSWORD + const command = process.argv[2] try { + if (!BLUESKY_HANDLE) { + throw new Error('bluesky username not set') + } + + if (!BLUESKY_APP_PASSWORD) { + throw new Error('bluesky app password not set') + } + const agent = new AtpAgent({ - service: 'https://api.bsky.app' + service: 'https://bsky.social' + }) + + await agent.login({ + identifier: BLUESKY_HANDLE, + password: BLUESKY_APP_PASSWORD }) switch (command) { @@ -22,6 +38,7 @@ try { process.env.SINCE, process.env.UNTIL, process.env.LIMIT, + process.env.TAGS, ) break case 'searchUsers': diff --git a/bluesky/tool.gpt b/bluesky/tool.gpt index 46149039..cddc2b09 100644 --- a/bluesky/tool.gpt +++ b/bluesky/tool.gpt @@ -6,20 +6,23 @@ Share Tools: Search Posts, Search Users --- Name: Search Posts -Description: Search for posts on Bluesky +Description: Search for Bluesky posts +Credential: ./credential JSON Response: true Share Context: ../time Share Tools: Search Users Param: query: A Lucene query to search for posts with. -Param: since: (optional) ISO 8601 timestamp to search for posts since. Defaults to 7 days ago. -Param: until: (optional) ISO 8601 timestamp to search for posts until. Defaults to now. +Param: since: (optional) ISO 8601 UTC timestamp to search for posts since (inclusive). Defaults to 7 days ago. +Param: until: (optional) ISO 8601 UTC timestamp to search for posts until (exclusive). Defaults to now. Param: limit: (optional) The maximum number of posts to return. Must be an integer >=1 and <=100. Defaults to 25. +Param: tags: (optional) A comma separated list of tags to find posts containing any of the specified tags. For example, `#apple,#banana` will return posts that include either `#apple`, `#banana`, both. To search for posts containing multiple tags together, combine hashtags with the 'AND' operator. For instance, `#apple AND #banana,#cherry` will return posts that include both `#apple` and `#banana`, as well as posts that include `#cherry`. #!/usr/bin/env npm --silent --prefix ${GPTSCRIPT_TOOL_DIR} run tool -- searchPosts --- Name: Search Users -Description: Search for users on Bluesky +Description: Search for Bluesky users +Credential: ./credential JSON Response: true Share Context: ../time Param: query: A Lucene query to search for users with.