Skip to content

Commit aa32048

Browse files
committed
refactor(P060): drop dead loadDocument, derive ClientToolName, clean comments
- Remove unused bridge.loadDocument + LoadDocumentInput + 'LOAD_DOCUMENT' from BridgeRequestType + matching arm in getRequestTimeoutMs. The copilot demo loads documents via URL params, never via postMessage — the method had no callers. - Derive ClientToolName from `keyof typeof LLM_STATIC_TOOLS | 'submit' | 'download'`. Drop the redundant CLIENT_TOOL_NAMES array. isClientToolName uses a derived ReadonlySet for the runtime guard. CLIENT_TOOL_NAMES is no longer exported from the barrel (it was internal only). - Stale "LLM dispatcher" comment wording → "LLM tool registry" (dispatch.ts has been gone for a while).
1 parent 0d5964e commit aa32048

7 files changed

Lines changed: 21 additions & 42 deletions

File tree

copilot/src/lib/embed-bridge-adapters/client-tools/factory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ export type ClientTools = {
2828
// the consumer boundary; the Vercel AI SDK guarantees the LLM only fires
2929
// registered tools.
3030
execute: (toolName: ClientToolName, input: ToolInput) => Promise<BridgeResult<unknown>>
31-
// Type guard re-export so the consumer can branch on tool names without
32-
// importing `tools.ts` separately.
31+
// Type guard re-export so the consumer can branch on LLM tool names
32+
// without importing `tools.ts` separately.
3333
isClientToolName: typeof isClientToolName
3434
}
3535

copilot/src/lib/embed-bridge-adapters/client-tools/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ export { FINALISATION_ACTION, FINALISATION_TOOL, withFinalisationTool } from './
55
export type { MiddlewareContext, ToolMiddleware } from './middleware'
66
export { composeMiddleware } from './middleware'
77
export type { ClientToolName } from './tools'
8-
export { CLIENT_TOOL_NAMES, isClientToolName, LLM_STATIC_TOOLS } from './tools'
8+
export { isClientToolName, LLM_STATIC_TOOLS } from './tools'

