@assistant-ui/react 0.11.22 → 0.11.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/types/Part.d.ts +2 -2
- package/dist/legacy-runtime/runtime/MessagePartRuntime.d.ts +2 -2
- package/dist/legacy-runtime/runtime/MessagePartRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts +4 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js +10 -10
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +2 -2
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
- package/dist/model-context/frame/AssistantFrameProvider.js +2 -2
- package/dist/model-context/frame/AssistantFrameProvider.js.map +1 -1
- package/dist/types/MessagePartTypes.d.ts +4 -1
- package/dist/types/MessagePartTypes.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client/types/Part.ts +2 -2
- package/src/legacy-runtime/runtime/MessagePartRuntime.ts +2 -2
- package/src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts +12 -12
- package/src/legacy-runtime/runtime-cores/external-store/auto-status.tsx +4 -4
- package/src/model-context/frame/AssistantFrameProvider.ts +2 -2
- package/src/types/MessagePartTypes.ts +1 -1
@@ -14,8 +14,8 @@ export type MessagePartClientApi = {
|
|
14
14
|
*/
|
15
15
|
addToolResult(result: any | ToolResponse<any>): void;
|
16
16
|
/**
|
17
|
-
* Resume
|
18
|
-
* This is useful when a tool has
|
17
|
+
* Resume a tool call that is waiting for human input with a payload.
|
18
|
+
* This is useful when a tool has requested human input and is waiting for a response.
|
19
19
|
*/
|
20
20
|
resumeToolCall(payload: unknown): void;
|
21
21
|
};
|
@@ -16,8 +16,8 @@ export type MessagePartRuntime = {
|
|
16
16
|
*/
|
17
17
|
addToolResult(result: any | ToolResponse<any>): void;
|
18
18
|
/**
|
19
|
-
* Resume
|
20
|
-
* This is useful when a tool has
|
19
|
+
* Resume a tool call that is waiting for human input with a payload.
|
20
|
+
* This is useful when a tool has requested human input and is waiting for a response.
|
21
21
|
*/
|
22
22
|
resumeToolCall(payload: unknown): void;
|
23
23
|
readonly path: MessagePartRuntimePath;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/legacy-runtime/runtime/MessagePartRuntime.ts"],"sourcesContent":["import {\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n MessagePartStatus,\n ToolCallMessagePartStatus,\n} from \"../../types/AssistantTypes\";\nimport { ThreadRuntimeCoreBinding } from \"./ThreadRuntime\";\nimport type { MessageStateBinding } from \"./RuntimeBindings\";\nimport { SubscribableWithState } from \"./subscribable/Subscribable\";\nimport { Unsubscribe } from \"../../types\";\nimport { MessagePartRuntimePath } from \"./RuntimePathTypes\";\nimport { ToolResponse } from \"assistant-stream\";\n\nexport type MessagePartState = (\n | ThreadUserMessagePart\n | ThreadAssistantMessagePart\n) & {\n readonly status: MessagePartStatus | ToolCallMessagePartStatus;\n};\n\ntype MessagePartSnapshotBinding = SubscribableWithState<\n MessagePartState,\n MessagePartRuntimePath\n>;\n\nexport type MessagePartRuntime = {\n /**\n * Add tool result to a tool call message part that has no tool result yet.\n * This is useful when you are collecting a tool result via user input (\"human tool calls\").\n */\n addToolResult(result: any | ToolResponse<any>): void;\n\n /**\n * Resume
|
1
|
+
{"version":3,"sources":["../../../src/legacy-runtime/runtime/MessagePartRuntime.ts"],"sourcesContent":["import {\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n MessagePartStatus,\n ToolCallMessagePartStatus,\n} from \"../../types/AssistantTypes\";\nimport { ThreadRuntimeCoreBinding } from \"./ThreadRuntime\";\nimport type { MessageStateBinding } from \"./RuntimeBindings\";\nimport { SubscribableWithState } from \"./subscribable/Subscribable\";\nimport { Unsubscribe } from \"../../types\";\nimport { MessagePartRuntimePath } from \"./RuntimePathTypes\";\nimport { ToolResponse } from \"assistant-stream\";\n\nexport type MessagePartState = (\n | ThreadUserMessagePart\n | ThreadAssistantMessagePart\n) & {\n readonly status: MessagePartStatus | ToolCallMessagePartStatus;\n};\n\ntype MessagePartSnapshotBinding = SubscribableWithState<\n MessagePartState,\n MessagePartRuntimePath\n>;\n\nexport type MessagePartRuntime = {\n /**\n * Add tool result to a tool call message part that has no tool result yet.\n * This is useful when you are collecting a tool result via user input (\"human tool calls\").\n */\n addToolResult(result: any | ToolResponse<any>): void;\n\n /**\n * Resume a tool call that is waiting for human input with a payload.\n * This is useful when a tool has requested human input and is waiting for a response.\n */\n resumeToolCall(payload: unknown): void;\n\n readonly path: MessagePartRuntimePath;\n getState(): MessagePartState;\n subscribe(callback: () => void): Unsubscribe;\n};\n\nexport class MessagePartRuntimeImpl implements MessagePartRuntime {\n public get path() {\n return this.contentBinding.path;\n }\n\n constructor(\n private contentBinding: MessagePartSnapshotBinding,\n private messageApi?: MessageStateBinding,\n private threadApi?: ThreadRuntimeCoreBinding,\n ) {\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.addToolResult = this.addToolResult.bind(this);\n this.resumeToolCall = this.resumeToolCall.bind(this);\n this.getState = this.getState.bind(this);\n this.subscribe = this.subscribe.bind(this);\n }\n\n public getState() {\n return this.contentBinding.getState();\n }\n\n public addToolResult(result: any | ToolResponse<any>) {\n const state = this.contentBinding.getState();\n if (!state) throw new Error(\"Message part is not available\");\n\n if (state.type !== \"tool-call\")\n throw new Error(\"Tried to add tool result to non-tool message part\");\n\n if (!this.messageApi)\n throw new Error(\n \"Message API is not available. This is likely a bug in assistant-ui.\",\n );\n if (!this.threadApi) throw new Error(\"Thread API is not available\");\n\n const message = this.messageApi.getState();\n if (!message) throw new Error(\"Message is not available\");\n\n const toolName = state.toolName;\n const toolCallId = state.toolCallId;\n\n const response = ToolResponse.toResponse(result);\n this.threadApi.getState().addToolResult({\n messageId: message.id,\n toolName,\n toolCallId,\n result: response.result,\n artifact: response.artifact,\n isError: response.isError,\n });\n }\n\n public resumeToolCall(payload: unknown) {\n const state = this.contentBinding.getState();\n if (!state) throw new Error(\"Message part is not available\");\n\n if (state.type !== \"tool-call\")\n throw new Error(\"Tried to resume tool call on non-tool message part\");\n\n if (!this.threadApi) throw new Error(\"Thread API is not available\");\n\n const toolCallId = state.toolCallId;\n this.threadApi.getState().resumeToolCall({\n toolCallId,\n payload,\n });\n }\n\n public subscribe(callback: () => void) {\n return this.contentBinding.subscribe(callback);\n }\n}\n"],"mappings":";AAWA,SAAS,oBAAoB;AAgCtB,IAAM,yBAAN,MAA2D;AAAA,EAKhE,YACU,gBACA,YACA,WACR;AAHQ;AACA;AACA;AAER,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAVA,IAAW,OAAO;AAChB,WAAO,KAAK,eAAe;AAAA,EAC7B;AAAA,EAUU,yBAAyB;AACjC,SAAK,gBAAgB,KAAK,cAAc,KAAK,IAAI;AACjD,SAAK,iBAAiB,KAAK,eAAe,KAAK,IAAI;AACnD,SAAK,WAAW,KAAK,SAAS,KAAK,IAAI;AACvC,SAAK,YAAY,KAAK,UAAU,KAAK,IAAI;AAAA,EAC3C;AAAA,EAEO,WAAW;AAChB,WAAO,KAAK,eAAe,SAAS;AAAA,EACtC;AAAA,EAEO,cAAc,QAAiC;AACpD,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,+BAA+B;AAE3D,QAAI,MAAM,SAAS;AACjB,YAAM,IAAI,MAAM,mDAAmD;AAErE,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AACF,QAAI,CAAC,KAAK,UAAW,OAAM,IAAI,MAAM,6BAA6B;AAElE,UAAM,UAAU,KAAK,WAAW,SAAS;AACzC,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,0BAA0B;AAExD,UAAM,WAAW,MAAM;AACvB,UAAM,aAAa,MAAM;AAEzB,UAAM,WAAW,aAAa,WAAW,MAAM;AAC/C,SAAK,UAAU,SAAS,EAAE,cAAc;AAAA,MACtC,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,MACA,QAAQ,SAAS;AAAA,MACjB,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EAEO,eAAe,SAAkB;AACtC,UAAM,QAAQ,KAAK,eAAe,SAAS;AAC3C,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,+BAA+B;AAE3D,QAAI,MAAM,SAAS;AACjB,YAAM,IAAI,MAAM,oDAAoD;AAEtE,QAAI,CAAC,KAAK,UAAW,OAAM,IAAI,MAAM,6BAA6B;AAElE,UAAM,aAAa,MAAM;AACzB,SAAK,UAAU,SAAS,EAAE,eAAe;AAAA,MACvC;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEO,UAAU,UAAsB;AACrC,WAAO,KAAK,eAAe,UAAU,QAAQ;AAAA,EAC/C;AACF;","names":[]}
|
@@ -10,7 +10,10 @@ export type ToolExecutionStatus = {
|
|
10
10
|
type: "executing";
|
11
11
|
} | {
|
12
12
|
type: "interrupt";
|
13
|
-
payload:
|
13
|
+
payload: {
|
14
|
+
type: "human";
|
15
|
+
payload: unknown;
|
16
|
+
};
|
14
17
|
};
|
15
18
|
export declare function useToolInvocations({ state, getTools, onResult, setToolStatuses, }: UseToolInvocationsParams): {
|
16
19
|
reset: () => void;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"useToolInvocations.d.ts","sourceRoot":"","sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,IAAI,EACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAejB,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,uBAAuB,CAAC;IAC/B,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC;IACjD,QAAQ,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IACvD,eAAe,EAAE,CACf,OAAO,EACH,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GACnC,CAAC,CACC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,KACtC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,KAC1C,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;
|
1
|
+
{"version":3,"file":"useToolInvocations.d.ts","sourceRoot":"","sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,IAAI,EACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAejB,KAAK,wBAAwB,GAAG;IAC9B,KAAK,EAAE,uBAAuB,CAAC;IAC/B,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC;IACjD,QAAQ,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,IAAI,CAAC;IACvD,eAAe,EAAE,CACf,OAAO,EACH,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,GACnC,CAAC,CACC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,KACtC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,KAC1C,IAAI,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,CAAC;AAExE,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,eAAe,GAChB,EAAE,wBAAwB;;;yBAgLF,MAAM,WAAW,OAAO;EAehD"}
|
@@ -23,7 +23,7 @@ function useToolInvocations({
|
|
23
23
|
setToolStatuses
|
24
24
|
}) {
|
25
25
|
const lastToolStates = useRef({});
|
26
|
-
const
|
26
|
+
const humanInputRef = useRef(/* @__PURE__ */ new Map());
|
27
27
|
const acRef = useRef(new AbortController());
|
28
28
|
const [controller] = useState(() => {
|
29
29
|
const [stream, controller2] = createAssistantStreamController();
|
@@ -32,16 +32,16 @@ function useToolInvocations({
|
|
32
32
|
() => acRef.current?.signal ?? new AbortController().signal,
|
33
33
|
(toolCallId, payload) => {
|
34
34
|
return new Promise((resolve, reject) => {
|
35
|
-
const previous =
|
35
|
+
const previous = humanInputRef.current.get(toolCallId);
|
36
36
|
if (previous) {
|
37
37
|
previous.reject(
|
38
|
-
new Error("
|
38
|
+
new Error("Human input request was superseded by a new request")
|
39
39
|
);
|
40
40
|
}
|
41
|
-
|
41
|
+
humanInputRef.current.set(toolCallId, { resolve, reject });
|
42
42
|
setToolStatuses((prev) => ({
|
43
43
|
...prev,
|
44
|
-
[toolCallId]: { type: "interrupt", payload }
|
44
|
+
[toolCallId]: { type: "interrupt", payload: { type: "human", payload } }
|
45
45
|
}));
|
46
46
|
});
|
47
47
|
}
|
@@ -143,10 +143,10 @@ function useToolInvocations({
|
|
143
143
|
}
|
144
144
|
}, [state, controller, onResult]);
|
145
145
|
const abort = () => {
|
146
|
-
|
146
|
+
humanInputRef.current.forEach(({ reject }) => {
|
147
147
|
reject(new Error("Tool execution aborted"));
|
148
148
|
});
|
149
|
-
|
149
|
+
humanInputRef.current.clear();
|
150
150
|
setToolStatuses({});
|
151
151
|
acRef.current.abort();
|
152
152
|
acRef.current = new AbortController();
|
@@ -158,9 +158,9 @@ function useToolInvocations({
|
|
158
158
|
},
|
159
159
|
abort,
|
160
160
|
resume: (toolCallId, payload) => {
|
161
|
-
const handlers =
|
161
|
+
const handlers = humanInputRef.current.get(toolCallId);
|
162
162
|
if (handlers) {
|
163
|
-
|
163
|
+
humanInputRef.current.delete(toolCallId);
|
164
164
|
setToolStatuses((prev) => {
|
165
165
|
const next = { ...prev };
|
166
166
|
delete next[toolCallId];
|
@@ -168,7 +168,7 @@ function useToolInvocations({
|
|
168
168
|
});
|
169
169
|
handlers.resolve(payload);
|
170
170
|
} else {
|
171
|
-
throw new Error(`Tool call ${toolCallId} is not
|
171
|
+
throw new Error(`Tool call ${toolCallId} is not waiting for human input`);
|
172
172
|
}
|
173
173
|
}
|
174
174
|
};
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n createAssistantStreamController,\n ToolCallStreamController,\n ToolResponse,\n unstable_toolResultStream,\n type Tool,\n} from \"assistant-stream\";\nimport type {\n AssistantTransportCommand,\n AssistantTransportState,\n} from \"./types\";\nimport {\n AssistantMetaTransformStream,\n type ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\n\nconst isArgsTextComplete = (argsText: string) => {\n try {\n JSON.parse(argsText);\n return true;\n } catch {\n return false;\n }\n};\n\ntype UseToolInvocationsParams = {\n state: AssistantTransportState;\n getTools: () => Record<string, Tool> | undefined;\n onResult: (command: AssistantTransportCommand) => void;\n setToolStatuses: (\n updater:\n | Record<string, ToolExecutionStatus>\n | ((\n prev: Record<string, ToolExecutionStatus>,\n ) => Record<string, ToolExecutionStatus>),\n ) => void;\n};\n\nexport type ToolExecutionStatus =\n | { type: \"executing\" }\n | { type: \"interrupt\"; payload: unknown };\n\nexport function useToolInvocations({\n state,\n getTools,\n onResult,\n setToolStatuses,\n}: UseToolInvocationsParams) {\n const lastToolStates = useRef<\n Record<\n string,\n {\n argsText: string;\n hasResult: boolean;\n controller: ToolCallStreamController;\n }\n >\n >({});\n\n const interruptedToolsRef = useRef<\n Map<\n string,\n {\n resolve: (payload: unknown) => void;\n reject: (reason: unknown) => void;\n }\n >\n >(new Map());\n\n const acRef = useRef<AbortController>(new AbortController());\n const [controller] = useState(() => {\n const [stream, controller] = createAssistantStreamController();\n const transform = unstable_toolResultStream(\n getTools,\n () => acRef.current?.signal ?? new AbortController().signal,\n (toolCallId: string, payload: unknown) => {\n return new Promise<unknown>((resolve, reject) => {\n // Reject previous interrupt if it exists\n const previous = interruptedToolsRef.current.get(toolCallId);\n if (previous) {\n previous.reject(\n new Error(\"Interrupt was superseded by a new interrupt\"),\n );\n }\n\n interruptedToolsRef.current.set(toolCallId, { resolve, reject });\n setToolStatuses((prev) => ({\n ...prev,\n [toolCallId]: { type: \"interrupt\", payload },\n }));\n });\n },\n );\n stream\n .pipeThrough(transform)\n .pipeThrough(new AssistantMetaTransformStream())\n .pipeTo(\n new WritableStream({\n write(chunk) {\n if (chunk.type === \"result\") {\n // the tool call result was already set by the backend\n if (lastToolStates.current[chunk.meta.toolCallId]?.hasResult)\n return;\n\n onResult({\n type: \"add-tool-result\",\n toolCallId: chunk.meta.toolCallId,\n toolName: chunk.meta.toolName,\n result: chunk.result,\n isError: chunk.isError,\n ...(chunk.artifact && { artifact: chunk.artifact }),\n });\n\n // Clear status when result is set\n setToolStatuses((prev) => {\n const next = { ...prev };\n delete next[chunk.meta.toolCallId];\n return next;\n });\n }\n },\n }),\n );\n\n return controller;\n });\n\n const ignoredToolIds = useRef<Set<string>>(new Set());\n const isInititialState = useRef(true);\n\n useEffect(() => {\n if (isInititialState.current) {\n state.messages.forEach((message) => {\n message.content.forEach((content) => {\n if (content.type === \"tool-call\") {\n ignoredToolIds.current.add(content.toolCallId);\n }\n });\n });\n isInititialState.current = false;\n } else {\n state.messages.forEach((message) => {\n message.content.forEach((content) => {\n if (content.type === \"tool-call\") {\n if (ignoredToolIds.current.has(content.toolCallId)) {\n return;\n }\n let lastState = lastToolStates.current[content.toolCallId];\n if (!lastState) {\n const toolCallController = controller.addToolCallPart({\n toolName: content.toolName,\n toolCallId: content.toolCallId,\n });\n lastState = {\n argsText: \"\",\n hasResult: false,\n controller: toolCallController,\n };\n lastToolStates.current[content.toolCallId] = lastState;\n }\n\n if (content.argsText !== lastState.argsText) {\n if (!content.argsText.startsWith(lastState.argsText)) {\n throw new Error(\n `Tool call argsText can only be appended, not updated: ${content.argsText} does not start with ${lastState.argsText}`,\n );\n }\n\n const argsTextDelta = content.argsText.slice(\n lastState.argsText.length,\n );\n lastState.controller.argsText.append(argsTextDelta);\n\n if (isArgsTextComplete(content.argsText)) {\n lastState.controller.argsText.close();\n }\n\n lastToolStates.current[content.toolCallId] = {\n argsText: content.argsText,\n hasResult: lastState.hasResult,\n controller: lastState.controller,\n };\n }\n\n if (content.result !== undefined && !lastState.hasResult) {\n lastState.controller.setResponse(\n new ToolResponse({\n result: content.result as ReadonlyJSONValue,\n artifact: content.artifact as ReadonlyJSONValue | undefined,\n isError: content.isError,\n }),\n );\n lastState.controller.close();\n\n lastToolStates.current[content.toolCallId] = {\n hasResult: true,\n argsText: lastState.argsText,\n controller: lastState.controller,\n };\n }\n }\n });\n });\n }\n }, [state, controller, onResult]);\n\n const abort = () => {\n interruptedToolsRef.current.forEach(({ reject }) => {\n reject(new Error(\"Tool execution aborted\"));\n });\n interruptedToolsRef.current.clear();\n setToolStatuses({});\n\n acRef.current.abort();\n acRef.current = new AbortController();\n };\n\n return {\n reset: () => {\n abort();\n isInititialState.current = true;\n },\n abort,\n resume: (toolCallId: string, payload: unknown) => {\n const handlers = interruptedToolsRef.current.get(toolCallId);\n if (handlers) {\n interruptedToolsRef.current.delete(toolCallId);\n setToolStatuses((prev) => {\n const next = { ...prev };\n delete next[toolCallId];\n return next;\n });\n handlers.resolve(payload);\n } else {\n throw new Error(`Tool call ${toolCallId} is not interrupted`);\n }\n },\n };\n}\n"],"mappings":"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","names":["controller"]}
|
1
|
+
{"version":3,"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n createAssistantStreamController,\n ToolCallStreamController,\n ToolResponse,\n unstable_toolResultStream,\n type Tool,\n} from \"assistant-stream\";\nimport type {\n AssistantTransportCommand,\n AssistantTransportState,\n} from \"./types\";\nimport {\n AssistantMetaTransformStream,\n type ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\n\nconst isArgsTextComplete = (argsText: string) => {\n try {\n JSON.parse(argsText);\n return true;\n } catch {\n return false;\n }\n};\n\ntype UseToolInvocationsParams = {\n state: AssistantTransportState;\n getTools: () => Record<string, Tool> | undefined;\n onResult: (command: AssistantTransportCommand) => void;\n setToolStatuses: (\n updater:\n | Record<string, ToolExecutionStatus>\n | ((\n prev: Record<string, ToolExecutionStatus>,\n ) => Record<string, ToolExecutionStatus>),\n ) => void;\n};\n\nexport type ToolExecutionStatus =\n | { type: \"executing\" }\n | { type: \"interrupt\"; payload: { type: \"human\"; payload: unknown } };\n\nexport function useToolInvocations({\n state,\n getTools,\n onResult,\n setToolStatuses,\n}: UseToolInvocationsParams) {\n const lastToolStates = useRef<\n Record<\n string,\n {\n argsText: string;\n hasResult: boolean;\n controller: ToolCallStreamController;\n }\n >\n >({});\n\n const humanInputRef = useRef<\n Map<\n string,\n {\n resolve: (payload: unknown) => void;\n reject: (reason: unknown) => void;\n }\n >\n >(new Map());\n\n const acRef = useRef<AbortController>(new AbortController());\n const [controller] = useState(() => {\n const [stream, controller] = createAssistantStreamController();\n const transform = unstable_toolResultStream(\n getTools,\n () => acRef.current?.signal ?? new AbortController().signal,\n (toolCallId: string, payload: unknown) => {\n return new Promise<unknown>((resolve, reject) => {\n // Reject previous human input request if it exists\n const previous = humanInputRef.current.get(toolCallId);\n if (previous) {\n previous.reject(\n new Error(\"Human input request was superseded by a new request\"),\n );\n }\n\n humanInputRef.current.set(toolCallId, { resolve, reject });\n setToolStatuses((prev) => ({\n ...prev,\n [toolCallId]: { type: \"interrupt\", payload: { type: \"human\", payload } },\n }));\n });\n },\n );\n stream\n .pipeThrough(transform)\n .pipeThrough(new AssistantMetaTransformStream())\n .pipeTo(\n new WritableStream({\n write(chunk) {\n if (chunk.type === \"result\") {\n // the tool call result was already set by the backend\n if (lastToolStates.current[chunk.meta.toolCallId]?.hasResult)\n return;\n\n onResult({\n type: \"add-tool-result\",\n toolCallId: chunk.meta.toolCallId,\n toolName: chunk.meta.toolName,\n result: chunk.result,\n isError: chunk.isError,\n ...(chunk.artifact && { artifact: chunk.artifact }),\n });\n\n // Clear status when result is set\n setToolStatuses((prev) => {\n const next = { ...prev };\n delete next[chunk.meta.toolCallId];\n return next;\n });\n }\n },\n }),\n );\n\n return controller;\n });\n\n const ignoredToolIds = useRef<Set<string>>(new Set());\n const isInititialState = useRef(true);\n\n useEffect(() => {\n if (isInititialState.current) {\n state.messages.forEach((message) => {\n message.content.forEach((content) => {\n if (content.type === \"tool-call\") {\n ignoredToolIds.current.add(content.toolCallId);\n }\n });\n });\n isInititialState.current = false;\n } else {\n state.messages.forEach((message) => {\n message.content.forEach((content) => {\n if (content.type === \"tool-call\") {\n if (ignoredToolIds.current.has(content.toolCallId)) {\n return;\n }\n let lastState = lastToolStates.current[content.toolCallId];\n if (!lastState) {\n const toolCallController = controller.addToolCallPart({\n toolName: content.toolName,\n toolCallId: content.toolCallId,\n });\n lastState = {\n argsText: \"\",\n hasResult: false,\n controller: toolCallController,\n };\n lastToolStates.current[content.toolCallId] = lastState;\n }\n\n if (content.argsText !== lastState.argsText) {\n if (!content.argsText.startsWith(lastState.argsText)) {\n throw new Error(\n `Tool call argsText can only be appended, not updated: ${content.argsText} does not start with ${lastState.argsText}`,\n );\n }\n\n const argsTextDelta = content.argsText.slice(\n lastState.argsText.length,\n );\n lastState.controller.argsText.append(argsTextDelta);\n\n if (isArgsTextComplete(content.argsText)) {\n lastState.controller.argsText.close();\n }\n\n lastToolStates.current[content.toolCallId] = {\n argsText: content.argsText,\n hasResult: lastState.hasResult,\n controller: lastState.controller,\n };\n }\n\n if (content.result !== undefined && !lastState.hasResult) {\n lastState.controller.setResponse(\n new ToolResponse({\n result: content.result as ReadonlyJSONValue,\n artifact: content.artifact as ReadonlyJSONValue | undefined,\n isError: content.isError,\n }),\n );\n lastState.controller.close();\n\n lastToolStates.current[content.toolCallId] = {\n hasResult: true,\n argsText: lastState.argsText,\n controller: lastState.controller,\n };\n }\n }\n });\n });\n }\n }, [state, controller, onResult]);\n\n const abort = () => {\n humanInputRef.current.forEach(({ reject }) => {\n reject(new Error(\"Tool execution aborted\"));\n });\n humanInputRef.current.clear();\n setToolStatuses({});\n\n acRef.current.abort();\n acRef.current = new AbortController();\n };\n\n return {\n reset: () => {\n abort();\n isInititialState.current = true;\n },\n abort,\n resume: (toolCallId: string, payload: unknown) => {\n const handlers = humanInputRef.current.get(toolCallId);\n if (handlers) {\n humanInputRef.current.delete(toolCallId);\n setToolStatuses((prev) => {\n const next = { ...prev };\n delete next[toolCallId];\n return next;\n });\n handlers.resolve(payload);\n } else {\n throw new Error(`Tool call ${toolCallId} is not waiting for human input`);\n }\n },\n };\n}\n"],"mappings":"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","names":["controller"]}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { MessageStatus } from "../../../types";
|
2
2
|
export declare const isAutoStatus: (status: MessageStatus) => boolean;
|
3
|
-
export declare const getAutoStatus: (isLast: boolean, isRunning: boolean,
|
3
|
+
export declare const getAutoStatus: (isLast: boolean, isRunning: boolean, hasInterruptedToolCalls: boolean, hasPendingToolCalls: boolean) => Readonly<{
|
4
4
|
type: "running";
|
5
5
|
}> | Readonly<{
|
6
6
|
type: "complete";
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"auto-status.d.ts","sourceRoot":"","sources":["../../../../src/legacy-runtime/runtime-cores/external-store/auto-status.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkB/C,eAAO,MAAM,YAAY,GAAI,QAAQ,aAAa,YACiB,CAAC;AAEpE,eAAO,MAAM,aAAa,GACxB,QAAQ,OAAO,EACf,WAAW,OAAO,EAClB,
|
1
|
+
{"version":3,"file":"auto-status.d.ts","sourceRoot":"","sources":["../../../../src/legacy-runtime/runtime-cores/external-store/auto-status.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkB/C,eAAO,MAAM,YAAY,GAAI,QAAQ,aAAa,YACiB,CAAC;AAEpE,eAAO,MAAM,aAAa,GACxB,QAAQ,OAAO,EACf,WAAW,OAAO,EAClB,yBAAyB,OAAO,EAChC,qBAAqB,OAAO;;;;;;;;;;;EAQA,CAAC"}
|
@@ -8,12 +8,12 @@ var AUTO_STATUS_PENDING = Object.freeze({
|
|
8
8
|
type: "requires-action",
|
9
9
|
reason: "tool-calls"
|
10
10
|
});
|
11
|
-
var
|
11
|
+
var AUTO_STATUS_INTERRUPT = Object.freeze({
|
12
12
|
type: "requires-action",
|
13
13
|
reason: "interrupt"
|
14
14
|
});
|
15
15
|
var isAutoStatus = (status) => status === AUTO_STATUS_RUNNING || status === AUTO_STATUS_COMPLETE;
|
16
|
-
var getAutoStatus = (isLast, isRunning,
|
16
|
+
var getAutoStatus = (isLast, isRunning, hasInterruptedToolCalls, hasPendingToolCalls) => isLast && isRunning ? AUTO_STATUS_RUNNING : hasInterruptedToolCalls ? AUTO_STATUS_INTERRUPT : hasPendingToolCalls ? AUTO_STATUS_PENDING : AUTO_STATUS_COMPLETE;
|
17
17
|
export {
|
18
18
|
getAutoStatus,
|
19
19
|
isAutoStatus
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../../src/legacy-runtime/runtime-cores/external-store/auto-status.tsx"],"sourcesContent":["import { MessageStatus } from \"../../../types\";\n\nconst AUTO_STATUS_RUNNING = Object.freeze({ type: \"running\" });\nconst AUTO_STATUS_COMPLETE = Object.freeze({\n type: \"complete\",\n reason: \"unknown\",\n});\n\nconst AUTO_STATUS_PENDING = Object.freeze({\n type: \"requires-action\",\n reason: \"tool-calls\",\n});\n\nconst
|
1
|
+
{"version":3,"sources":["../../../../src/legacy-runtime/runtime-cores/external-store/auto-status.tsx"],"sourcesContent":["import { MessageStatus } from \"../../../types\";\n\nconst AUTO_STATUS_RUNNING = Object.freeze({ type: \"running\" });\nconst AUTO_STATUS_COMPLETE = Object.freeze({\n type: \"complete\",\n reason: \"unknown\",\n});\n\nconst AUTO_STATUS_PENDING = Object.freeze({\n type: \"requires-action\",\n reason: \"tool-calls\",\n});\n\nconst AUTO_STATUS_INTERRUPT = Object.freeze({\n type: \"requires-action\",\n reason: \"interrupt\",\n});\n\nexport const isAutoStatus = (status: MessageStatus) =>\n status === AUTO_STATUS_RUNNING || status === AUTO_STATUS_COMPLETE;\n\nexport const getAutoStatus = (\n isLast: boolean,\n isRunning: boolean,\n hasInterruptedToolCalls: boolean,\n hasPendingToolCalls: boolean,\n) =>\n isLast && isRunning\n ? AUTO_STATUS_RUNNING\n : hasInterruptedToolCalls\n ? AUTO_STATUS_INTERRUPT\n : hasPendingToolCalls\n ? AUTO_STATUS_PENDING\n : AUTO_STATUS_COMPLETE;\n"],"mappings":";AAEA,IAAM,sBAAsB,OAAO,OAAO,EAAE,MAAM,UAAU,CAAC;AAC7D,IAAM,uBAAuB,OAAO,OAAO;AAAA,EACzC,MAAM;AAAA,EACN,QAAQ;AACV,CAAC;AAED,IAAM,sBAAsB,OAAO,OAAO;AAAA,EACxC,MAAM;AAAA,EACN,QAAQ;AACV,CAAC;AAED,IAAM,wBAAwB,OAAO,OAAO;AAAA,EAC1C,MAAM;AAAA,EACN,QAAQ;AACV,CAAC;AAEM,IAAM,eAAe,CAAC,WAC3B,WAAW,uBAAuB,WAAW;AAExC,IAAM,gBAAgB,CAC3B,QACA,WACA,yBACA,wBAEA,UAAU,YACN,sBACA,0BACE,wBACA,sBACE,sBACA;","names":[]}
|
@@ -67,9 +67,9 @@ var AssistantFrameProvider = class _AssistantFrameProvider {
|
|
67
67
|
result = tool.execute ? await tool.execute(message.args, {
|
68
68
|
toolCallId: message.id,
|
69
69
|
abortSignal: new AbortController().signal,
|
70
|
-
|
70
|
+
human: async () => {
|
71
71
|
throw new Error(
|
72
|
-
"Tool
|
72
|
+
"Tool human input is not supported in frame context"
|
73
73
|
);
|
74
74
|
}
|
75
75
|
}) : void 0;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/model-context/frame/AssistantFrameProvider.ts"],"sourcesContent":["import {\n ModelContextProvider,\n ModelContext,\n} from \"../../model-context/ModelContextTypes\";\nimport { Unsubscribe } from \"../../types/Unsubscribe\";\nimport { Tool } from \"assistant-stream\";\nimport { z } from \"zod\";\nimport {\n FrameMessage,\n FRAME_MESSAGE_CHANNEL,\n SerializedModelContext,\n SerializedTool,\n} from \"./AssistantFrameTypes\";\n\n/**\n * Converts tools to JSON Schema format for serialization\n */\nconst serializeTool = (tool: Tool<any, any>): SerializedTool => ({\n ...(tool.description && { description: tool.description }),\n parameters:\n tool.parameters instanceof z.ZodType\n ? ((z as any).toJSONSchema?.(tool.parameters) ?? tool.parameters)\n : tool.parameters,\n ...(tool.disabled !== undefined && { disabled: tool.disabled }),\n ...(tool.type && { type: tool.type }),\n});\n\n/**\n * Serializes a ModelContext for transmission across iframe boundary\n */\nconst serializeModelContext = (\n context: ModelContext,\n): SerializedModelContext => ({\n ...(context.system !== undefined && { system: context.system }),\n ...(context.tools && {\n tools: Object.fromEntries(\n Object.entries(context.tools).map(([name, tool]) => [\n name,\n serializeTool(tool),\n ]),\n ),\n }),\n});\n\n/**\n * AssistantFrameProvider - Runs inside an iframe and provides ModelContextProviders\n * to the parent window's AssistantFrameHost.\n *\n * Usage example:\n * ```typescript\n * // Inside the iframe\n * // Add model context providers\n * const registry = new ModelContextRegistry();\n * AssistantFrameProvider.addModelContextProvider(registry);\n *\n * // Add tools to registry\n * registry.addTool({\n * toolName: \"search\",\n * description: \"Search the web\",\n * parameters: z.object({ query: z.string() }),\n * execute: async (args) => {\n * // Tool implementation runs in iframe\n * return { results: [\"...\"] };\n * }\n * });\n * ```\n */\nexport class AssistantFrameProvider {\n private static _instance: AssistantFrameProvider | null = null;\n\n private _providers = new Set<ModelContextProvider>();\n private _providerUnsubscribes = new Map<\n ModelContextProvider,\n Unsubscribe | undefined\n >();\n private _targetOrigin: string;\n\n private constructor(targetOrigin: string = \"*\") {\n this._targetOrigin = targetOrigin;\n this.handleMessage = this.handleMessage.bind(this);\n window.addEventListener(\"message\", this.handleMessage);\n\n // Send initial update on initialization\n setTimeout(() => this.broadcastUpdate(), 0);\n }\n\n private static getInstance(targetOrigin?: string): AssistantFrameProvider {\n if (!AssistantFrameProvider._instance) {\n AssistantFrameProvider._instance = new AssistantFrameProvider(\n targetOrigin,\n );\n }\n return AssistantFrameProvider._instance;\n }\n\n private handleMessage(event: MessageEvent) {\n // Security: Validate origin if specified\n if (this._targetOrigin !== \"*\" && event.origin !== this._targetOrigin)\n return;\n if (event.data?.channel !== FRAME_MESSAGE_CHANNEL) return;\n\n const message = event.data.message as FrameMessage;\n\n switch (message.type) {\n case \"model-context-request\":\n // Respond with current context\n this.sendMessage(event, {\n type: \"model-context-update\",\n context: serializeModelContext(this.getModelContext()),\n });\n break;\n\n case \"tool-call\":\n this.handleToolCall(message, event);\n break;\n }\n }\n\n private async handleToolCall(\n message: Extract<FrameMessage, { type: \"tool-call\" }>,\n event: MessageEvent,\n ) {\n const tool = this.getModelContext().tools?.[message.toolName];\n\n let result: any;\n let error: string | undefined;\n\n if (!tool) {\n error = `Tool \"${message.toolName}\" not found`;\n } else {\n try {\n result = tool.execute\n ? await tool.execute(message.args, {\n toolCallId: message.id,\n abortSignal: new AbortController().signal,\n interrupt: async () => {\n throw new Error(\n \"Tool interrupt is not supported in frame context\",\n );\n },\n })\n : undefined;\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n }\n }\n\n this.sendMessage(event, {\n type: \"tool-result\",\n id: message.id,\n ...(error ? { error } : { result }),\n });\n }\n\n private sendMessage(event: MessageEvent, message: FrameMessage) {\n event.source?.postMessage(\n { channel: FRAME_MESSAGE_CHANNEL, message },\n { targetOrigin: event.origin },\n );\n }\n\n private getModelContext(): ModelContext {\n const contexts = Array.from(this._providers).map((p) =>\n p.getModelContext(),\n );\n\n return contexts.reduce(\n (merged, context) => ({\n system: context.system\n ? merged.system\n ? `${merged.system}\\n\\n${context.system}`\n : context.system\n : merged.system,\n tools: { ...(merged.tools || {}), ...(context.tools || {}) },\n }),\n {} as ModelContext,\n );\n }\n\n private broadcastUpdate() {\n // Always broadcast to parent window\n if (window.parent && window.parent !== window) {\n const updateMessage: FrameMessage = {\n type: \"model-context-update\",\n context: serializeModelContext(this.getModelContext()),\n };\n\n window.parent.postMessage(\n { channel: FRAME_MESSAGE_CHANNEL, message: updateMessage },\n this._targetOrigin,\n );\n }\n }\n\n static addModelContextProvider(\n provider: ModelContextProvider,\n targetOrigin?: string,\n ): Unsubscribe {\n const instance = AssistantFrameProvider.getInstance(targetOrigin);\n instance._providers.add(provider);\n\n const unsubscribe = provider.subscribe?.(() => instance.broadcastUpdate());\n if (unsubscribe) {\n instance._providerUnsubscribes.set(provider, unsubscribe);\n }\n\n instance.broadcastUpdate();\n\n return () => {\n instance._providers.delete(provider);\n instance._providerUnsubscribes.get(provider)?.();\n instance._providerUnsubscribes.delete(provider);\n instance.broadcastUpdate();\n };\n }\n\n static dispose() {\n if (AssistantFrameProvider._instance) {\n const instance = AssistantFrameProvider._instance;\n window.removeEventListener(\"message\", instance.handleMessage);\n\n // Unsubscribe from all providers\n instance._providerUnsubscribes.forEach((unsubscribe) => unsubscribe?.());\n instance._providerUnsubscribes.clear();\n instance._providers.clear();\n\n AssistantFrameProvider._instance = null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
1
|
+
{"version":3,"sources":["../../../src/model-context/frame/AssistantFrameProvider.ts"],"sourcesContent":["import {\n ModelContextProvider,\n ModelContext,\n} from \"../../model-context/ModelContextTypes\";\nimport { Unsubscribe } from \"../../types/Unsubscribe\";\nimport { Tool } from \"assistant-stream\";\nimport { z } from \"zod\";\nimport {\n FrameMessage,\n FRAME_MESSAGE_CHANNEL,\n SerializedModelContext,\n SerializedTool,\n} from \"./AssistantFrameTypes\";\n\n/**\n * Converts tools to JSON Schema format for serialization\n */\nconst serializeTool = (tool: Tool<any, any>): SerializedTool => ({\n ...(tool.description && { description: tool.description }),\n parameters:\n tool.parameters instanceof z.ZodType\n ? ((z as any).toJSONSchema?.(tool.parameters) ?? tool.parameters)\n : tool.parameters,\n ...(tool.disabled !== undefined && { disabled: tool.disabled }),\n ...(tool.type && { type: tool.type }),\n});\n\n/**\n * Serializes a ModelContext for transmission across iframe boundary\n */\nconst serializeModelContext = (\n context: ModelContext,\n): SerializedModelContext => ({\n ...(context.system !== undefined && { system: context.system }),\n ...(context.tools && {\n tools: Object.fromEntries(\n Object.entries(context.tools).map(([name, tool]) => [\n name,\n serializeTool(tool),\n ]),\n ),\n }),\n});\n\n/**\n * AssistantFrameProvider - Runs inside an iframe and provides ModelContextProviders\n * to the parent window's AssistantFrameHost.\n *\n * Usage example:\n * ```typescript\n * // Inside the iframe\n * // Add model context providers\n * const registry = new ModelContextRegistry();\n * AssistantFrameProvider.addModelContextProvider(registry);\n *\n * // Add tools to registry\n * registry.addTool({\n * toolName: \"search\",\n * description: \"Search the web\",\n * parameters: z.object({ query: z.string() }),\n * execute: async (args) => {\n * // Tool implementation runs in iframe\n * return { results: [\"...\"] };\n * }\n * });\n * ```\n */\nexport class AssistantFrameProvider {\n private static _instance: AssistantFrameProvider | null = null;\n\n private _providers = new Set<ModelContextProvider>();\n private _providerUnsubscribes = new Map<\n ModelContextProvider,\n Unsubscribe | undefined\n >();\n private _targetOrigin: string;\n\n private constructor(targetOrigin: string = \"*\") {\n this._targetOrigin = targetOrigin;\n this.handleMessage = this.handleMessage.bind(this);\n window.addEventListener(\"message\", this.handleMessage);\n\n // Send initial update on initialization\n setTimeout(() => this.broadcastUpdate(), 0);\n }\n\n private static getInstance(targetOrigin?: string): AssistantFrameProvider {\n if (!AssistantFrameProvider._instance) {\n AssistantFrameProvider._instance = new AssistantFrameProvider(\n targetOrigin,\n );\n }\n return AssistantFrameProvider._instance;\n }\n\n private handleMessage(event: MessageEvent) {\n // Security: Validate origin if specified\n if (this._targetOrigin !== \"*\" && event.origin !== this._targetOrigin)\n return;\n if (event.data?.channel !== FRAME_MESSAGE_CHANNEL) return;\n\n const message = event.data.message as FrameMessage;\n\n switch (message.type) {\n case \"model-context-request\":\n // Respond with current context\n this.sendMessage(event, {\n type: \"model-context-update\",\n context: serializeModelContext(this.getModelContext()),\n });\n break;\n\n case \"tool-call\":\n this.handleToolCall(message, event);\n break;\n }\n }\n\n private async handleToolCall(\n message: Extract<FrameMessage, { type: \"tool-call\" }>,\n event: MessageEvent,\n ) {\n const tool = this.getModelContext().tools?.[message.toolName];\n\n let result: any;\n let error: string | undefined;\n\n if (!tool) {\n error = `Tool \"${message.toolName}\" not found`;\n } else {\n try {\n result = tool.execute\n ? await tool.execute(message.args, {\n toolCallId: message.id,\n abortSignal: new AbortController().signal,\n human: async () => {\n throw new Error(\n \"Tool human input is not supported in frame context\",\n );\n },\n })\n : undefined;\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n }\n }\n\n this.sendMessage(event, {\n type: \"tool-result\",\n id: message.id,\n ...(error ? { error } : { result }),\n });\n }\n\n private sendMessage(event: MessageEvent, message: FrameMessage) {\n event.source?.postMessage(\n { channel: FRAME_MESSAGE_CHANNEL, message },\n { targetOrigin: event.origin },\n );\n }\n\n private getModelContext(): ModelContext {\n const contexts = Array.from(this._providers).map((p) =>\n p.getModelContext(),\n );\n\n return contexts.reduce(\n (merged, context) => ({\n system: context.system\n ? merged.system\n ? `${merged.system}\\n\\n${context.system}`\n : context.system\n : merged.system,\n tools: { ...(merged.tools || {}), ...(context.tools || {}) },\n }),\n {} as ModelContext,\n );\n }\n\n private broadcastUpdate() {\n // Always broadcast to parent window\n if (window.parent && window.parent !== window) {\n const updateMessage: FrameMessage = {\n type: \"model-context-update\",\n context: serializeModelContext(this.getModelContext()),\n };\n\n window.parent.postMessage(\n { channel: FRAME_MESSAGE_CHANNEL, message: updateMessage },\n this._targetOrigin,\n );\n }\n }\n\n static addModelContextProvider(\n provider: ModelContextProvider,\n targetOrigin?: string,\n ): Unsubscribe {\n const instance = AssistantFrameProvider.getInstance(targetOrigin);\n instance._providers.add(provider);\n\n const unsubscribe = provider.subscribe?.(() => instance.broadcastUpdate());\n if (unsubscribe) {\n instance._providerUnsubscribes.set(provider, unsubscribe);\n }\n\n instance.broadcastUpdate();\n\n return () => {\n instance._providers.delete(provider);\n instance._providerUnsubscribes.get(provider)?.();\n instance._providerUnsubscribes.delete(provider);\n instance.broadcastUpdate();\n };\n }\n\n static dispose() {\n if (AssistantFrameProvider._instance) {\n const instance = AssistantFrameProvider._instance;\n window.removeEventListener(\"message\", instance.handleMessage);\n\n // Unsubscribe from all providers\n instance._providerUnsubscribes.forEach((unsubscribe) => unsubscribe?.());\n instance._providerUnsubscribes.clear();\n instance._providers.clear();\n\n AssistantFrameProvider._instance = null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
@@ -44,7 +44,10 @@ export type ToolCallMessagePart<TArgs = ReadonlyJSONObject, TResult = unknown> =
|
|
44
44
|
readonly isError?: boolean | undefined;
|
45
45
|
readonly argsText: string;
|
46
46
|
readonly artifact?: unknown;
|
47
|
-
readonly interrupt?:
|
47
|
+
readonly interrupt?: {
|
48
|
+
type: "human";
|
49
|
+
payload: unknown;
|
50
|
+
};
|
48
51
|
readonly parentId?: string;
|
49
52
|
};
|
50
53
|
export type ThreadUserMessagePart = TextMessagePart | ImageMessagePart | FileMessagePart | Unstable_AudioMessagePart;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"MessagePartTypes.d.ts","sourceRoot":"","sources":["../../src/types/MessagePartTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAC7B,KAAK,GAAG,kBAAkB,EAC1B,OAAO,GAAG,OAAO,IACf;IACF,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;
|
1
|
+
{"version":3,"file":"MessagePartTypes.d.ts","sourceRoot":"","sources":["../../src/types/MessagePartTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAC7B,KAAK,GAAG,kBAAkB,EAC1B,OAAO,GAAG,OAAO,IACf;IACF,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,yBAAyB,CAAC;AAE9B,MAAM,MAAM,0BAA0B,GAClC,eAAe,GACf,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GACjB,eAAe,GACf,gBAAgB,CAAC"}
|
package/package.json
CHANGED
@@ -28,7 +28,7 @@
|
|
28
28
|
"conversational-ui",
|
29
29
|
"conversational-ai"
|
30
30
|
],
|
31
|
-
"version": "0.11.
|
31
|
+
"version": "0.11.23",
|
32
32
|
"license": "MIT",
|
33
33
|
"type": "module",
|
34
34
|
"exports": {
|
@@ -59,7 +59,7 @@
|
|
59
59
|
"@radix-ui/react-use-callback-ref": "^1.1.1",
|
60
60
|
"@radix-ui/react-use-escape-keydown": "^1.1.1",
|
61
61
|
"@standard-schema/spec": "^1.0.0",
|
62
|
-
"assistant-stream": "^0.2.
|
62
|
+
"assistant-stream": "^0.2.33",
|
63
63
|
"json-schema": "^0.4.0",
|
64
64
|
"nanoid": "5.1.6",
|
65
65
|
"react-textarea-autosize": "^8.5.9",
|
package/src/client/types/Part.ts
CHANGED
@@ -27,8 +27,8 @@ export type MessagePartClientApi = {
|
|
27
27
|
addToolResult(result: any | ToolResponse<any>): void;
|
28
28
|
|
29
29
|
/**
|
30
|
-
* Resume
|
31
|
-
* This is useful when a tool has
|
30
|
+
* Resume a tool call that is waiting for human input with a payload.
|
31
|
+
* This is useful when a tool has requested human input and is waiting for a response.
|
32
32
|
*/
|
33
33
|
resumeToolCall(payload: unknown): void;
|
34
34
|
|
@@ -31,8 +31,8 @@ export type MessagePartRuntime = {
|
|
31
31
|
addToolResult(result: any | ToolResponse<any>): void;
|
32
32
|
|
33
33
|
/**
|
34
|
-
* Resume
|
35
|
-
* This is useful when a tool has
|
34
|
+
* Resume a tool call that is waiting for human input with a payload.
|
35
|
+
* This is useful when a tool has requested human input and is waiting for a response.
|
36
36
|
*/
|
37
37
|
resumeToolCall(payload: unknown): void;
|
38
38
|
|
@@ -39,7 +39,7 @@ type UseToolInvocationsParams = {
|
|
39
39
|
|
40
40
|
export type ToolExecutionStatus =
|
41
41
|
| { type: "executing" }
|
42
|
-
| { type: "interrupt"; payload: unknown };
|
42
|
+
| { type: "interrupt"; payload: { type: "human"; payload: unknown } };
|
43
43
|
|
44
44
|
export function useToolInvocations({
|
45
45
|
state,
|
@@ -58,7 +58,7 @@ export function useToolInvocations({
|
|
58
58
|
>
|
59
59
|
>({});
|
60
60
|
|
61
|
-
const
|
61
|
+
const humanInputRef = useRef<
|
62
62
|
Map<
|
63
63
|
string,
|
64
64
|
{
|
@@ -76,18 +76,18 @@ export function useToolInvocations({
|
|
76
76
|
() => acRef.current?.signal ?? new AbortController().signal,
|
77
77
|
(toolCallId: string, payload: unknown) => {
|
78
78
|
return new Promise<unknown>((resolve, reject) => {
|
79
|
-
// Reject previous
|
80
|
-
const previous =
|
79
|
+
// Reject previous human input request if it exists
|
80
|
+
const previous = humanInputRef.current.get(toolCallId);
|
81
81
|
if (previous) {
|
82
82
|
previous.reject(
|
83
|
-
new Error("
|
83
|
+
new Error("Human input request was superseded by a new request"),
|
84
84
|
);
|
85
85
|
}
|
86
86
|
|
87
|
-
|
87
|
+
humanInputRef.current.set(toolCallId, { resolve, reject });
|
88
88
|
setToolStatuses((prev) => ({
|
89
89
|
...prev,
|
90
|
-
[toolCallId]: { type: "interrupt", payload },
|
90
|
+
[toolCallId]: { type: "interrupt", payload: { type: "human", payload } },
|
91
91
|
}));
|
92
92
|
});
|
93
93
|
},
|
@@ -206,10 +206,10 @@ export function useToolInvocations({
|
|
206
206
|
}, [state, controller, onResult]);
|
207
207
|
|
208
208
|
const abort = () => {
|
209
|
-
|
209
|
+
humanInputRef.current.forEach(({ reject }) => {
|
210
210
|
reject(new Error("Tool execution aborted"));
|
211
211
|
});
|
212
|
-
|
212
|
+
humanInputRef.current.clear();
|
213
213
|
setToolStatuses({});
|
214
214
|
|
215
215
|
acRef.current.abort();
|
@@ -223,9 +223,9 @@ export function useToolInvocations({
|
|
223
223
|
},
|
224
224
|
abort,
|
225
225
|
resume: (toolCallId: string, payload: unknown) => {
|
226
|
-
const handlers =
|
226
|
+
const handlers = humanInputRef.current.get(toolCallId);
|
227
227
|
if (handlers) {
|
228
|
-
|
228
|
+
humanInputRef.current.delete(toolCallId);
|
229
229
|
setToolStatuses((prev) => {
|
230
230
|
const next = { ...prev };
|
231
231
|
delete next[toolCallId];
|
@@ -233,7 +233,7 @@ export function useToolInvocations({
|
|
233
233
|
});
|
234
234
|
handlers.resolve(payload);
|
235
235
|
} else {
|
236
|
-
throw new Error(`Tool call ${toolCallId} is not
|
236
|
+
throw new Error(`Tool call ${toolCallId} is not waiting for human input`);
|
237
237
|
}
|
238
238
|
},
|
239
239
|
};
|
@@ -11,7 +11,7 @@ const AUTO_STATUS_PENDING = Object.freeze({
|
|
11
11
|
reason: "tool-calls",
|
12
12
|
});
|
13
13
|
|
14
|
-
const
|
14
|
+
const AUTO_STATUS_INTERRUPT = Object.freeze({
|
15
15
|
type: "requires-action",
|
16
16
|
reason: "interrupt",
|
17
17
|
});
|
@@ -22,13 +22,13 @@ export const isAutoStatus = (status: MessageStatus) =>
|
|
22
22
|
export const getAutoStatus = (
|
23
23
|
isLast: boolean,
|
24
24
|
isRunning: boolean,
|
25
|
-
|
25
|
+
hasInterruptedToolCalls: boolean,
|
26
26
|
hasPendingToolCalls: boolean,
|
27
27
|
) =>
|
28
28
|
isLast && isRunning
|
29
29
|
? AUTO_STATUS_RUNNING
|
30
|
-
:
|
31
|
-
?
|
30
|
+
: hasInterruptedToolCalls
|
31
|
+
? AUTO_STATUS_INTERRUPT
|
32
32
|
: hasPendingToolCalls
|
33
33
|
? AUTO_STATUS_PENDING
|
34
34
|
: AUTO_STATUS_COMPLETE;
|
@@ -133,9 +133,9 @@ export class AssistantFrameProvider {
|
|
133
133
|
? await tool.execute(message.args, {
|
134
134
|
toolCallId: message.id,
|
135
135
|
abortSignal: new AbortController().signal,
|
136
|
-
|
136
|
+
human: async () => {
|
137
137
|
throw new Error(
|
138
|
-
"Tool
|
138
|
+
"Tool human input is not supported in frame context",
|
139
139
|
);
|
140
140
|
},
|
141
141
|
})
|
@@ -54,7 +54,7 @@ export type ToolCallMessagePart<
|
|
54
54
|
readonly isError?: boolean | undefined;
|
55
55
|
readonly argsText: string;
|
56
56
|
readonly artifact?: unknown;
|
57
|
-
readonly interrupt?: unknown;
|
57
|
+
readonly interrupt?: { type: "human"; payload: unknown };
|
58
58
|
readonly parentId?: string;
|
59
59
|
};
|
60
60
|
|