-
Notifications
You must be signed in to change notification settings - Fork 0
fix: report an ungrouped tool's group as null to every reader (#86)
#87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
993413a
e00ea17
753abc9
41dadd6
55a9961
af2715e
6ca8d98
d4a0fd8
5e23e86
b3975d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ import { | |
| RPC_METHODS, | ||
| type EventNotification, | ||
| type EventsSinceResult, | ||
| type ToolDescriptor, | ||
| type ListedToolDescriptor, | ||
| type ToolsCallResult, | ||
| type ToolsListResult, | ||
| } from "@appduct/shared"; | ||
|
|
@@ -93,8 +93,9 @@ export type AppEvent<TPayload = unknown> = { | |
| export type AppClient<TTools = ToolMap> = { | ||
| readonly sessionId: string; | ||
|
|
||
| /** `tools.list` for this session. */ | ||
| tools(): Promise<ToolDescriptor[]>; | ||
| /** `tools.list` for this session. An entry spells an ungrouped tool's `group` as `null`, | ||
| * where a registration omits it. */ | ||
| tools(): Promise<ListedToolDescriptor[]>; | ||
|
|
||
| /** `tools.call`; rejects with a {@link AppductError} whose `type` preserves the wire error | ||
| * type verbatim (e.g. `"tool_timeout"`, `"policy_denied"`, `"session_suspended"`). */ | ||
|
|
@@ -164,7 +165,7 @@ export const makeAppClient = <TTools = ToolMap>(stream: DaemonStream, sessionId: | |
| const client = { | ||
| sessionId, | ||
|
|
||
| tools: async (): Promise<ToolDescriptor[]> => { | ||
| tools: async (): Promise<ListedToolDescriptor[]> => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should-fix. The return type now promises
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolved. |
||
| try { | ||
| // No `filter`/`limit`/`offset`: this client's public `tools()` contract is "every tool on | ||
| // this session", unchanged by `tools.list`'s daemon-side paging (added for the CLI). | ||
|
|
@@ -173,7 +174,10 @@ export const makeAppClient = <TTools = ToolMap>(stream: DaemonStream, sessionId: | |
| }); | ||
| // Unlike the CLI, this client runs no daemon version check, so it can meet a daemon from | ||
| // before `tools.list` returned `{ tools, total }` — one that still answers a bare array. | ||
| return Array.isArray(result) ? result : result.tools; | ||
| const entries = Array.isArray(result) ? result : result.tools; | ||
| // That daemon predates tool groups as well and sends no `group` key, so normalise it the | ||
| // way the daemon itself would. Callers are told every entry carries one. | ||
| return entries.map((entry) => ({ ...entry, group: entry.group ?? null })); | ||
| } catch (error) { | ||
| throw toAppductError(error); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,8 +19,8 @@ import { | |
| summarizeToolDescription, | ||
| TOOL_GROUP_PATTERN, | ||
| type EffectivePolicyDecision, | ||
| type ListedToolDescriptor, | ||
| type SessionsDescribeResult, | ||
| type ToolDescriptor, | ||
| type ToolsListEntry, | ||
| type ToolsListResult, | ||
| } from "@appduct/shared"; | ||
|
|
@@ -119,7 +119,7 @@ export const CALL_TOOL_TOOL_DESCRIPTOR = { | |
| export type ResolvedAppTool = { | ||
| sessionId: string; | ||
| alias: string; | ||
| descriptor: ToolDescriptor; | ||
| descriptor: ListedToolDescriptor; | ||
| policy: EffectivePolicyDecision; | ||
| }; | ||
|
|
||
|
|
@@ -180,15 +180,18 @@ const asRequiredString = (value: unknown, field: string): string => { | |
|
|
||
| /** Explicit pick, so a non-descriptor field on `ToolsListEntry` (today `policy`) is reported once, | ||
| * on its own key, rather than twice. */ | ||
| const toDescriptor = (entry: ToolsListEntry): ToolDescriptor => { | ||
| const toDescriptor = (entry: ToolsListEntry): ListedToolDescriptor => { | ||
| return { | ||
| name: entry.name, | ||
| description: entry.description, | ||
| input_schema: entry.input_schema, | ||
| output_schema: entry.output_schema, | ||
| annotations: entry.annotations, | ||
| timeout_ms: entry.timeout_ms, | ||
| group: entry.group, | ||
| // Normalised the same way the listing normalises it, so `appduct_describe_tool` never | ||
| // disagrees with `appduct_list_tools` about whether a tool has a group. The `?? null` also | ||
| // covers a daemon that predates groups and omits the key entirely. | ||
| group: entry.group ?? null, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit. At head nothing fails without the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolved. |
||
| }; | ||
| }; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should-fix.
packages/appduct/README.md:235still documents this asawait app.tools(); // ToolDescriptor[]. A user who annotates from the README,const tools: ToolDescriptor[] = await app.tools(), now gets TS2322:group: string | nullis not assignable togroup?: string. That README is the surface the PR template's docs checklist item names for an SDK API change (the template landed on main after this branch was cut, so the PR body does not carry the item). Change the comment toListedToolDescriptor[]and say in one clause thatgroupisnullfor an ungrouped tool.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved.
packages/appduct/README.md:235now readsListedToolDescriptor[]; an ungrouped tool's group is null, andappduct/clientexports the type (client/index.ts:26), so an annotation copied from the example compiles.