copilot/src/lib/embed-bridge-adapters/client-tools/tools.ts

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ import {
1919
// name, and pulls each description verbatim from the bridge schema's
2020
// `.describe()` — no duplicated text.
2121
//
22-
// Adding a new LLM tool: add an entry to LLM_STATIC_TOOLS, add the snake
23-
// name to CLIENT_TOOL_NAMES, add a switch arm in factory.ts. The switch
24-
// is exhaustive over ClientToolName, so any addition forces a matching
25-
// arm at compile time.
22+
// Adding an LLM tool: add an entry to LLM_STATIC_TOOLS, add a switch arm
23+
// in factory.ts. The switch is exhaustive over ClientToolName, so any
24+
// addition forces a matching arm at compile time.
2625

2726
const tool = <TSchema extends z.ZodType>(inputSchema: TSchema): { description: string; inputSchema: TSchema } => ({
2827
description: inputSchema.description ?? '',
@@ -43,23 +42,17 @@ export const LLM_STATIC_TOOLS = {
4342
rotate_page: tool(RotatePageInput),
4443
} as const
4544

46-
export const CLIENT_TOOL_NAMES = [
47-
'get_fields',
48-
'get_document_content',
49-
'detect_fields',
50-
'delete_fields',
51-
'select_tool',
52-
'set_field_value',
53-
'focus_field',
54-
'go_to_page',
55-
'move_page',
56-
'delete_pages',
57-
'rotate_page',
45+
// Finalisation tools (submit / download) are mode-gated and merged in via
46+
// `withFinalisationTool` rather than living in LLM_STATIC_TOOLS, so the
47+
// type union covers both.
48+
type FinalisationToolName = 'submit' | 'download'
49+
export type ClientToolName = keyof typeof LLM_STATIC_TOOLS | FinalisationToolName
50+
51+
const ALL_CLIENT_TOOL_NAMES: ReadonlySet<string> = new Set<ClientToolName>([
52+
...(Object.keys(LLM_STATIC_TOOLS) as Array<keyof typeof LLM_STATIC_TOOLS>),
5853
'submit',
5954
'download',
60-
] as const
61-
62-
export type ClientToolName = (typeof CLIENT_TOOL_NAMES)[number]
55+
])
6356

6457
export const isClientToolName = (value: unknown): value is ClientToolName =>
65-
typeof value === 'string' && CLIENT_TOOL_NAMES.some((candidate) => candidate === value)
58+
typeof value === 'string' && ALL_CLIENT_TOOL_NAMES.has(value)

copilot/src/lib/embed-bridge/bridge.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
FocusFieldInput,
77
GetDocumentContentInput,
88
GoToInput,
9-
LoadDocumentInput,
109
MovePageInput,
1110
RotatePageInput,
1211
SelectToolInput,
@@ -52,7 +51,6 @@ const getRequestTimeoutMs = (requestType: BridgeRequestType): number => {
5251
case 'GET_FIELDS':
5352
case 'DOWNLOAD':
5453
case 'GO_TO':
55-
case 'LOAD_DOCUMENT':
5654
case 'MOVE_PAGE':
5755
case 'ROTATE_PAGE':
5856
case 'SELECT_TOOL':
@@ -385,7 +383,7 @@ export const createBridge = ({
385383

386384
// The bridge OWNS validation: each method validates its `unknown` input
387385
// against the schema in schemas.ts before posting to the iframe. The
388-
// adapter layer (LLM dispatcher, React SDK, etc.) is therefore a pure
386+
// adapter layer (LLM tool registry, React SDK, etc.) is therefore a pure
389387
// router — no parse, no narrowing. Adding a new method = add a schema in
390388
// schemas.ts, add a method on IframeBridge, and add a `parseAndSend` line
391389
// here.
@@ -405,7 +403,6 @@ export const createBridge = ({
405403
}
406404
const bridge: IframeBridge = {
407405
getState: () => state,
408-
loadDocument: (args) => parseAndSend(LoadDocumentInput, 'LOAD_DOCUMENT', args),
409406
getFields: () => sendRequest<{ fields: FieldRecord[] }>('GET_FIELDS', {}),
410407
getDocumentContent: (args) => parseAndSend<typeof GetDocumentContentInput, DocumentContentResult>(
411408
GetDocumentContentInput,

copilot/src/lib/embed-bridge/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export {
1111
GetDocumentContentInput,
1212
GetFieldsInput,
1313
GoToInput,
14-
LoadDocumentInput,
1514
MovePageInput,
1615
NoInput,
1716
RotatePageInput,

copilot/src/lib/embed-bridge/schemas.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,3 @@ export const SubmitInput = z
9898
export const DownloadInput = NoInput.describe(
9999
'Finalizes the filled PDF and triggers an in-browser download for the user. Use only when the user asks to download.',
100100
)
101-
102-
export const LoadDocumentInput = z
103-
.object({
104-
data_url: z.string(),
105-
name: z.string().optional(),
106-
page: z.number().int().positive().optional(),
107-
})
108-
.describe('Loads a PDF document into the editor by URL or data-URL.')

copilot/src/lib/embed-bridge/types.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ export type BridgeState =
7474
// Request type union. Every postMessage the bridge sends carries one of these
7575
// as its `type` field. The editor honours each.
7676
export type BridgeRequestType =
77-
| 'LOAD_DOCUMENT'
7877
| 'GO_TO'
7978
| 'SELECT_TOOL'
8079
| 'DETECT_FIELDS'
@@ -92,14 +91,13 @@ export type BridgeRequestType =
9291
export type FocusFieldResult = { hint: { type: 'user_action_expected'; message: string } } | null
9392

9493
// The bridge owns the contract. Each method takes `unknown` (raw, from any
95-
// caller — the LLM dispatcher, direct UI code, etc.) and validates it
96-
// internally against the matching Zod schema in schemas.ts before posting
97-
// to the iframe. Bad input surfaces as `{ success: false, error: { code:
98-
// 'bad_input', ... } }` without a postMessage round-trip. Adapters do not
94+
// caller) and validates it internally against the matching Zod schema in
95+
// schemas.ts before posting to the iframe. Bad input surfaces as
96+
// `{ success: false, error: { code: 'bad_input', ... } }` without a
97+
// postMessage round-trip. Adapters (LLM tool registry, etc.) do not
9998
// re-validate.
10099
export type IframeBridge = {
101100
getState: () => BridgeState
102-
loadDocument: (args: unknown) => Promise<BridgeResult>
103101
getFields: () => Promise<BridgeResult<{ fields: FieldRecord[] }>>
104102
getDocumentContent: (args: unknown) => Promise<BridgeResult<DocumentContentResult>>
105103
detectFields: () => Promise<BridgeResult<{ detected_count: number }>>

0 commit comments

Comments
 (0)