@assistant-ui/core 0.3.0 → 0.3.1
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/react/model-context/useInteractable.d.ts.map +1 -1
- package/dist/react/model-context/useInteractable.js +2 -4
- package/dist/react/model-context/useInteractable.js.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +4 -3
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/package.json +3 -3
- package/src/react/model-context/useInteractable.ts +2 -6
- package/src/runtimes/local/local-thread-runtime-core.test.ts +38 -0
- package/src/runtimes/local/local-thread-runtime-core.ts +6 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInteractable.d.ts","names":[],"sources":["../../../src/react/model-context/useInteractable.ts"],"mappings":";;;;;;;;KAkBY,gCAAgC,WAAW;EACrD;IAAe;MAAU,cAAc;;;IAErC;;;;;;KAQQ,iCAAiC;;EAE3C,OAAO;;EAEP;;EAEA;;;;;;KAOU,4BACV,gBAAgB;EAEhB;EACA,aAAa;EACb,cAAc,gCAAgC;;EAE9C;;;;;;;;EAQA,eAAe;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useInteractable.d.ts","names":[],"sources":["../../../src/react/model-context/useInteractable.ts"],"mappings":";;;;;;;;KAkBY,gCAAgC,WAAW;EACrD;IAAe;MAAU,cAAc;;;IAErC;;;;;;KAQQ,iCAAiC;;EAE3C,OAAO;;EAEP;;EAEA;;;;;;KAOU,4BACV,gBAAgB;EAEhB;EACA,aAAa;EACb,cAAc,gCAAgC;;EAE9C;;;;;;;;EAQA,eAAe;;;;;;;;;;;;;;;;;;;;cAkJJ,2BACX,gBAAgB,kCAEhB,cACA,QAAQ,4BAA4B,uBAEpC,gCAAgC;EAE9B;EACA,SACI,iCACE,gCAAgC;EAGtC,WACE,SACI,gCAAgC,aAE9B,MAAM,gCAAgC,aACnC,gCAAgC;EAE3C;EACA;EACA,aAAa"}
|
|
@@ -8,12 +8,10 @@ import { useEffect, useId, useMemo, useRef } from "@assistant-ui/tap/react-shim"
|
|
|
8
8
|
const useInteractable = (name, config) => {
|
|
9
9
|
const aui = useAui();
|
|
10
10
|
const autoId = useId().replace(/[^a-zA-Z0-9]/g, "");
|
|
11
|
-
const inPart = aui.part.source != null;
|
|
12
11
|
const updateToolName = interactableToolName(name);
|
|
13
12
|
const part = useAuiState((s) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return p.type === "tool-call" ? p : void 0;
|
|
13
|
+
const p = s.optional.part;
|
|
14
|
+
return p?.type === "tool-call" ? p : void 0;
|
|
17
15
|
});
|
|
18
16
|
let inferredId;
|
|
19
17
|
if (part?.toolName === updateToolName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInteractable.js","names":["useEffect","useId","useMemo","useRef","useAui","useAuiState","Unstable_InteractableStateSchema","ToolCallMessagePartComponent","unstable_getInteractableVersions","getInteractableVersions","interactableToolName","unstable_useInteractableState","useInteractableState","useJSONEqual","Unstable_InferInteractableState","TSchema","types","output","TOutput","Unstable_InteractableVersionInfo","state","TState","isLatest","restore","Unstable_InteractableConfig","description","stateSchema","initialState","id","updateRender","useInteractable","name","config","version","setState","updater","prev","isPending","error","flush","Promise","aui","autoId","replace","inPart","part","source","updateToolName","s","undefined","p","type","inferredId","toolName","result","Record","args","success","internalScope","stateSchemaRef","current","initialStateRef","interactables","unstable_interactables","register","scope","Parameters","myToolCallId","toolCallId","registeredState","methods","versionValue","versions","thread","messages","some","v","origin","mine","find","latestToolCallId","findLast","const","unstable_useInteractable"],"sources":["../../../src/react/model-context/useInteractable.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useMemo, useRef } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { Unstable_InteractableStateSchema } from \"../types/scopes/interactables\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport {\n unstable_getInteractableVersions as getInteractableVersions,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\nimport { useJSONEqual } from \"../utils/useJSONEqual\";\n\n/**\n * The state type described by an interactable's `stateSchema`. Resolves the\n * output type of a StandardSchemaV1 schema (e.g. Zod); plain JSON Schema\n * falls back to `unknown`.\n */\nexport type Unstable_InferInteractableState<TSchema> = TSchema extends {\n \"~standard\": { types?: { output: infer TOutput } | undefined };\n}\n ? TOutput\n : unknown;\n\n/**\n * One message's version of an interactable, for components rendered inside\n * tool-call parts. Show `state` to display history; call `restore()` to set\n * the live instance back to it.\n */\nexport type Unstable_InteractableVersionInfo<TState> = {\n /** The interactable's state as it was at this message. */\n state: TState;\n /** Whether this message holds the instance's most recent tool-driven version. */\n isLatest: boolean;\n /** Sets the live state back to this version. */\n restore: () => void;\n};\n\n/**\n * Unstable / Experimental — the interactables API is still evolving and may change in any release.\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport type Unstable_InteractableConfig<\n TSchema extends Unstable_InteractableStateSchema,\n> = {\n description: string;\n stateSchema: TSchema;\n initialState: Unstable_InferInteractableState<TSchema>;\n /** Unique instance ID; required to address this instance when multiple interactables share a name. Auto-generated if omitted. */\n id?: string | undefined;\n /**\n * Component installed as the tool UI for this interactable's `update_{name}`\n * tool calls, so a model edit re-renders the interactable at the message\n * that made it instead of only mutating an earlier one. Prefer\n * `unstable_interactableTool`, which wires this up. Pass a stable component reference;\n * changing identity re-registers the tool UI.\n */\n updateRender?: ToolCallMessagePartComponent | undefined;\n};\n\nconst useInteractable = <TSchema extends Unstable_InteractableStateSchema>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n): readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n /**\n * This message's version of the instance, when rendered inside a\n * tool-created interactable message part; `undefined` elsewhere.\n */\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n\n // Whether this component renders inside a message part is fixed for its\n // lifetime, so conditioning the selectors on it is safe.\n const inPart = aui.part.source != null;\n const updateToolName = interactableToolName(name);\n const part = useAuiState((s) => {\n if (!inPart) return undefined;\n const p = s.part;\n return p.type === \"tool-call\" ? p : undefined;\n });\n\n // Inside an update_{name} part, the instance id comes from the call itself:\n // the result's resolved id (covers id-less calls), or the id argument.\n let inferredId: string | undefined;\n if (part?.toolName === updateToolName) {\n const result = part.result as Record<string, unknown> | undefined;\n const args = part.args as Record<string, unknown> | undefined;\n if (result?.success !== false) {\n if (typeof result?.id === \"string\") inferredId = result.id;\n else if (typeof args?.id === \"string\") inferredId = args.id;\n }\n }\n\n const id = config.id ?? inferredId ?? autoId;\n const internalScope =\n part?.toolName === name || part?.toolName === updateToolName\n ? \"thread\"\n : undefined;\n\n const stateSchemaRef = useRef(config.stateSchema);\n stateSchemaRef.current = config.stateSchema;\n const initialStateRef = useRef(config.initialState);\n initialStateRef.current = config.initialState;\n\n const interactables = useAuiState(() => aui.unstable_interactables);\n\n useEffect(() => {\n return interactables.register({\n id,\n name,\n description: config.description,\n stateSchema: stateSchemaRef.current,\n initialState: initialStateRef.current,\n updateRender: config.updateRender,\n ...(internalScope ? { scope: internalScope } : {}),\n } as Parameters<typeof interactables.register>[0] & {\n scope?: \"thread\" | undefined;\n });\n }, [\n interactables,\n id,\n name,\n config.description,\n internalScope,\n config.updateRender,\n ]);\n\n const myToolCallId = part?.toolCallId;\n\n const [registeredState, methods] =\n useInteractableState<Unstable_InferInteractableState<TSchema>>(id);\n const { setState } = methods;\n\n const versionValue = useAuiState(\n useJSONEqual((s) => {\n if (!internalScope || !myToolCallId) return undefined;\n const versions = getInteractableVersions(s.thread.messages, id, name);\n if (!versions.some((v) => v.origin === \"create\" && v.toolCallId === id)) {\n return undefined;\n }\n const mine = versions.find((v) => v.toolCallId === myToolCallId);\n if (!mine) return undefined;\n const latestToolCallId = versions.findLast(\n (v) => v.toolCallId !== undefined,\n )?.toolCallId;\n return { state: mine.state, isLatest: latestToolCallId === myToolCallId };\n }),\n );\n\n const version = useMemo(\n () =>\n versionValue && {\n state: versionValue.state as Unstable_InferInteractableState<TSchema>,\n isLatest: versionValue.isLatest,\n restore: () =>\n setState(\n versionValue.state as Unstable_InferInteractableState<TSchema>,\n ),\n },\n [versionValue, setState],\n );\n\n const state =\n registeredState === undefined ? config.initialState : registeredState;\n\n return [state, { id, version, ...methods }] as const;\n};\n\n/**\n * Registers an interactable with the AI assistant and returns its live state,\n * like `useState` that the model can also read and update.\n *\n * Call this once per place that shows the interactable. Other components can\n * read and write the same instance by passing its `id` to\n * `unstable_useInteractableState`.\n *\n * For tool-created interactables rendered inside tool-call message parts,\n * `version` carries this message's version of the instance — its state as of\n * that point in the conversation, whether it is the most recent tool-driven\n * version, and a `restore()` back to it. Whether older messages render frozen history or stay\n * live-editable is the component's choice. Inside an `update_{name}` part the\n * instance `id` is inferred from the call, so the same component works at the\n * creating call and at update calls.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractable: <\n TSchema extends Unstable_InteractableStateSchema,\n>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n) => readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] = useInteractable;\n"],"mappings":";;;;;;;AA4DA,MAAM8B,mBACJC,MACAC,WAyBG;CACH,MAAMS,MAAMrC,OAAO;CAEnB,MAAMsC,SAASzC,MAAM,CAAC,CAAC0C,QAAQ,iBAAiB,EAAE;CAIlD,MAAMC,SAASH,IAAII,KAAKC,UAAU;CAClC,MAAMC,iBAAiBrC,qBAAqBqB,IAAI;CAChD,MAAMc,OAAOxC,aAAa2C,MAAM;EAC9B,IAAI,CAACJ,QAAQ,OAAOK,KAAAA;EACpB,MAAMC,IAAIF,EAAEH;EACZ,OAAOK,EAAEC,SAAS,cAAcD,IAAID,KAAAA;CACtC,CAAC;CAID,IAAIG;CACJ,IAAIP,MAAMQ,aAAaN,gBAAgB;EACrC,MAAMO,SAAST,KAAKS;EACpB,MAAME,OAAOX,KAAKW;EAClB,IAAIF,QAAQG,YAAY,OAClB;OAAA,OAAOH,QAAQ1B,OAAO,UAAUwB,aAAaE,OAAO1B;QACnD,IAAI,OAAO4B,MAAM5B,OAAO,UAAUwB,aAAaI,KAAK5B;EAAAA;CAE7D;CAEA,MAAMA,KAAKI,OAAOJ,MAAMwB,cAAcV;CACtC,MAAMgB,gBACJb,MAAMQ,aAAatB,QAAQc,MAAMQ,aAAaN,iBAC1C,WACAE,KAAAA;CAEN,MAAMU,iBAAiBxD,OAAO6B,OAAON,WAAW;CAChDiC,eAAeC,UAAU5B,OAAON;CAChC,MAAMmC,kBAAkB1D,OAAO6B,OAAOL,YAAY;CAClDkC,gBAAgBD,UAAU5B,OAAOL;CAEjC,MAAMmC,gBAAgBzD,kBAAkBoC,IAAIsB,sBAAsB;CAElE/D,gBAAgB;EACd,OAAO8D,cAAcE,SAAS;GAC5BpC;GACAG;GACAN,aAAaO,OAAOP;GACpBC,aAAaiC,eAAeC;GAC5BjC,cAAckC,gBAAgBD;GAC9B/B,cAAcG,OAAOH;GACrB,GAAI6B,gBAAgB,EAAEO,OAAOP,cAAc,IAAI,CAAC;EAClD,CAEC;CACH,GAAG;EACDI;EACAlC;EACAG;EACAC,OAAOP;EACPiC;EACA1B,OAAOH;CAAY,CACpB;CAED,MAAMsC,eAAetB,MAAMuB;CAE3B,MAAM,CAACC,iBAAiBC,WACtB1D,8BAA+DgB,EAAE;CACnE,MAAM,EAAEM,aAAaoC;CAErB,MAAMC,eAAelE,YACnBQ,cAAcmC,QAAM;EAClB,IAAI,CAACU,iBAAiB,CAACS,cAAc,OAAOlB,KAAAA;EAC5C,MAAMuB,WAAW/D,iCAAwBuC,IAAEyB,OAAOC,UAAU9C,IAAIG,IAAI;EACpE,IAAI,CAACyC,SAASG,MAAMC,MAAMA,EAAEC,WAAW,YAAYD,EAAER,eAAexC,EAAE,GACpE;EAEF,MAAMkD,OAAON,SAASO,MAAMH,QAAMA,IAAER,eAAeD,YAAY;EAC/D,IAAI,CAACW,MAAM,OAAO7B,KAAAA;EAClB,MAAM+B,mBAAmBR,SAASS,UAC/BL,QAAMA,IAAER,eAAenB,KAAAA,CAC1B,CAAC,EAAEmB;EACH,OAAO;GAAEhD,OAAO0D,KAAK1D;GAAOE,UAAU0D,qBAAqBb;EAAa;CAC1E,CAAC,CACH;CAEA,MAAMlC,UAAU/B,cAEZqE,gBAAgB;EACdnD,OAAOmD,aAAanD;EACpBE,UAAUiD,aAAajD;EACvBC,eACEW,SACEqC,aAAanD,KACf;CACJ,GACF,CAACmD,cAAcrC,QAAQ,CACzB;CAKA,OAAO,CAFLmC,oBAAoBpB,KAAAA,IAAYjB,OAAOL,eAAe0C,iBAEzC;EAAEzC;EAAIK;EAAS,GAAGqC;CAAQ,CAAC;AAC5C;;;;;;;;;;;;;;;;;;;AAoBA,MAAaa,2BAyBTrD"}
|
|
1
|
+
{"version":3,"file":"useInteractable.js","names":["useEffect","useId","useMemo","useRef","useAui","useAuiState","Unstable_InteractableStateSchema","ToolCallMessagePartComponent","unstable_getInteractableVersions","getInteractableVersions","interactableToolName","unstable_useInteractableState","useInteractableState","useJSONEqual","Unstable_InferInteractableState","TSchema","types","output","TOutput","Unstable_InteractableVersionInfo","state","TState","isLatest","restore","Unstable_InteractableConfig","description","stateSchema","initialState","id","updateRender","useInteractable","name","config","version","setState","updater","prev","isPending","error","flush","Promise","aui","autoId","replace","updateToolName","part","s","p","optional","type","undefined","inferredId","toolName","result","Record","args","success","internalScope","stateSchemaRef","current","initialStateRef","interactables","unstable_interactables","register","scope","Parameters","myToolCallId","toolCallId","registeredState","methods","versionValue","versions","thread","messages","some","v","origin","mine","find","latestToolCallId","findLast","const","unstable_useInteractable"],"sources":["../../../src/react/model-context/useInteractable.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useMemo, useRef } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { Unstable_InteractableStateSchema } from \"../types/scopes/interactables\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport {\n unstable_getInteractableVersions as getInteractableVersions,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\nimport { useJSONEqual } from \"../utils/useJSONEqual\";\n\n/**\n * The state type described by an interactable's `stateSchema`. Resolves the\n * output type of a StandardSchemaV1 schema (e.g. Zod); plain JSON Schema\n * falls back to `unknown`.\n */\nexport type Unstable_InferInteractableState<TSchema> = TSchema extends {\n \"~standard\": { types?: { output: infer TOutput } | undefined };\n}\n ? TOutput\n : unknown;\n\n/**\n * One message's version of an interactable, for components rendered inside\n * tool-call parts. Show `state` to display history; call `restore()` to set\n * the live instance back to it.\n */\nexport type Unstable_InteractableVersionInfo<TState> = {\n /** The interactable's state as it was at this message. */\n state: TState;\n /** Whether this message holds the instance's most recent tool-driven version. */\n isLatest: boolean;\n /** Sets the live state back to this version. */\n restore: () => void;\n};\n\n/**\n * Unstable / Experimental — the interactables API is still evolving and may change in any release.\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport type Unstable_InteractableConfig<\n TSchema extends Unstable_InteractableStateSchema,\n> = {\n description: string;\n stateSchema: TSchema;\n initialState: Unstable_InferInteractableState<TSchema>;\n /** Unique instance ID; required to address this instance when multiple interactables share a name. Auto-generated if omitted. */\n id?: string | undefined;\n /**\n * Component installed as the tool UI for this interactable's `update_{name}`\n * tool calls, so a model edit re-renders the interactable at the message\n * that made it instead of only mutating an earlier one. Prefer\n * `unstable_interactableTool`, which wires this up. Pass a stable component reference;\n * changing identity re-registers the tool UI.\n */\n updateRender?: ToolCallMessagePartComponent | undefined;\n};\n\nconst useInteractable = <TSchema extends Unstable_InteractableStateSchema>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n): readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n /**\n * This message's version of the instance, when rendered inside a\n * tool-created interactable message part; `undefined` elsewhere.\n */\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n\n const updateToolName = interactableToolName(name);\n const part = useAuiState((s) => {\n const p = s.optional.part;\n return p?.type === \"tool-call\" ? p : undefined;\n });\n\n // Inside an update_{name} part, the instance id comes from the call itself:\n // the result's resolved id (covers id-less calls), or the id argument.\n let inferredId: string | undefined;\n if (part?.toolName === updateToolName) {\n const result = part.result as Record<string, unknown> | undefined;\n const args = part.args as Record<string, unknown> | undefined;\n if (result?.success !== false) {\n if (typeof result?.id === \"string\") inferredId = result.id;\n else if (typeof args?.id === \"string\") inferredId = args.id;\n }\n }\n\n const id = config.id ?? inferredId ?? autoId;\n const internalScope =\n part?.toolName === name || part?.toolName === updateToolName\n ? \"thread\"\n : undefined;\n\n const stateSchemaRef = useRef(config.stateSchema);\n stateSchemaRef.current = config.stateSchema;\n const initialStateRef = useRef(config.initialState);\n initialStateRef.current = config.initialState;\n\n const interactables = useAuiState(() => aui.unstable_interactables);\n\n useEffect(() => {\n return interactables.register({\n id,\n name,\n description: config.description,\n stateSchema: stateSchemaRef.current,\n initialState: initialStateRef.current,\n updateRender: config.updateRender,\n ...(internalScope ? { scope: internalScope } : {}),\n } as Parameters<typeof interactables.register>[0] & {\n scope?: \"thread\" | undefined;\n });\n }, [\n interactables,\n id,\n name,\n config.description,\n internalScope,\n config.updateRender,\n ]);\n\n const myToolCallId = part?.toolCallId;\n\n const [registeredState, methods] =\n useInteractableState<Unstable_InferInteractableState<TSchema>>(id);\n const { setState } = methods;\n\n const versionValue = useAuiState(\n useJSONEqual((s) => {\n if (!internalScope || !myToolCallId) return undefined;\n const versions = getInteractableVersions(s.thread.messages, id, name);\n if (!versions.some((v) => v.origin === \"create\" && v.toolCallId === id)) {\n return undefined;\n }\n const mine = versions.find((v) => v.toolCallId === myToolCallId);\n if (!mine) return undefined;\n const latestToolCallId = versions.findLast(\n (v) => v.toolCallId !== undefined,\n )?.toolCallId;\n return { state: mine.state, isLatest: latestToolCallId === myToolCallId };\n }),\n );\n\n const version = useMemo(\n () =>\n versionValue && {\n state: versionValue.state as Unstable_InferInteractableState<TSchema>,\n isLatest: versionValue.isLatest,\n restore: () =>\n setState(\n versionValue.state as Unstable_InferInteractableState<TSchema>,\n ),\n },\n [versionValue, setState],\n );\n\n const state =\n registeredState === undefined ? config.initialState : registeredState;\n\n return [state, { id, version, ...methods }] as const;\n};\n\n/**\n * Registers an interactable with the AI assistant and returns its live state,\n * like `useState` that the model can also read and update.\n *\n * Call this once per place that shows the interactable. Other components can\n * read and write the same instance by passing its `id` to\n * `unstable_useInteractableState`.\n *\n * For tool-created interactables rendered inside tool-call message parts,\n * `version` carries this message's version of the instance — its state as of\n * that point in the conversation, whether it is the most recent tool-driven\n * version, and a `restore()` back to it. Whether older messages render frozen history or stay\n * live-editable is the component's choice. Inside an `update_{name}` part the\n * instance `id` is inferred from the call, so the same component works at the\n * creating call and at update calls.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractable: <\n TSchema extends Unstable_InteractableStateSchema,\n>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n) => readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] = useInteractable;\n"],"mappings":";;;;;;;AA4DA,MAAM8B,mBACJC,MACAC,WAyBG;CACH,MAAMS,MAAMrC,OAAO;CAEnB,MAAMsC,SAASzC,MAAM,CAAC,CAAC0C,QAAQ,iBAAiB,EAAE;CAElD,MAAMC,iBAAiBlC,qBAAqBqB,IAAI;CAChD,MAAMc,OAAOxC,aAAayC,MAAM;EAC9B,MAAMC,IAAID,EAAEE,SAASH;EACrB,OAAOE,GAAGE,SAAS,cAAcF,IAAIG,KAAAA;CACvC,CAAC;CAID,IAAIC;CACJ,IAAIN,MAAMO,aAAaR,gBAAgB;EACrC,MAAMS,SAASR,KAAKQ;EACpB,MAAME,OAAOV,KAAKU;EAClB,IAAIF,QAAQG,YAAY,OAClB;OAAA,OAAOH,QAAQzB,OAAO,UAAUuB,aAAaE,OAAOzB;QACnD,IAAI,OAAO2B,MAAM3B,OAAO,UAAUuB,aAAaI,KAAK3B;EAAAA;CAE7D;CAEA,MAAMA,KAAKI,OAAOJ,MAAMuB,cAAcT;CACtC,MAAMe,gBACJZ,MAAMO,aAAarB,QAAQc,MAAMO,aAAaR,iBAC1C,WACAM,KAAAA;CAEN,MAAMQ,iBAAiBvD,OAAO6B,OAAON,WAAW;CAChDgC,eAAeC,UAAU3B,OAAON;CAChC,MAAMkC,kBAAkBzD,OAAO6B,OAAOL,YAAY;CAClDiC,gBAAgBD,UAAU3B,OAAOL;CAEjC,MAAMkC,gBAAgBxD,kBAAkBoC,IAAIqB,sBAAsB;CAElE9D,gBAAgB;EACd,OAAO6D,cAAcE,SAAS;GAC5BnC;GACAG;GACAN,aAAaO,OAAOP;GACpBC,aAAagC,eAAeC;GAC5BhC,cAAciC,gBAAgBD;GAC9B9B,cAAcG,OAAOH;GACrB,GAAI4B,gBAAgB,EAAEO,OAAOP,cAAc,IAAI,CAAC;EAClD,CAEC;CACH,GAAG;EACDI;EACAjC;EACAG;EACAC,OAAOP;EACPgC;EACAzB,OAAOH;CAAY,CACpB;CAED,MAAMqC,eAAerB,MAAMsB;CAE3B,MAAM,CAACC,iBAAiBC,WACtBzD,8BAA+DgB,EAAE;CACnE,MAAM,EAAEM,aAAamC;CAErB,MAAMC,eAAejE,YACnBQ,cAAciC,QAAM;EAClB,IAAI,CAACW,iBAAiB,CAACS,cAAc,OAAOhB,KAAAA;EAC5C,MAAMqB,WAAW9D,iCAAwBqC,IAAE0B,OAAOC,UAAU7C,IAAIG,IAAI;EACpE,IAAI,CAACwC,SAASG,MAAMC,MAAMA,EAAEC,WAAW,YAAYD,EAAER,eAAevC,EAAE,GACpE;EAEF,MAAMiD,OAAON,SAASO,MAAMH,QAAMA,IAAER,eAAeD,YAAY;EAC/D,IAAI,CAACW,MAAM,OAAO3B,KAAAA;EAClB,MAAM6B,mBAAmBR,SAASS,UAC/BL,QAAMA,IAAER,eAAejB,KAAAA,CAC1B,CAAC,EAAEiB;EACH,OAAO;GAAE/C,OAAOyD,KAAKzD;GAAOE,UAAUyD,qBAAqBb;EAAa;CAC1E,CAAC,CACH;CAEA,MAAMjC,UAAU/B,cAEZoE,gBAAgB;EACdlD,OAAOkD,aAAalD;EACpBE,UAAUgD,aAAahD;EACvBC,eACEW,SACEoC,aAAalD,KACf;CACJ,GACF,CAACkD,cAAcpC,QAAQ,CACzB;CAKA,OAAO,CAFLkC,oBAAoBlB,KAAAA,IAAYlB,OAAOL,eAAeyC,iBAEzC;EAAExC;EAAIK;EAAS,GAAGoC;CAAQ,CAAC;AAC5C;;;;;;;;;;;;;;;;;;;AAoBA,MAAaa,2BAyBTpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/local/local-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;cA6Ca,+BACH,iCACG;WAEK;;;;;;;;;;;;;;;UAgBR;UAEA;UACA;UAEA;UAIA;UAuBA;WAYQ;WACA;UAER;MACG;UAIH;UACA;MACG,wBAAwB;MAIxB;;;;;;;;;;EAKT,YAAA,iBAAiB,sBACjB,SAAS;UAMH;UAEA;UAEA;EAED,0BAA0B;UAIzB;EAED,mCACL,kBAAkB;MAKT;EAIJ,sBAAsB,SAAS;UAuE9B;EACD,mBAAe;EAuCT,OAAO,SAAS,gBAAgB;EAWtC,0BAA0B;EAM1B,eAAe;EAIf,gBAAgB;UAIT;EAgCD,cAAc,oBAAoB;EAmBxC,YAAY,WAAW,eAAe,kBAAkB;EAMxD;EAIA;EAIM,WACT,UAAU,aAAa,gBACzB,cAAc,0BACb;UAuBW;UAkEA;
|
|
1
|
+
{"version":3,"file":"local-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/local/local-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;cA6Ca,+BACH,iCACG;WAEK;;;;;;;;;;;;;;;UAgBR;UAEA;UACA;UAEA;UAIA;UAuBA;WAYQ;WACA;UAER;MACG;UAIH;UACA;MACG,wBAAwB;MAIxB;;;;;;;;;;EAKT,YAAA,iBAAiB,sBACjB,SAAS;UAMH;UAEA;UAEA;EAED,0BAA0B;UAIzB;EAED,mCACL,kBAAkB;MAKT;EAIJ,sBAAsB,SAAS;UAuE9B;EACD,mBAAe;EAuCT,OAAO,SAAS,gBAAgB;EAWtC,0BAA0B;EAM1B,eAAe;EAIf,gBAAgB;UAIT;EAgCD,cAAc,oBAAoB;EAmBxC,YAAY,WAAW,eAAe,kBAAkB;EAMxD;EAIA;EAIM,WACT,UAAU,aAAa,gBACzB,cAAc,0BACb;UAuBW;UAkEA;EAkMP;EASA;EASA,gBACL,WACA,YACA,QACA,SACA,YACC;EA6CI,eAAe,UAAU;EAMzB,wBACL,YACA,UACA,UACA,UACC"}
|
|
@@ -288,7 +288,8 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
288
288
|
async performRoundtrip(parentId, message, runConfig, alreadyPersisted, runCallback) {
|
|
289
289
|
const messages = parentId ? this.repository.getMessages(parentId) : [];
|
|
290
290
|
this.abortController?.abort();
|
|
291
|
-
|
|
291
|
+
const abortController = new AbortController();
|
|
292
|
+
this.abortController = abortController;
|
|
292
293
|
const initialContent = message.content;
|
|
293
294
|
const initialAnnotations = message.metadata?.unstable_annotations;
|
|
294
295
|
const initialData = message.metadata?.unstable_data;
|
|
@@ -336,7 +337,7 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
336
337
|
this._lastRunConfig = runConfig ?? {};
|
|
337
338
|
const { unstable_composerMetadata: _, ...context } = this.getModelContext();
|
|
338
339
|
runCallback = runCallback ?? this.adapters.chatModel.run.bind(this.adapters.chatModel);
|
|
339
|
-
const abortSignal =
|
|
340
|
+
const abortSignal = abortController.signal;
|
|
340
341
|
const threadId = this._getThreadId?.();
|
|
341
342
|
const promiseOrGenerator = runCallback({
|
|
342
343
|
messages,
|
|
@@ -386,7 +387,7 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
|
|
|
386
387
|
throw e;
|
|
387
388
|
}
|
|
388
389
|
} finally {
|
|
389
|
-
this.abortController = null;
|
|
390
|
+
if (this.abortController === abortController) this.abortController = null;
|
|
390
391
|
const history = this._options.adapters.history;
|
|
391
392
|
const item = {
|
|
392
393
|
parentId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-thread-runtime-core.js","names":["fromThreadMessageLike","generateId","ChatModelAdapter","ChatModelRunResult","shouldContinue","LocalRuntimeOptionsBase","consumeSuggestionResult","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","ThreadRuntimeCore","StartRunConfig","ResumeRunConfig","BaseThreadRuntimeCore","AppendMessage","ThreadAssistantMessage","RunConfig","toAssistantError","ModelContextProvider","createMessageQueue","MessageQueueController","EMPTY_QUEUE_ITEMS","QueueItemState","AbortError","Error","name","detach","constructor","message","LocalThreadRuntimeCore","capabilities","switchToBranch","switchBranchDuringRun","edit","delete","reload","cancel","unstable_copy","speech","dictation","voice","attachments","feedback","queue","abortController","AbortController","_queue","_queueRunInFlight","_historyWrites","Map","Promise","_chainHistoryWrite","id","write","next","get","resolve","then","stored","set","_persistPausedMessage","parentId","status","type","history","_options","adapters","update","bind","item","runConfig","_lastRunConfig","catch","isDisabled","isSendDisabled","_isLoading","isLoading","_suggestions","_suggestionsController","suggestions","contextProvider","options","__internal_setOptions","_getThreadId","__internal_setGetThreadId","getThreadId","_getInitializePromise","__internal_setGetInitializePromise","getPromise","extras","undefined","hasUpdates","canSpeak","canDictate","canVoice","canAttach","canFeedback","canDelete","canQueue","unstable_enableMessageQueue","run","_runAppend","finally","notifyIdle","subscribe","_notifySubscribers","adapter","clear","_loadPromise","__internal_load","promise","load","repo","repository","import","messages","length","ensureInitialized","resume","unstable_resume","startRun","headId","sourceId","append","isTail","at","willRun","role","enqueue","steer","getQueueItems","items","steerQueueItem","queueItemId","removeQueueItem","remove","initPromise","newMessage","reason","addOrUpdateMessage","resetHead","deleteMessage","messageId","getMessages","messageIndex","findIndex","m","resumeRun","stream","startConfig","exportExternalState","importExternalState","runCallback","content","metadata","unstable_state","state","unstable_annotations","unstable_data","steps","custom","createdAt","Date","_runLoop","_notifyEventSubscribers","alreadyPersisted","notifyBusy","abort","performRoundtrip","unstable_humanToolNames","queueMicrotask","suggestion","signal","promiseOrGenerator","generate","onUpdate","r","initialContent","initialAnnotations","initialData","initialSteps","initialCustom","updateMessage","Partial","newSteps","newAnnotations","newData","annotations","data","timing","maxSteps","unstable_composerMetadata","_","context","getModelContext","chatModel","abortSignal","threadId","unstable_assistantMessageId","unstable_threadId","unstable_parentId","unstable_getMessage","Symbol","asyncIterator","aborted","e","error","isTerminal","isPausing","cancelRun","addToolResult","toolCallId","result","isError","artifact","messageData","getMessage","added","found","newContent","map","c","resumeToolCall","respondToToolApproval","approvalId","approved","optionId","findLast","some","approval","target","find","resolution","targetApproval"],"sources":["../../../src/runtimes/local/local-thread-runtime-core.ts"],"sourcesContent":["import { fromThreadMessageLike } from \"../../runtime/utils/thread-message-like\";\nimport { generateId } from \"../../utils/id\";\nimport type {\n ChatModelAdapter,\n ChatModelRunResult,\n} from \"../../runtime/utils/chat-model-adapter\";\nimport { shouldContinue } from \"./should-continue\";\nimport type { LocalRuntimeOptionsBase } from \"./local-runtime-options\";\nimport { consumeSuggestionResult } from \"../../adapters/suggestion\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n ThreadRuntimeCore,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../../runtime/interfaces/thread-runtime-core\";\nimport { BaseThreadRuntimeCore } from \"../../runtime/base/base-thread-runtime-core\";\nimport type {\n AppendMessage,\n ThreadAssistantMessage,\n} from \"../../types/message\";\nimport type { RunConfig } from \"../../types/message\";\nimport { toAssistantError } from \"../../types/error\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport {\n createMessageQueue,\n type MessageQueueController,\n} from \"../../runtime/queue/message-queue\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\n\nclass AbortError extends Error {\n override name = \"AbortError\";\n detach: boolean;\n\n constructor(detach: boolean, message?: string) {\n super(message);\n this.detach = detach;\n }\n}\n\nexport class LocalThreadRuntimeCore\n extends BaseThreadRuntimeCore\n implements ThreadRuntimeCore\n{\n public readonly capabilities = {\n switchToBranch: true,\n switchBranchDuringRun: true,\n edit: true,\n delete: false,\n reload: true,\n cancel: true,\n unstable_copy: true,\n speech: false,\n dictation: false,\n voice: false,\n attachments: false,\n feedback: false,\n queue: false,\n };\n\n private abortController: AbortController | null = null;\n\n private _queue: MessageQueueController | null = null;\n private _queueRunInFlight = false;\n\n private _historyWrites = new Map<string, Promise<void>>();\n\n // Writes for one message id must land in issue order; an earlier paused\n // snapshot arriving after the terminal write would resurrect the pause.\n private _chainHistoryWrite(\n id: string,\n write: () => Promise<void>,\n ): Promise<void> {\n const next = (this._historyWrites.get(id) ?? Promise.resolve()).then(\n write,\n write,\n );\n const stored = next.then(\n () => {},\n () => {},\n );\n this._historyWrites.set(id, stored);\n void stored.then(() => {\n if (this._historyWrites.get(id) === stored) {\n this._historyWrites.delete(id);\n }\n });\n return next;\n }\n\n // A decision recorded on a still-paused message must reach history before\n // the run resumes, or a refresh would restore the message without it.\n private _persistPausedMessage(\n parentId: string | null,\n message: ThreadAssistantMessage,\n ) {\n if (message.status?.type !== \"requires-action\") return;\n const history = this._options.adapters.history;\n if (!history?.update) return;\n const update = history.update.bind(history);\n const item = { parentId, message, runConfig: this._lastRunConfig };\n this._chainHistoryWrite(message.id, () => update(item)).catch(() => {});\n }\n\n public readonly isDisabled = false;\n public readonly isSendDisabled = false;\n\n private _isLoading = false;\n public get isLoading() {\n return this._isLoading;\n }\n\n private _suggestions: readonly ThreadSuggestion[] = [];\n private _suggestionsController: AbortController | null = null;\n public get suggestions(): readonly ThreadSuggestion[] {\n return this._suggestions;\n }\n\n public get adapters() {\n return this._options.adapters;\n }\n\n constructor(\n contextProvider: ModelContextProvider,\n options: LocalRuntimeOptionsBase,\n ) {\n super(contextProvider);\n this.__internal_setOptions(options);\n }\n\n private _options!: LocalRuntimeOptionsBase;\n\n private _lastRunConfig: RunConfig = {};\n\n private _getThreadId?: () => string | undefined;\n\n public __internal_setGetThreadId(getThreadId: () => string | undefined) {\n this._getThreadId = getThreadId;\n }\n\n private _getInitializePromise?: () => Promise<unknown> | undefined;\n\n public __internal_setGetInitializePromise(\n getPromise: () => Promise<unknown> | undefined,\n ) {\n this._getInitializePromise = getPromise;\n }\n\n public get extras() {\n return undefined;\n }\n\n public __internal_setOptions(options: LocalRuntimeOptionsBase) {\n if (this._options === options) return;\n\n this._options = options;\n\n let hasUpdates = false;\n\n const canSpeak = options.adapters?.speech !== undefined;\n if (this.capabilities.speech !== canSpeak) {\n this.capabilities.speech = canSpeak;\n hasUpdates = true;\n }\n\n const canDictate = options.adapters?.dictation !== undefined;\n if (this.capabilities.dictation !== canDictate) {\n this.capabilities.dictation = canDictate;\n hasUpdates = true;\n }\n\n const canVoice = options.adapters?.voice !== undefined;\n if (this.capabilities.voice !== canVoice) {\n this.capabilities.voice = canVoice;\n hasUpdates = true;\n }\n\n const canAttach = options.adapters?.attachments !== undefined;\n if (this.capabilities.attachments !== canAttach) {\n this.capabilities.attachments = canAttach;\n hasUpdates = true;\n }\n\n const canFeedback = options.adapters?.feedback !== undefined;\n if (this.capabilities.feedback !== canFeedback) {\n this.capabilities.feedback = canFeedback;\n hasUpdates = true;\n }\n\n const canDelete = options.adapters?.history?.delete !== undefined;\n if (this.capabilities.delete !== canDelete) {\n this.capabilities.delete = canDelete;\n hasUpdates = true;\n }\n\n const canQueue = options.unstable_enableMessageQueue === true;\n if (canQueue && !this._queue) {\n this._queue = createMessageQueue({\n run: (message) => {\n // release the queue when the dispatch settles, even if it rejects\n // before reaching startRun's finally, so a failure can't deadlock it\n this._queueRunInFlight = true;\n void this._runAppend(message)\n .finally(() => {\n this._queueRunInFlight = false;\n this._queue?.notifyIdle();\n })\n .catch(() => {});\n },\n });\n this._queue.subscribe(() => this._notifySubscribers());\n } else if (!canQueue && this._queue) {\n this._queue.adapter.clear(\"cancel-run\");\n this._queue = null;\n }\n if (this.capabilities.queue !== canQueue) {\n this.capabilities.queue = canQueue;\n hasUpdates = true;\n }\n\n if (hasUpdates) this._notifySubscribers();\n }\n\n private _loadPromise: Promise<void> | undefined;\n public __internal_load() {\n if (this._loadPromise) return this._loadPromise;\n\n const promise = this.adapters.history?.load() ?? Promise.resolve(null);\n\n this._isLoading = true;\n this._notifySubscribers();\n\n this._loadPromise = promise\n .then((repo) => {\n if (!repo) return;\n this.repository.import(repo);\n if (repo.messages.length > 0) {\n this.ensureInitialized();\n }\n this._notifySubscribers();\n\n const resume = this.adapters.history?.resume?.bind(\n this.adapters.history,\n );\n if (repo.unstable_resume && resume) {\n this.startRun(\n {\n parentId: this.repository.headId,\n sourceId: this.repository.headId,\n runConfig: this._lastRunConfig,\n },\n resume,\n ).catch(() => {});\n }\n })\n .finally(() => {\n this._isLoading = false;\n this._notifySubscribers();\n });\n\n return this._loadPromise;\n }\n\n public async append(message: AppendMessage): Promise<void> {\n const isTail = message.parentId === (this.messages.at(-1)?.id ?? null);\n const willRun = message.startRun ?? message.role === \"user\";\n if (this._queue && willRun && isTail) {\n this._queue.adapter.enqueue(message, { steer: message.steer ?? false });\n return;\n }\n if (this._queue && !isTail) this._queue.adapter.clear(\"edit\");\n return this._runAppend(message);\n }\n\n public getQueueItems(): readonly QueueItemState[] {\n // Reads can arrive during base-thread construction, before the queue field\n // is assigned, so guard against the unset field.\n return this._queue?.adapter.items ?? EMPTY_QUEUE_ITEMS;\n }\n\n public steerQueueItem(queueItemId: string): void {\n this._queue?.adapter.steer(queueItemId);\n }\n\n public removeQueueItem(queueItemId: string): void {\n this._queue?.adapter.remove(queueItemId);\n }\n\n private async _runAppend(message: AppendMessage): Promise<void> {\n this.ensureInitialized();\n\n const initPromise = this._getInitializePromise?.();\n if (initPromise) {\n await initPromise;\n }\n\n const newMessage = fromThreadMessageLike(message, generateId(), {\n type: \"complete\",\n reason: \"unknown\",\n });\n this.repository.addOrUpdateMessage(message.parentId, newMessage);\n this._options.adapters.history?.append({\n parentId: message.parentId,\n message: newMessage,\n ...(message.runConfig !== undefined && { runConfig: message.runConfig }),\n });\n\n const startRun = message.startRun ?? message.role === \"user\";\n if (startRun) {\n await this.startRun({\n parentId: newMessage.id,\n sourceId: message.sourceId,\n runConfig: message.runConfig ?? {},\n });\n } else {\n this.repository.resetHead(newMessage.id);\n this._notifySubscribers();\n }\n }\n\n public async deleteMessage(messageId: string): Promise<void> {\n const adapter = this._options.adapters.history;\n if (!adapter?.delete)\n throw new Error(\"Runtime does not support deleting messages.\");\n\n const messages = this.repository.getMessages();\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) throw new Error(\"Message not found.\");\n\n const message = messages[messageIndex]!;\n const parentId = messages[messageIndex - 1]?.id ?? null;\n const items = [{ parentId, message }];\n\n await adapter.delete(items);\n\n this.repository.deleteMessage(messageId);\n this._notifySubscribers();\n }\n\n public resumeRun({ stream, ...startConfig }: ResumeRunConfig): Promise<void> {\n if (!stream)\n throw new Error(\"You must pass a stream parameter to resume runs.\");\n return this.startRun(startConfig, stream);\n }\n\n public exportExternalState(): any {\n throw new Error(\"Runtime does not support exporting external states.\");\n }\n\n public importExternalState(): void {\n throw new Error(\"Runtime does not support importing external states.\");\n }\n\n public async startRun(\n { parentId, runConfig }: StartRunConfig,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this.ensureInitialized();\n\n // add assistant message\n const id = generateId();\n const message: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n createdAt: new Date(),\n };\n\n return this._runLoop(parentId, message, runConfig, runCallback);\n }\n\n private async _runLoop(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this._notifyEventSubscribers(\"runStart\", {});\n\n // A run entered on a requires-action message resumes a pause an\n // update-capable adapter already holds (written at pause time or loaded).\n const alreadyPersisted =\n message.status?.type === \"requires-action\" &&\n this._options.adapters.history?.update !== undefined;\n\n try {\n // mark busy for runs not started through the queue (regenerate, resume)\n this._queue?.notifyBusy();\n this._suggestions = [];\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n this._notifySubscribers();\n\n do {\n message = await this.performRoundtrip(\n parentId,\n message,\n runConfig,\n alreadyPersisted,\n runCallback,\n );\n runCallback = undefined;\n } while (shouldContinue(message, this._options.unstable_humanToolNames));\n } finally {\n this._notifyEventSubscribers(\"runEnd\", {});\n // queue-driven runs release from the driver settle handler; a direct\n // run (regenerate, resume) releases here\n if (!this._queueRunInFlight) {\n queueMicrotask(() => this._queue?.notifyIdle());\n }\n }\n\n if (\n this.adapters.suggestion &&\n message.status?.type !== \"requires-action\"\n ) {\n this._suggestionsController = new AbortController();\n const signal = this._suggestionsController.signal;\n const adapter = this.adapters.suggestion;\n void (async () => {\n try {\n const promiseOrGenerator = adapter.generate({\n messages: this.messages,\n signal,\n });\n await consumeSuggestionResult(promiseOrGenerator, {\n signal,\n onUpdate: (r) => {\n this._suggestions = r;\n this._notifySubscribers();\n },\n });\n } catch {}\n })();\n }\n }\n\n private async performRoundtrip(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n alreadyPersisted: boolean,\n runCallback?: ChatModelAdapter[\"run\"],\n ) {\n const messages = parentId ? this.repository.getMessages(parentId) : [];\n\n // abort existing run\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n const initialContent = message.content;\n const initialAnnotations = message.metadata?.unstable_annotations;\n const initialData = message.metadata?.unstable_data;\n const initialSteps = message.metadata?.steps;\n const initialCustom = message.metadata?.custom;\n const updateMessage = (m: Partial<ChatModelRunResult>) => {\n const newSteps = m.metadata?.steps;\n const steps = newSteps\n ? [...(initialSteps ?? []), ...newSteps]\n : undefined;\n\n const newAnnotations = m.metadata?.unstable_annotations;\n const newData = m.metadata?.unstable_data;\n const annotations = newAnnotations\n ? [...(initialAnnotations ?? []), ...newAnnotations]\n : undefined;\n const data = newData ? [...(initialData ?? []), ...newData] : undefined;\n\n message = {\n ...message,\n ...(m.content\n ? { content: [...initialContent, ...(m.content ?? [])] }\n : undefined),\n status: m.status ?? message.status,\n ...(m.metadata\n ? {\n metadata: {\n ...message.metadata,\n ...(m.metadata.unstable_state !== undefined\n ? { unstable_state: m.metadata.unstable_state }\n : undefined),\n ...(annotations\n ? { unstable_annotations: annotations }\n : undefined),\n ...(data ? { unstable_data: data } : undefined),\n ...(steps ? { steps } : undefined),\n ...(m.metadata?.timing\n ? { timing: m.metadata.timing }\n : undefined),\n ...(m.metadata?.custom\n ? {\n custom: {\n ...(initialCustom ?? {}),\n ...m.metadata.custom,\n },\n }\n : undefined),\n },\n }\n : undefined),\n };\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n };\n\n const maxSteps = this._options.maxSteps ?? 2;\n\n try {\n const steps = message.metadata?.steps?.length ?? 0;\n if (steps >= maxSteps) {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"tool-calls\",\n },\n });\n return message;\n }\n\n updateMessage({\n status: {\n type: \"running\",\n },\n });\n\n // Switch to the new message branch right after adding it for the first time\n this.repository.resetHead(message.id);\n this._notifySubscribers();\n\n this._lastRunConfig = runConfig ?? {};\n // unstable_composerMetadata is composer-only (stamped onto the outgoing\n // message); never expose it to the chat-model adapter's run context.\n const { unstable_composerMetadata: _, ...context } =\n this.getModelContext();\n\n runCallback =\n runCallback ??\n this.adapters.chatModel.run.bind(this.adapters.chatModel);\n\n const abortSignal = this.abortController.signal;\n const threadId = this._getThreadId?.();\n const promiseOrGenerator = runCallback({\n messages,\n runConfig: this._lastRunConfig,\n abortSignal,\n context,\n unstable_assistantMessageId: message.id,\n unstable_threadId: threadId,\n unstable_parentId: parentId,\n unstable_getMessage() {\n return message;\n },\n });\n\n // handle async iterator for streaming results\n if (Symbol.asyncIterator in promiseOrGenerator) {\n for await (const r of promiseOrGenerator) {\n if (abortSignal.aborted) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n break;\n }\n\n updateMessage(r);\n }\n } else {\n updateMessage(await promiseOrGenerator);\n }\n\n if (message.status.type === \"running\") {\n updateMessage({\n status: abortSignal.aborted\n ? { type: \"incomplete\", reason: \"cancelled\" }\n : { type: \"complete\", reason: \"unknown\" },\n });\n }\n } catch (e) {\n if (e instanceof AbortError) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else if (e instanceof Error && e.name === \"AbortError\") {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"error\",\n error: toAssistantError(e),\n },\n });\n\n throw e;\n }\n } finally {\n this.abortController = null;\n\n const history = this._options.adapters.history;\n const item = {\n parentId,\n message,\n runConfig: this._lastRunConfig,\n };\n const isTerminal =\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n const isPausing =\n message.status.type === \"requires-action\" &&\n !shouldContinue(message, this._options.unstable_humanToolNames);\n\n // Pauses are written only for adapters that can rewrite the entry later;\n // an append-only adapter would strand a half-finished run in history.\n if (isTerminal || (isPausing && history?.update)) {\n const write =\n alreadyPersisted && history?.update\n ? history.update.bind(history)\n : history?.append.bind(history);\n if (write) {\n await this._chainHistoryWrite(message.id, () => write(item));\n }\n }\n }\n return message;\n }\n\n public detach() {\n this._queue?.adapter.clear(\"cancel-run\");\n const error = new AbortError(true);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public cancelRun() {\n this._queue?.adapter.clear(\"cancel-run\");\n const error = new AbortError(false);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public addToolResult({\n messageId,\n toolCallId,\n result,\n isError,\n artifact,\n }: AddToolResultOptions) {\n const messageData = this.repository.getMessage(messageId);\n const { parentId } = messageData;\n let { message } = messageData;\n\n if (message.role !== \"assistant\")\n throw new Error(\"Tried to add tool result to non-assistant message\");\n\n let added = false;\n let found = false;\n const newContent = message.content.map((c) => {\n if (c.type !== \"tool-call\") return c;\n if (c.toolCallId !== toolCallId) return c;\n found = true;\n if (!c.result) added = true;\n return {\n ...c,\n result,\n artifact,\n isError,\n };\n });\n\n if (!found)\n throw new Error(\"Tried to add tool result to non-existing tool call\");\n\n message = {\n ...message,\n content: newContent,\n };\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n // a result may arrive mid-run or on a non-head message; the resume\n // intentionally aborts any in-flight run, unlike respondToToolApproval\n if (\n added &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else if (added) {\n this._persistPausedMessage(parentId, message);\n }\n }\n\n public resumeToolCall(_options: ResumeToolCallOptions) {\n throw new Error(\n \"Local runtime does not support resuming tool calls. For human-in-the-loop tools, list the tool in unstable_humanToolNames and complete the call with addToolResult.\",\n );\n }\n\n public respondToToolApproval({\n approvalId,\n approved,\n optionId,\n reason,\n }: RespondToToolApprovalOptions) {\n let message = this.repository\n .getMessages()\n .findLast(\n (m): m is ThreadAssistantMessage =>\n m.role === \"assistant\" &&\n m.content.some(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n ),\n );\n\n if (!message)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n\n if (this.abortController !== null)\n throw new Error(\n \"Tried to respond to a tool approval while a run is in progress\",\n );\n\n if (message.status?.type !== \"requires-action\")\n throw new Error(\n \"Tried to respond to a tool approval on a message whose status is not requires-action\",\n );\n\n const target = message.content.find(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n );\n if (target?.type !== \"tool-call\" || !target.approval)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n if (target.approval.resolution !== undefined)\n throw new Error(\n \"Tried to respond to a tool approval that was cancelled or expired\",\n );\n if (target.approval.approved !== undefined)\n throw new Error(\"Tried to respond to an already decided tool approval\");\n\n const targetApproval = target.approval;\n const newContent = message.content.map((c) => {\n if (c !== target) return c;\n const approval = {\n ...targetApproval,\n approved,\n ...(optionId != null && { optionId }),\n ...(reason != null && { reason }),\n };\n if (approved) return { ...c, approval };\n return {\n ...c,\n approval,\n result: { error: reason || \"Tool approval denied\" },\n isError: true,\n };\n });\n\n message = { ...message, content: newContent };\n const { parentId } = this.repository.getMessage(message.id);\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n if (\n this.repository.headId === message.id &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else {\n this._persistPausedMessage(parentId, message);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"local-thread-runtime-core.js","names":["fromThreadMessageLike","generateId","ChatModelAdapter","ChatModelRunResult","shouldContinue","LocalRuntimeOptionsBase","consumeSuggestionResult","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","ThreadRuntimeCore","StartRunConfig","ResumeRunConfig","BaseThreadRuntimeCore","AppendMessage","ThreadAssistantMessage","RunConfig","toAssistantError","ModelContextProvider","createMessageQueue","MessageQueueController","EMPTY_QUEUE_ITEMS","QueueItemState","AbortError","Error","name","detach","constructor","message","LocalThreadRuntimeCore","capabilities","switchToBranch","switchBranchDuringRun","edit","delete","reload","cancel","unstable_copy","speech","dictation","voice","attachments","feedback","queue","abortController","AbortController","_queue","_queueRunInFlight","_historyWrites","Map","Promise","_chainHistoryWrite","id","write","next","get","resolve","then","stored","set","_persistPausedMessage","parentId","status","type","history","_options","adapters","update","bind","item","runConfig","_lastRunConfig","catch","isDisabled","isSendDisabled","_isLoading","isLoading","_suggestions","_suggestionsController","suggestions","contextProvider","options","__internal_setOptions","_getThreadId","__internal_setGetThreadId","getThreadId","_getInitializePromise","__internal_setGetInitializePromise","getPromise","extras","undefined","hasUpdates","canSpeak","canDictate","canVoice","canAttach","canFeedback","canDelete","canQueue","unstable_enableMessageQueue","run","_runAppend","finally","notifyIdle","subscribe","_notifySubscribers","adapter","clear","_loadPromise","__internal_load","promise","load","repo","repository","import","messages","length","ensureInitialized","resume","unstable_resume","startRun","headId","sourceId","append","isTail","at","willRun","role","enqueue","steer","getQueueItems","items","steerQueueItem","queueItemId","removeQueueItem","remove","initPromise","newMessage","reason","addOrUpdateMessage","resetHead","deleteMessage","messageId","getMessages","messageIndex","findIndex","m","resumeRun","stream","startConfig","exportExternalState","importExternalState","runCallback","content","metadata","unstable_state","state","unstable_annotations","unstable_data","steps","custom","createdAt","Date","_runLoop","_notifyEventSubscribers","alreadyPersisted","notifyBusy","abort","performRoundtrip","unstable_humanToolNames","queueMicrotask","suggestion","signal","promiseOrGenerator","generate","onUpdate","r","initialContent","initialAnnotations","initialData","initialSteps","initialCustom","updateMessage","Partial","newSteps","newAnnotations","newData","annotations","data","timing","maxSteps","unstable_composerMetadata","_","context","getModelContext","chatModel","abortSignal","threadId","unstable_assistantMessageId","unstable_threadId","unstable_parentId","unstable_getMessage","Symbol","asyncIterator","aborted","e","error","isTerminal","isPausing","cancelRun","addToolResult","toolCallId","result","isError","artifact","messageData","getMessage","added","found","newContent","map","c","resumeToolCall","respondToToolApproval","approvalId","approved","optionId","findLast","some","approval","target","find","resolution","targetApproval"],"sources":["../../../src/runtimes/local/local-thread-runtime-core.ts"],"sourcesContent":["import { fromThreadMessageLike } from \"../../runtime/utils/thread-message-like\";\nimport { generateId } from \"../../utils/id\";\nimport type {\n ChatModelAdapter,\n ChatModelRunResult,\n} from \"../../runtime/utils/chat-model-adapter\";\nimport { shouldContinue } from \"./should-continue\";\nimport type { LocalRuntimeOptionsBase } from \"./local-runtime-options\";\nimport { consumeSuggestionResult } from \"../../adapters/suggestion\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n ThreadRuntimeCore,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../../runtime/interfaces/thread-runtime-core\";\nimport { BaseThreadRuntimeCore } from \"../../runtime/base/base-thread-runtime-core\";\nimport type {\n AppendMessage,\n ThreadAssistantMessage,\n} from \"../../types/message\";\nimport type { RunConfig } from \"../../types/message\";\nimport { toAssistantError } from \"../../types/error\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport {\n createMessageQueue,\n type MessageQueueController,\n} from \"../../runtime/queue/message-queue\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\n\nclass AbortError extends Error {\n override name = \"AbortError\";\n detach: boolean;\n\n constructor(detach: boolean, message?: string) {\n super(message);\n this.detach = detach;\n }\n}\n\nexport class LocalThreadRuntimeCore\n extends BaseThreadRuntimeCore\n implements ThreadRuntimeCore\n{\n public readonly capabilities = {\n switchToBranch: true,\n switchBranchDuringRun: true,\n edit: true,\n delete: false,\n reload: true,\n cancel: true,\n unstable_copy: true,\n speech: false,\n dictation: false,\n voice: false,\n attachments: false,\n feedback: false,\n queue: false,\n };\n\n private abortController: AbortController | null = null;\n\n private _queue: MessageQueueController | null = null;\n private _queueRunInFlight = false;\n\n private _historyWrites = new Map<string, Promise<void>>();\n\n // Writes for one message id must land in issue order; an earlier paused\n // snapshot arriving after the terminal write would resurrect the pause.\n private _chainHistoryWrite(\n id: string,\n write: () => Promise<void>,\n ): Promise<void> {\n const next = (this._historyWrites.get(id) ?? Promise.resolve()).then(\n write,\n write,\n );\n const stored = next.then(\n () => {},\n () => {},\n );\n this._historyWrites.set(id, stored);\n void stored.then(() => {\n if (this._historyWrites.get(id) === stored) {\n this._historyWrites.delete(id);\n }\n });\n return next;\n }\n\n // A decision recorded on a still-paused message must reach history before\n // the run resumes, or a refresh would restore the message without it.\n private _persistPausedMessage(\n parentId: string | null,\n message: ThreadAssistantMessage,\n ) {\n if (message.status?.type !== \"requires-action\") return;\n const history = this._options.adapters.history;\n if (!history?.update) return;\n const update = history.update.bind(history);\n const item = { parentId, message, runConfig: this._lastRunConfig };\n this._chainHistoryWrite(message.id, () => update(item)).catch(() => {});\n }\n\n public readonly isDisabled = false;\n public readonly isSendDisabled = false;\n\n private _isLoading = false;\n public get isLoading() {\n return this._isLoading;\n }\n\n private _suggestions: readonly ThreadSuggestion[] = [];\n private _suggestionsController: AbortController | null = null;\n public get suggestions(): readonly ThreadSuggestion[] {\n return this._suggestions;\n }\n\n public get adapters() {\n return this._options.adapters;\n }\n\n constructor(\n contextProvider: ModelContextProvider,\n options: LocalRuntimeOptionsBase,\n ) {\n super(contextProvider);\n this.__internal_setOptions(options);\n }\n\n private _options!: LocalRuntimeOptionsBase;\n\n private _lastRunConfig: RunConfig = {};\n\n private _getThreadId?: () => string | undefined;\n\n public __internal_setGetThreadId(getThreadId: () => string | undefined) {\n this._getThreadId = getThreadId;\n }\n\n private _getInitializePromise?: () => Promise<unknown> | undefined;\n\n public __internal_setGetInitializePromise(\n getPromise: () => Promise<unknown> | undefined,\n ) {\n this._getInitializePromise = getPromise;\n }\n\n public get extras() {\n return undefined;\n }\n\n public __internal_setOptions(options: LocalRuntimeOptionsBase) {\n if (this._options === options) return;\n\n this._options = options;\n\n let hasUpdates = false;\n\n const canSpeak = options.adapters?.speech !== undefined;\n if (this.capabilities.speech !== canSpeak) {\n this.capabilities.speech = canSpeak;\n hasUpdates = true;\n }\n\n const canDictate = options.adapters?.dictation !== undefined;\n if (this.capabilities.dictation !== canDictate) {\n this.capabilities.dictation = canDictate;\n hasUpdates = true;\n }\n\n const canVoice = options.adapters?.voice !== undefined;\n if (this.capabilities.voice !== canVoice) {\n this.capabilities.voice = canVoice;\n hasUpdates = true;\n }\n\n const canAttach = options.adapters?.attachments !== undefined;\n if (this.capabilities.attachments !== canAttach) {\n this.capabilities.attachments = canAttach;\n hasUpdates = true;\n }\n\n const canFeedback = options.adapters?.feedback !== undefined;\n if (this.capabilities.feedback !== canFeedback) {\n this.capabilities.feedback = canFeedback;\n hasUpdates = true;\n }\n\n const canDelete = options.adapters?.history?.delete !== undefined;\n if (this.capabilities.delete !== canDelete) {\n this.capabilities.delete = canDelete;\n hasUpdates = true;\n }\n\n const canQueue = options.unstable_enableMessageQueue === true;\n if (canQueue && !this._queue) {\n this._queue = createMessageQueue({\n run: (message) => {\n // release the queue when the dispatch settles, even if it rejects\n // before reaching startRun's finally, so a failure can't deadlock it\n this._queueRunInFlight = true;\n void this._runAppend(message)\n .finally(() => {\n this._queueRunInFlight = false;\n this._queue?.notifyIdle();\n })\n .catch(() => {});\n },\n });\n this._queue.subscribe(() => this._notifySubscribers());\n } else if (!canQueue && this._queue) {\n this._queue.adapter.clear(\"cancel-run\");\n this._queue = null;\n }\n if (this.capabilities.queue !== canQueue) {\n this.capabilities.queue = canQueue;\n hasUpdates = true;\n }\n\n if (hasUpdates) this._notifySubscribers();\n }\n\n private _loadPromise: Promise<void> | undefined;\n public __internal_load() {\n if (this._loadPromise) return this._loadPromise;\n\n const promise = this.adapters.history?.load() ?? Promise.resolve(null);\n\n this._isLoading = true;\n this._notifySubscribers();\n\n this._loadPromise = promise\n .then((repo) => {\n if (!repo) return;\n this.repository.import(repo);\n if (repo.messages.length > 0) {\n this.ensureInitialized();\n }\n this._notifySubscribers();\n\n const resume = this.adapters.history?.resume?.bind(\n this.adapters.history,\n );\n if (repo.unstable_resume && resume) {\n this.startRun(\n {\n parentId: this.repository.headId,\n sourceId: this.repository.headId,\n runConfig: this._lastRunConfig,\n },\n resume,\n ).catch(() => {});\n }\n })\n .finally(() => {\n this._isLoading = false;\n this._notifySubscribers();\n });\n\n return this._loadPromise;\n }\n\n public async append(message: AppendMessage): Promise<void> {\n const isTail = message.parentId === (this.messages.at(-1)?.id ?? null);\n const willRun = message.startRun ?? message.role === \"user\";\n if (this._queue && willRun && isTail) {\n this._queue.adapter.enqueue(message, { steer: message.steer ?? false });\n return;\n }\n if (this._queue && !isTail) this._queue.adapter.clear(\"edit\");\n return this._runAppend(message);\n }\n\n public getQueueItems(): readonly QueueItemState[] {\n // Reads can arrive during base-thread construction, before the queue field\n // is assigned, so guard against the unset field.\n return this._queue?.adapter.items ?? EMPTY_QUEUE_ITEMS;\n }\n\n public steerQueueItem(queueItemId: string): void {\n this._queue?.adapter.steer(queueItemId);\n }\n\n public removeQueueItem(queueItemId: string): void {\n this._queue?.adapter.remove(queueItemId);\n }\n\n private async _runAppend(message: AppendMessage): Promise<void> {\n this.ensureInitialized();\n\n const initPromise = this._getInitializePromise?.();\n if (initPromise) {\n await initPromise;\n }\n\n const newMessage = fromThreadMessageLike(message, generateId(), {\n type: \"complete\",\n reason: \"unknown\",\n });\n this.repository.addOrUpdateMessage(message.parentId, newMessage);\n this._options.adapters.history?.append({\n parentId: message.parentId,\n message: newMessage,\n ...(message.runConfig !== undefined && { runConfig: message.runConfig }),\n });\n\n const startRun = message.startRun ?? message.role === \"user\";\n if (startRun) {\n await this.startRun({\n parentId: newMessage.id,\n sourceId: message.sourceId,\n runConfig: message.runConfig ?? {},\n });\n } else {\n this.repository.resetHead(newMessage.id);\n this._notifySubscribers();\n }\n }\n\n public async deleteMessage(messageId: string): Promise<void> {\n const adapter = this._options.adapters.history;\n if (!adapter?.delete)\n throw new Error(\"Runtime does not support deleting messages.\");\n\n const messages = this.repository.getMessages();\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) throw new Error(\"Message not found.\");\n\n const message = messages[messageIndex]!;\n const parentId = messages[messageIndex - 1]?.id ?? null;\n const items = [{ parentId, message }];\n\n await adapter.delete(items);\n\n this.repository.deleteMessage(messageId);\n this._notifySubscribers();\n }\n\n public resumeRun({ stream, ...startConfig }: ResumeRunConfig): Promise<void> {\n if (!stream)\n throw new Error(\"You must pass a stream parameter to resume runs.\");\n return this.startRun(startConfig, stream);\n }\n\n public exportExternalState(): any {\n throw new Error(\"Runtime does not support exporting external states.\");\n }\n\n public importExternalState(): void {\n throw new Error(\"Runtime does not support importing external states.\");\n }\n\n public async startRun(\n { parentId, runConfig }: StartRunConfig,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this.ensureInitialized();\n\n // add assistant message\n const id = generateId();\n const message: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n createdAt: new Date(),\n };\n\n return this._runLoop(parentId, message, runConfig, runCallback);\n }\n\n private async _runLoop(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this._notifyEventSubscribers(\"runStart\", {});\n\n // A run entered on a requires-action message resumes a pause an\n // update-capable adapter already holds (written at pause time or loaded).\n const alreadyPersisted =\n message.status?.type === \"requires-action\" &&\n this._options.adapters.history?.update !== undefined;\n\n try {\n // mark busy for runs not started through the queue (regenerate, resume)\n this._queue?.notifyBusy();\n this._suggestions = [];\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n this._notifySubscribers();\n\n do {\n message = await this.performRoundtrip(\n parentId,\n message,\n runConfig,\n alreadyPersisted,\n runCallback,\n );\n runCallback = undefined;\n } while (shouldContinue(message, this._options.unstable_humanToolNames));\n } finally {\n this._notifyEventSubscribers(\"runEnd\", {});\n // queue-driven runs release from the driver settle handler; a direct\n // run (regenerate, resume) releases here\n if (!this._queueRunInFlight) {\n queueMicrotask(() => this._queue?.notifyIdle());\n }\n }\n\n if (\n this.adapters.suggestion &&\n message.status?.type !== \"requires-action\"\n ) {\n this._suggestionsController = new AbortController();\n const signal = this._suggestionsController.signal;\n const adapter = this.adapters.suggestion;\n void (async () => {\n try {\n const promiseOrGenerator = adapter.generate({\n messages: this.messages,\n signal,\n });\n await consumeSuggestionResult(promiseOrGenerator, {\n signal,\n onUpdate: (r) => {\n this._suggestions = r;\n this._notifySubscribers();\n },\n });\n } catch {}\n })();\n }\n }\n\n private async performRoundtrip(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n alreadyPersisted: boolean,\n runCallback?: ChatModelAdapter[\"run\"],\n ) {\n const messages = parentId ? this.repository.getMessages(parentId) : [];\n\n // abort existing run\n this.abortController?.abort();\n const abortController = new AbortController();\n this.abortController = abortController;\n\n const initialContent = message.content;\n const initialAnnotations = message.metadata?.unstable_annotations;\n const initialData = message.metadata?.unstable_data;\n const initialSteps = message.metadata?.steps;\n const initialCustom = message.metadata?.custom;\n const updateMessage = (m: Partial<ChatModelRunResult>) => {\n const newSteps = m.metadata?.steps;\n const steps = newSteps\n ? [...(initialSteps ?? []), ...newSteps]\n : undefined;\n\n const newAnnotations = m.metadata?.unstable_annotations;\n const newData = m.metadata?.unstable_data;\n const annotations = newAnnotations\n ? [...(initialAnnotations ?? []), ...newAnnotations]\n : undefined;\n const data = newData ? [...(initialData ?? []), ...newData] : undefined;\n\n message = {\n ...message,\n ...(m.content\n ? { content: [...initialContent, ...(m.content ?? [])] }\n : undefined),\n status: m.status ?? message.status,\n ...(m.metadata\n ? {\n metadata: {\n ...message.metadata,\n ...(m.metadata.unstable_state !== undefined\n ? { unstable_state: m.metadata.unstable_state }\n : undefined),\n ...(annotations\n ? { unstable_annotations: annotations }\n : undefined),\n ...(data ? { unstable_data: data } : undefined),\n ...(steps ? { steps } : undefined),\n ...(m.metadata?.timing\n ? { timing: m.metadata.timing }\n : undefined),\n ...(m.metadata?.custom\n ? {\n custom: {\n ...(initialCustom ?? {}),\n ...m.metadata.custom,\n },\n }\n : undefined),\n },\n }\n : undefined),\n };\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n };\n\n const maxSteps = this._options.maxSteps ?? 2;\n\n try {\n const steps = message.metadata?.steps?.length ?? 0;\n if (steps >= maxSteps) {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"tool-calls\",\n },\n });\n return message;\n }\n\n updateMessage({\n status: {\n type: \"running\",\n },\n });\n\n // Switch to the new message branch right after adding it for the first time\n this.repository.resetHead(message.id);\n this._notifySubscribers();\n\n this._lastRunConfig = runConfig ?? {};\n // unstable_composerMetadata is composer-only (stamped onto the outgoing\n // message); never expose it to the chat-model adapter's run context.\n const { unstable_composerMetadata: _, ...context } =\n this.getModelContext();\n\n runCallback =\n runCallback ??\n this.adapters.chatModel.run.bind(this.adapters.chatModel);\n\n const abortSignal = abortController.signal;\n const threadId = this._getThreadId?.();\n const promiseOrGenerator = runCallback({\n messages,\n runConfig: this._lastRunConfig,\n abortSignal,\n context,\n unstable_assistantMessageId: message.id,\n unstable_threadId: threadId,\n unstable_parentId: parentId,\n unstable_getMessage() {\n return message;\n },\n });\n\n // handle async iterator for streaming results\n if (Symbol.asyncIterator in promiseOrGenerator) {\n for await (const r of promiseOrGenerator) {\n if (abortSignal.aborted) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n break;\n }\n\n updateMessage(r);\n }\n } else {\n updateMessage(await promiseOrGenerator);\n }\n\n if (message.status.type === \"running\") {\n updateMessage({\n status: abortSignal.aborted\n ? { type: \"incomplete\", reason: \"cancelled\" }\n : { type: \"complete\", reason: \"unknown\" },\n });\n }\n } catch (e) {\n if (e instanceof AbortError) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else if (e instanceof Error && e.name === \"AbortError\") {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"error\",\n error: toAssistantError(e),\n },\n });\n\n throw e;\n }\n } finally {\n if (this.abortController === abortController) {\n this.abortController = null;\n }\n\n const history = this._options.adapters.history;\n const item = {\n parentId,\n message,\n runConfig: this._lastRunConfig,\n };\n const isTerminal =\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n const isPausing =\n message.status.type === \"requires-action\" &&\n !shouldContinue(message, this._options.unstable_humanToolNames);\n\n // Pauses are written only for adapters that can rewrite the entry later;\n // an append-only adapter would strand a half-finished run in history.\n if (isTerminal || (isPausing && history?.update)) {\n const write =\n alreadyPersisted && history?.update\n ? history.update.bind(history)\n : history?.append.bind(history);\n if (write) {\n await this._chainHistoryWrite(message.id, () => write(item));\n }\n }\n }\n return message;\n }\n\n public detach() {\n this._queue?.adapter.clear(\"cancel-run\");\n const error = new AbortError(true);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public cancelRun() {\n this._queue?.adapter.clear(\"cancel-run\");\n const error = new AbortError(false);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public addToolResult({\n messageId,\n toolCallId,\n result,\n isError,\n artifact,\n }: AddToolResultOptions) {\n const messageData = this.repository.getMessage(messageId);\n const { parentId } = messageData;\n let { message } = messageData;\n\n if (message.role !== \"assistant\")\n throw new Error(\"Tried to add tool result to non-assistant message\");\n\n let added = false;\n let found = false;\n const newContent = message.content.map((c) => {\n if (c.type !== \"tool-call\") return c;\n if (c.toolCallId !== toolCallId) return c;\n found = true;\n if (!c.result) added = true;\n return {\n ...c,\n result,\n artifact,\n isError,\n };\n });\n\n if (!found)\n throw new Error(\"Tried to add tool result to non-existing tool call\");\n\n message = {\n ...message,\n content: newContent,\n };\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n // a result may arrive mid-run or on a non-head message; the resume\n // intentionally aborts any in-flight run, unlike respondToToolApproval\n if (\n added &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else if (added) {\n this._persistPausedMessage(parentId, message);\n }\n }\n\n public resumeToolCall(_options: ResumeToolCallOptions) {\n throw new Error(\n \"Local runtime does not support resuming tool calls. For human-in-the-loop tools, list the tool in unstable_humanToolNames and complete the call with addToolResult.\",\n );\n }\n\n public respondToToolApproval({\n approvalId,\n approved,\n optionId,\n reason,\n }: RespondToToolApprovalOptions) {\n let message = this.repository\n .getMessages()\n .findLast(\n (m): m is ThreadAssistantMessage =>\n m.role === \"assistant\" &&\n m.content.some(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n ),\n );\n\n if (!message)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n\n if (this.abortController !== null)\n throw new Error(\n \"Tried to respond to a tool approval while a run is in progress\",\n );\n\n if (message.status?.type !== \"requires-action\")\n throw new Error(\n \"Tried to respond to a tool approval on a message whose status is not requires-action\",\n );\n\n const target = message.content.find(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n );\n if (target?.type !== \"tool-call\" || !target.approval)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n if (target.approval.resolution !== undefined)\n throw new Error(\n \"Tried to respond to a tool approval that was cancelled or expired\",\n );\n if (target.approval.approved !== undefined)\n throw new Error(\"Tried to respond to an already decided tool approval\");\n\n const targetApproval = target.approval;\n const newContent = message.content.map((c) => {\n if (c !== target) return c;\n const approval = {\n ...targetApproval,\n approved,\n ...(optionId != null && { optionId }),\n ...(reason != null && { reason }),\n };\n if (approved) return { ...c, approval };\n return {\n ...c,\n approval,\n result: { error: reason || \"Tool approval denied\" },\n isError: true,\n };\n });\n\n message = { ...message, content: newContent };\n const { parentId } = this.repository.getMessage(message.id);\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n if (\n this.repository.headId === message.id &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else {\n this._persistPausedMessage(parentId, message);\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Framework-agnostic core runtime for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"assistant",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
],
|
|
60
60
|
"sideEffects": false,
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"assistant-stream": "^0.3.
|
|
62
|
+
"assistant-stream": "^0.3.30",
|
|
63
63
|
"nanoid": "^6.0.0"
|
|
64
64
|
},
|
|
65
65
|
"optionalDevDependencies": {
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"react-dom": "^19.2.8",
|
|
96
96
|
"vitest": "^4.1.10",
|
|
97
97
|
"zustand": "^5.0.14",
|
|
98
|
-
"@assistant-ui/store": "0.3.
|
|
98
|
+
"@assistant-ui/store": "0.3.1",
|
|
99
99
|
"@assistant-ui/tap": "0.9.7",
|
|
100
100
|
"@assistant-ui/vite": "0.0.11",
|
|
101
101
|
"@assistant-ui/x-buildutils": "0.0.20",
|
|
@@ -90,14 +90,10 @@ const useInteractable = <TSchema extends Unstable_InteractableStateSchema>(
|
|
|
90
90
|
|
|
91
91
|
const autoId = useId().replace(/[^a-zA-Z0-9]/g, "");
|
|
92
92
|
|
|
93
|
-
// Whether this component renders inside a message part is fixed for its
|
|
94
|
-
// lifetime, so conditioning the selectors on it is safe.
|
|
95
|
-
const inPart = aui.part.source != null;
|
|
96
93
|
const updateToolName = interactableToolName(name);
|
|
97
94
|
const part = useAuiState((s) => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return p.type === "tool-call" ? p : undefined;
|
|
95
|
+
const p = s.optional.part;
|
|
96
|
+
return p?.type === "tool-call" ? p : undefined;
|
|
101
97
|
});
|
|
102
98
|
|
|
103
99
|
// Inside an update_{name} part, the instance id comes from the call itself:
|
|
@@ -497,6 +497,44 @@ describe("LocalThreadRuntimeCore tool approvals", () => {
|
|
|
497
497
|
});
|
|
498
498
|
|
|
499
499
|
describe("LocalThreadRuntimeCore cancellation", () => {
|
|
500
|
+
it("keeps a replacement run cancellable after the previous run settles", async () => {
|
|
501
|
+
let releaseFirst!: () => void;
|
|
502
|
+
let releaseSecond!: () => void;
|
|
503
|
+
const firstGate = new Promise<void>((resolve) => {
|
|
504
|
+
releaseFirst = resolve;
|
|
505
|
+
});
|
|
506
|
+
const secondGate = new Promise<void>((resolve) => {
|
|
507
|
+
releaseSecond = resolve;
|
|
508
|
+
});
|
|
509
|
+
const signals: AbortSignal[] = [];
|
|
510
|
+
const thread = createThread({
|
|
511
|
+
async *run({ abortSignal }) {
|
|
512
|
+
signals.push(abortSignal);
|
|
513
|
+
await (signals.length === 1 ? firstGate : secondGate);
|
|
514
|
+
},
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
const firstAppend = thread.append(userMessage("first"));
|
|
518
|
+
await flush();
|
|
519
|
+
const secondAppend = thread.append(userMessage("second"));
|
|
520
|
+
await flush();
|
|
521
|
+
|
|
522
|
+
expect(signals).toHaveLength(2);
|
|
523
|
+
expect(signals[0]?.aborted).toBe(true);
|
|
524
|
+
expect(signals[1]?.aborted).toBe(false);
|
|
525
|
+
|
|
526
|
+
releaseFirst();
|
|
527
|
+
await firstAppend;
|
|
528
|
+
|
|
529
|
+
thread.cancelRun();
|
|
530
|
+
const replacementWasAborted = signals[1]?.aborted;
|
|
531
|
+
|
|
532
|
+
releaseSecond();
|
|
533
|
+
await secondAppend;
|
|
534
|
+
|
|
535
|
+
expect(replacementWasAborted).toBe(true);
|
|
536
|
+
});
|
|
537
|
+
|
|
500
538
|
it("marks the message cancelled when a streaming adapter returns after abort", async () => {
|
|
501
539
|
let released!: () => void;
|
|
502
540
|
const streaming = new Promise<void>((resolve) => {
|
|
@@ -459,7 +459,8 @@ export class LocalThreadRuntimeCore
|
|
|
459
459
|
|
|
460
460
|
// abort existing run
|
|
461
461
|
this.abortController?.abort();
|
|
462
|
-
|
|
462
|
+
const abortController = new AbortController();
|
|
463
|
+
this.abortController = abortController;
|
|
463
464
|
|
|
464
465
|
const initialContent = message.content;
|
|
465
466
|
const initialAnnotations = message.metadata?.unstable_annotations;
|
|
@@ -550,7 +551,7 @@ export class LocalThreadRuntimeCore
|
|
|
550
551
|
runCallback ??
|
|
551
552
|
this.adapters.chatModel.run.bind(this.adapters.chatModel);
|
|
552
553
|
|
|
553
|
-
const abortSignal =
|
|
554
|
+
const abortSignal = abortController.signal;
|
|
554
555
|
const threadId = this._getThreadId?.();
|
|
555
556
|
const promiseOrGenerator = runCallback({
|
|
556
557
|
messages,
|
|
@@ -609,7 +610,9 @@ export class LocalThreadRuntimeCore
|
|
|
609
610
|
throw e;
|
|
610
611
|
}
|
|
611
612
|
} finally {
|
|
612
|
-
this.abortController
|
|
613
|
+
if (this.abortController === abortController) {
|
|
614
|
+
this.abortController = null;
|
|
615
|
+
}
|
|
613
616
|
|
|
614
617
|
const history = this._options.adapters.history;
|
|
615
618
|
const item = {
|