@assistant-ui/core 0.3.14 → 0.3.15
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/adapters/voice.js +11 -0
- package/dist/adapters/voice.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +2 -1
- package/dist/internal.js +2 -1
- package/dist/model-context/frame/host.d.ts +1 -1
- package/dist/model-context/frame/host.d.ts.map +1 -1
- package/dist/model-context/frame/host.js +17 -3
- package/dist/model-context/frame/host.js.map +1 -1
- package/dist/model-context/frame/provider.d.ts +4 -0
- package/dist/model-context/frame/provider.d.ts.map +1 -1
- package/dist/model-context/frame/provider.js +50 -3
- package/dist/model-context/frame/provider.js.map +1 -1
- package/dist/model-context/frame/types.d.ts +4 -1
- package/dist/model-context/frame/types.d.ts.map +1 -1
- package/dist/model-context/frame/types.js.map +1 -1
- package/dist/react/client/RemoteThreadList.d.ts +1 -1
- package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
- package/dist/react/client/RemoteThreadList.js +95 -23
- package/dist/react/client/RemoteThreadList.js.map +1 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js +7 -1
- package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
- package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
- package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +2 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +6 -0
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +6 -0
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +192 -50
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadResource.js +2 -0
- package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +1 -1
- package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +38 -5
- package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
- package/dist/runtime/utils/message-repository.d.ts.map +1 -1
- package/dist/runtime/utils/message-repository.js +27 -18
- package/dist/runtime/utils/message-repository.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +2 -0
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
- package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +25 -6
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -60
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -145
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
- package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -155
- package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
- package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
- package/dist/runtimes/remote-thread-list/types.d.ts +3 -0
- package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
- package/dist/store/clients/external-thread.js +1 -1
- package/dist/store/clients/external-thread.js.map +1 -1
- package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
- package/dist/store/runtime-clients/handle-runtime-action.js +2 -0
- package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -1
- package/dist/types/message.d.ts +1 -1
- package/dist/types/message.js.map +1 -1
- package/dist/utils/silent-runtime-action.d.ts +6 -0
- package/dist/utils/silent-runtime-action.d.ts.map +1 -0
- package/dist/utils/silent-runtime-action.js +7 -0
- package/dist/utils/silent-runtime-action.js.map +1 -0
- package/package.json +4 -4
- package/src/adapters/voice.test.ts +66 -1
- package/src/adapters/voice.ts +8 -0
- package/src/internal.ts +1 -0
- package/src/model-context/frame/host.test.ts +64 -5
- package/src/model-context/frame/host.ts +16 -3
- package/src/model-context/frame/provider.test.ts +347 -20
- package/src/model-context/frame/provider.ts +58 -2
- package/src/model-context/frame/types.ts +5 -0
- package/src/react/client/RemoteThreadList.test.ts +196 -0
- package/src/react/client/RemoteThreadList.ts +93 -24
- package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
- package/src/react/primitive-hooks/useActionBarCopy.ts +13 -3
- package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
- package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
- package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +12 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
- package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +268 -63
- package/src/react/runtimes/RemoteThreadResource.ts +2 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +58 -0
- package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +3 -1
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
- package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +68 -6
- package/src/react/runtimes/useLocalRuntime.test.tsx +5 -5
- package/src/runtime/utils/message-repository.ts +26 -18
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +4 -0
- package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
- package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
- package/src/runtimes/local/local-thread-runtime-core.test.ts +319 -0
- package/src/runtimes/local/local-thread-runtime-core.ts +38 -8
- package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -209
- package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
- package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -221
- package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
- package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
- package/src/runtimes/remote-thread-list/types.ts +4 -0
- package/src/store/clients/external-thread.ts +1 -1
- package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
- package/src/store/runtime-clients/handle-runtime-action.ts +3 -0
- package/src/tests/MessageRepository.test.ts +48 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
- package/src/tests/empty-thread-core.test.ts +6 -0
- package/src/tests/external-store-thread-runtime-core-adapter.test.ts +20 -0
- package/src/tests/external-thread-isEmpty.test.tsx +100 -0
- package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
- package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
- package/src/types/message.ts +1 -1
- package/src/utils/silent-runtime-action.ts +6 -0
package/dist/adapters/voice.js
CHANGED
|
@@ -66,6 +66,13 @@ function createVoiceSession(options, setup) {
|
|
|
66
66
|
if (disconnected) return;
|
|
67
67
|
disconnected = true;
|
|
68
68
|
detachAbortHandler();
|
|
69
|
+
if (currentStatus.type !== "ended") {
|
|
70
|
+
currentStatus = {
|
|
71
|
+
type: "ended",
|
|
72
|
+
reason: "cancelled"
|
|
73
|
+
};
|
|
74
|
+
notifyEventListeners(statusCbs, currentStatus, "Voice session");
|
|
75
|
+
}
|
|
69
76
|
try {
|
|
70
77
|
controls?.disconnect();
|
|
71
78
|
} finally {
|
|
@@ -100,6 +107,10 @@ function createVoiceSession(options, setup) {
|
|
|
100
107
|
if (abortSignal) {
|
|
101
108
|
abortHandler = () => session.disconnect();
|
|
102
109
|
abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
110
|
+
if (abortSignal.aborted) {
|
|
111
|
+
session.disconnect();
|
|
112
|
+
return session;
|
|
113
|
+
}
|
|
103
114
|
}
|
|
104
115
|
const doSetup = async () => {
|
|
105
116
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice.js","names":["Unsubscribe","notifyEventListeners","RealtimeVoiceAdapter","Status","type","reason","error","Mode","TranscriptItem","role","text","isFinal","Session","status","isMuted","disconnect","mute","unmute","onStatusChange","callback","onTranscript","transcript","onModeChange","mode","onVolumeChange","volume","connect","options","abortSignal","AbortSignal","VoiceSessionControls","VoiceSessionHelpers","setStatus","end","emitTranscript","item","emitMode","emitVolume","isDisposed","createVoiceSession","setup","helpers","Promise","statusCbs","Set","s","transcriptCbs","t","modeCbs","m","volumeCbs","v","currentStatus","disposed","disconnected","controls","abortHandler","detachAbortHandler","removeEventListener","undefined","cleanup","clear","session","cb","add","delete","addEventListener","once","doSetup"],"sources":["../../src/adapters/voice.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\nimport { notifyEventListeners } from \"../utils/notify-event-listeners\";\n\nexport namespace RealtimeVoiceAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"finished\" | \"cancelled\" | \"error\";\n error?: unknown;\n };\n\n export type Mode = \"listening\" | \"speaking\";\n\n export type TranscriptItem = {\n role: \"user\" | \"assistant\";\n text: string;\n isFinal?: boolean;\n };\n\n export type Session = {\n status: Status;\n isMuted: boolean;\n\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n\n onStatusChange: (callback: (status: Status) => void) => Unsubscribe;\n onTranscript: (\n callback: (transcript: TranscriptItem) => void,\n ) => Unsubscribe;\n onModeChange: (callback: (mode: Mode) => void) => Unsubscribe;\n onVolumeChange: (callback: (volume: number) => void) => Unsubscribe;\n };\n}\n\nexport type RealtimeVoiceAdapter = {\n connect: (options: {\n abortSignal?: AbortSignal;\n }) => RealtimeVoiceAdapter.Session;\n};\n\nexport type VoiceSessionControls = {\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n};\n\nexport type VoiceSessionHelpers = {\n setStatus: (status: RealtimeVoiceAdapter.Status) => void;\n end: (reason: \"finished\" | \"cancelled\" | \"error\", error?: unknown) => void;\n emitTranscript: (item: RealtimeVoiceAdapter.TranscriptItem) => void;\n emitMode: (mode: RealtimeVoiceAdapter.Mode) => void;\n emitVolume: (volume: number) => void;\n isDisposed: () => boolean;\n};\n\nexport function createVoiceSession(\n options: { abortSignal?: AbortSignal },\n setup: (helpers: VoiceSessionHelpers) => Promise<VoiceSessionControls>,\n): RealtimeVoiceAdapter.Session {\n const statusCbs = new Set<(s: RealtimeVoiceAdapter.Status) => void>();\n const transcriptCbs = new Set<\n (t: RealtimeVoiceAdapter.TranscriptItem) => void\n >();\n const modeCbs = new Set<(m: RealtimeVoiceAdapter.Mode) => void>();\n const volumeCbs = new Set<(v: number) => void>();\n\n let currentStatus: RealtimeVoiceAdapter.Status = { type: \"starting\" };\n let isMuted = false;\n let disposed = false;\n let disconnected = false;\n let controls: VoiceSessionControls | null = null;\n const abortSignal = options.abortSignal;\n let abortHandler: (() => void) | undefined;\n\n const detachAbortHandler = () => {\n if (abortHandler) {\n abortSignal?.removeEventListener(\"abort\", abortHandler);\n abortHandler = undefined;\n }\n };\n\n const cleanup = () => {\n disposed = true;\n statusCbs.clear();\n transcriptCbs.clear();\n modeCbs.clear();\n volumeCbs.clear();\n };\n\n const helpers: VoiceSessionHelpers = {\n setStatus: (status) => {\n if (disposed) return;\n currentStatus = status;\n notifyEventListeners(statusCbs, status, \"Voice session\");\n },\n end: (reason, error?) => {\n if (disposed) return;\n currentStatus = { type: \"ended\", reason, error };\n notifyEventListeners(statusCbs, currentStatus, \"Voice session\");\n cleanup();\n },\n emitTranscript: (item) => {\n if (disposed) return;\n notifyEventListeners(transcriptCbs, item, \"Voice session\");\n },\n emitMode: (mode) => {\n if (disposed) return;\n notifyEventListeners(modeCbs, mode, \"Voice session\");\n },\n emitVolume: (volume) => {\n if (disposed) return;\n notifyEventListeners(volumeCbs, volume, \"Voice session\");\n },\n isDisposed: () => disposed,\n };\n\n const session: RealtimeVoiceAdapter.Session = {\n get status() {\n return currentStatus;\n },\n get isMuted() {\n return isMuted;\n },\n disconnect: () => {\n if (disconnected) return;\n disconnected = true;\n detachAbortHandler();\n try {\n controls?.disconnect();\n } finally {\n cleanup();\n }\n },\n mute: () => {\n controls?.mute();\n isMuted = true;\n },\n unmute: () => {\n controls?.unmute();\n isMuted = false;\n },\n onStatusChange: (cb) => {\n statusCbs.add(cb);\n return () => statusCbs.delete(cb);\n },\n onTranscript: (cb) => {\n transcriptCbs.add(cb);\n return () => transcriptCbs.delete(cb);\n },\n onModeChange: (cb) => {\n modeCbs.add(cb);\n return () => modeCbs.delete(cb);\n },\n onVolumeChange: (cb) => {\n volumeCbs.add(cb);\n return () => volumeCbs.delete(cb);\n },\n };\n\n if (abortSignal) {\n abortHandler = () => session.disconnect();\n abortSignal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n\n const doSetup = async () => {\n try {\n if (disposed) return;\n controls = await setup(helpers);\n if (disposed) {\n controls.disconnect();\n } else if (isMuted) {\n controls.mute();\n }\n } catch (error) {\n helpers.end(\"error\", error);\n }\n };\n\n doSetup();\n return session;\n}\n"],"mappings":";;AA4DA,SAAgBuC,mBACdZ,SACAa,OAC8B;CAC9B,MAAMG,4BAAY,IAAIC,IAA8C;CACpE,MAAME,gCAAgB,IAAIF,IAExB;CACF,MAAMI,0BAAU,IAAIJ,IAA4C;CAChE,MAAMM,4BAAY,IAAIN,IAAyB;CAE/C,IAAIQ,gBAA6C,EAAEhD,MAAM,WAAW;CACpE,IAAIU,UAAU;CACd,IAAIuC,WAAW;CACf,IAAIC,eAAe;CACnB,IAAIC,WAAwC;CAC5C,MAAM3B,cAAcD,QAAQC;CAC5B,IAAI4B;CAEJ,MAAMC,2BAA2B;EAC/B,IAAID,cAAc;GAChB5B,aAAa8B,oBAAoB,SAASF,YAAY;GACtDA,eAAeG,KAAAA;EACjB;CACF;CAEA,MAAMC,gBAAgB;EACpBP,WAAW;EACXV,UAAUkB,MAAM;EAChBf,cAAce,MAAM;EACpBb,QAAQa,MAAM;EACdX,UAAUW,MAAM;CAClB;CAEA,MAAMpB,UAA+B;EACnCT,YAAYnB,WAAW;GACrB,IAAIwC,UAAU;GACdD,gBAAgBvC;GAChBZ,qBAAqB0C,WAAW9B,QAAQ,eAAe;EACzD;EACAoB,MAAM5B,QAAQC,UAAW;GACvB,IAAI+C,UAAU;GACdD,gBAAgB;IAAEhD,MAAM;IAASC;IAAQC;GAAM;GAC/CL,qBAAqB0C,WAAWS,eAAe,eAAe;GAC9DQ,QAAQ;EACV;EACA1B,iBAAiBC,SAAS;GACxB,IAAIkB,UAAU;GACdpD,qBAAqB6C,eAAeX,MAAM,eAAe;EAC3D;EACAC,WAAWb,SAAS;GAClB,IAAI8B,UAAU;GACdpD,qBAAqB+C,SAASzB,MAAM,eAAe;EACrD;EACAc,aAAaZ,WAAW;GACtB,IAAI4B,UAAU;GACdpD,qBAAqBiD,WAAWzB,QAAQ,eAAe;EACzD;EACAa,kBAAkBe;CACpB;CAEA,MAAMS,UAAwC;EAC5C,IAAIjD,SAAS;GACX,OAAOuC;EACT;EACA,IAAItC,UAAU;GACZ,OAAOA;EACT;EACAC,kBAAkB;GAChB,IAAIuC,cAAc;GAClBA,eAAe;GACfG,mBAAmB;GACnB,IAAI;
|
|
1
|
+
{"version":3,"file":"voice.js","names":["Unsubscribe","notifyEventListeners","RealtimeVoiceAdapter","Status","type","reason","error","Mode","TranscriptItem","role","text","isFinal","Session","status","isMuted","disconnect","mute","unmute","onStatusChange","callback","onTranscript","transcript","onModeChange","mode","onVolumeChange","volume","connect","options","abortSignal","AbortSignal","VoiceSessionControls","VoiceSessionHelpers","setStatus","end","emitTranscript","item","emitMode","emitVolume","isDisposed","createVoiceSession","setup","helpers","Promise","statusCbs","Set","s","transcriptCbs","t","modeCbs","m","volumeCbs","v","currentStatus","disposed","disconnected","controls","abortHandler","detachAbortHandler","removeEventListener","undefined","cleanup","clear","session","cb","add","delete","addEventListener","once","aborted","doSetup"],"sources":["../../src/adapters/voice.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\nimport { notifyEventListeners } from \"../utils/notify-event-listeners\";\n\nexport namespace RealtimeVoiceAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"finished\" | \"cancelled\" | \"error\";\n error?: unknown;\n };\n\n export type Mode = \"listening\" | \"speaking\";\n\n export type TranscriptItem = {\n role: \"user\" | \"assistant\";\n text: string;\n isFinal?: boolean;\n };\n\n export type Session = {\n status: Status;\n isMuted: boolean;\n\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n\n onStatusChange: (callback: (status: Status) => void) => Unsubscribe;\n onTranscript: (\n callback: (transcript: TranscriptItem) => void,\n ) => Unsubscribe;\n onModeChange: (callback: (mode: Mode) => void) => Unsubscribe;\n onVolumeChange: (callback: (volume: number) => void) => Unsubscribe;\n };\n}\n\nexport type RealtimeVoiceAdapter = {\n connect: (options: {\n abortSignal?: AbortSignal;\n }) => RealtimeVoiceAdapter.Session;\n};\n\nexport type VoiceSessionControls = {\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n};\n\nexport type VoiceSessionHelpers = {\n setStatus: (status: RealtimeVoiceAdapter.Status) => void;\n end: (reason: \"finished\" | \"cancelled\" | \"error\", error?: unknown) => void;\n emitTranscript: (item: RealtimeVoiceAdapter.TranscriptItem) => void;\n emitMode: (mode: RealtimeVoiceAdapter.Mode) => void;\n emitVolume: (volume: number) => void;\n isDisposed: () => boolean;\n};\n\nexport function createVoiceSession(\n options: { abortSignal?: AbortSignal },\n setup: (helpers: VoiceSessionHelpers) => Promise<VoiceSessionControls>,\n): RealtimeVoiceAdapter.Session {\n const statusCbs = new Set<(s: RealtimeVoiceAdapter.Status) => void>();\n const transcriptCbs = new Set<\n (t: RealtimeVoiceAdapter.TranscriptItem) => void\n >();\n const modeCbs = new Set<(m: RealtimeVoiceAdapter.Mode) => void>();\n const volumeCbs = new Set<(v: number) => void>();\n\n let currentStatus: RealtimeVoiceAdapter.Status = { type: \"starting\" };\n let isMuted = false;\n let disposed = false;\n let disconnected = false;\n let controls: VoiceSessionControls | null = null;\n const abortSignal = options.abortSignal;\n let abortHandler: (() => void) | undefined;\n\n const detachAbortHandler = () => {\n if (abortHandler) {\n abortSignal?.removeEventListener(\"abort\", abortHandler);\n abortHandler = undefined;\n }\n };\n\n const cleanup = () => {\n disposed = true;\n statusCbs.clear();\n transcriptCbs.clear();\n modeCbs.clear();\n volumeCbs.clear();\n };\n\n const helpers: VoiceSessionHelpers = {\n setStatus: (status) => {\n if (disposed) return;\n currentStatus = status;\n notifyEventListeners(statusCbs, status, \"Voice session\");\n },\n end: (reason, error?) => {\n if (disposed) return;\n currentStatus = { type: \"ended\", reason, error };\n notifyEventListeners(statusCbs, currentStatus, \"Voice session\");\n cleanup();\n },\n emitTranscript: (item) => {\n if (disposed) return;\n notifyEventListeners(transcriptCbs, item, \"Voice session\");\n },\n emitMode: (mode) => {\n if (disposed) return;\n notifyEventListeners(modeCbs, mode, \"Voice session\");\n },\n emitVolume: (volume) => {\n if (disposed) return;\n notifyEventListeners(volumeCbs, volume, \"Voice session\");\n },\n isDisposed: () => disposed,\n };\n\n const session: RealtimeVoiceAdapter.Session = {\n get status() {\n return currentStatus;\n },\n get isMuted() {\n return isMuted;\n },\n disconnect: () => {\n if (disconnected) return;\n disconnected = true;\n detachAbortHandler();\n if (currentStatus.type !== \"ended\") {\n currentStatus = { type: \"ended\", reason: \"cancelled\" };\n notifyEventListeners(statusCbs, currentStatus, \"Voice session\");\n }\n try {\n controls?.disconnect();\n } finally {\n cleanup();\n }\n },\n mute: () => {\n controls?.mute();\n isMuted = true;\n },\n unmute: () => {\n controls?.unmute();\n isMuted = false;\n },\n onStatusChange: (cb) => {\n statusCbs.add(cb);\n return () => statusCbs.delete(cb);\n },\n onTranscript: (cb) => {\n transcriptCbs.add(cb);\n return () => transcriptCbs.delete(cb);\n },\n onModeChange: (cb) => {\n modeCbs.add(cb);\n return () => modeCbs.delete(cb);\n },\n onVolumeChange: (cb) => {\n volumeCbs.add(cb);\n return () => volumeCbs.delete(cb);\n },\n };\n\n if (abortSignal) {\n abortHandler = () => session.disconnect();\n abortSignal.addEventListener(\"abort\", abortHandler, { once: true });\n if (abortSignal.aborted) {\n session.disconnect();\n return session;\n }\n }\n\n const doSetup = async () => {\n try {\n if (disposed) return;\n controls = await setup(helpers);\n if (disposed) {\n controls.disconnect();\n } else if (isMuted) {\n controls.mute();\n }\n } catch (error) {\n helpers.end(\"error\", error);\n }\n };\n\n doSetup();\n return session;\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,10 @@ import { mergeModelContexts } from "./model-context/types.js";
|
|
|
4
4
|
import { tool } from "./model-context/tool.js";
|
|
5
5
|
import { unstable_formatInteractableSnapshot, unstable_getInteractableSnapshots, unstable_getInteractableVersions } from "./model-context/interactable-composer-metadata.js";
|
|
6
6
|
import { ModelContextRegistry } from "./model-context/registry.js";
|
|
7
|
+
import { generateId } from "./utils/id.js";
|
|
7
8
|
import { FRAME_MESSAGE_CHANNEL } from "./model-context/frame/types.js";
|
|
8
9
|
import { AssistantFrameHost } from "./model-context/frame/host.js";
|
|
9
10
|
import { AssistantFrameProvider } from "./model-context/frame/provider.js";
|
|
10
|
-
import { generateId } from "./utils/id.js";
|
|
11
11
|
import { CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter } from "./adapters/attachment.js";
|
|
12
12
|
import { WebSpeechDictationAdapter, WebSpeechSynthesisAdapter } from "./adapters/speech.js";
|
|
13
13
|
import { createVoiceSession } from "./adapters/voice.js";
|
package/dist/internal.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { BaseSubject, BaseSubscribable, EventSubscribable, EventSubscriptionSubj
|
|
|
8
8
|
import { generateErrorMessageId, generateId, isErrorMessageId } from "./utils/id.js";
|
|
9
9
|
import { getThreadMessageText } from "./utils/text.js";
|
|
10
10
|
import { toMessagePartStatus } from "./utils/normalizePartStatus.js";
|
|
11
|
+
import { notifyEventListeners } from "./utils/notify-event-listeners.js";
|
|
11
12
|
import { resolveToolApprovalResponse } from "./runtime/utils/resolveToolApprovalResponse.js";
|
|
12
13
|
import { CompositeContextProvider } from "./utils/composite-context-provider.js";
|
|
13
14
|
import { stableStringifyToolArgs, trackToolArgsKeyOrder } from "./utils/json/stable-stringify-tool-args.js";
|
|
@@ -47,4 +48,4 @@ import { RemoteThreadData, RemoteThreadState, THREAD_MAPPING_ID, createThreadMap
|
|
|
47
48
|
import "./runtimes/internal.js";
|
|
48
49
|
import { ThreadListItemRuntimeBinding, ThreadRuntimeCoreBinding, ThreadRuntimeImpl, getThreadState } from "./runtime/api/thread-runtime.js";
|
|
49
50
|
import { AssistantRuntimeImpl } from "./runtime/api/assistant-runtime.js";
|
|
50
|
-
export { AssistantRuntimeImpl, AttachmentRuntimeImpl, BaseAssistantRuntimeCore, BaseComposerRuntimeCore, BaseSubject, BaseSubscribable, BaseThreadRuntimeCore, type ComposerRuntimeCoreBinding, ComposerRuntimeImpl, CompositeContextProvider, type ConverterCallback, DefaultEditComposerRuntimeCore, DefaultThreadComposerRuntimeCore, EMPTY_THREAD_CORE, EditComposerAttachmentRuntimeImpl, type EditComposerRuntimeCoreBinding, EditComposerRuntimeImpl, type EventSubscribable, EventSubscriptionSubject, ExportedMessageRepository, type ExportedMessageRepositoryItem, ExternalStoreRuntimeCore, type ExternalStoreThreadFactory, ExternalStoreThreadListRuntimeCore, ExternalStoreThreadRuntimeCore, LazyMemoizeSubject, LocalRuntimeCore, type LocalRuntimeOptionsBase, type LocalThreadFactory, LocalThreadListRuntimeCore, LocalThreadRuntimeCore, MessageAttachmentRuntimeImpl, MessagePartRuntimeImpl, MessageRepository, MessageRuntimeImpl, type MessageStateBinding, type NestedSubscribable, NestedSubscriptionSubject, OptimisticState, ReadonlyThreadRuntimeCore, type RemoteThreadData, type RemoteThreadInitializeResponse, type RemoteThreadListOptions, type RemoteThreadState, SKIP_UPDATE, type SKIP_UPDATE as SKIP_UPDATE_TYPE, ShallowMemoizeSubject, type Subscribable, type SubscribableWithState, type THREAD_MAPPING_ID, ThreadComposerAttachmentRuntimeImpl, type ThreadComposerRuntimeCoreBinding, ThreadComposerRuntimeImpl, type ThreadListItemRuntimeBinding, ThreadListItemRuntimeImpl, type ThreadListItemStateBinding, type ThreadListRuntimeCoreBinding, ThreadListRuntimeImpl, ThreadMessageConverter, type ThreadRuntimeCoreBinding, ThreadRuntimeImpl, ToolInvocationTracker, consumeSuggestionResult, createThreadMappingId, dataUrlMediaType, detectImageMediaType, fileMatchesAccept, fromThreadMessageLike, generateErrorMessageId, generateId, getAutoStatus, getFileDataURL, getThreadData, getThreadMessageText, getThreadState, hasUpcomingMessage, httpUrlPattern, isAutoStatus, isCreateAttachment, isErrorMessageId, isJSONValue, isParsableUrl, isRecord, parseDataUrl, resolveFileMediaType, resolveImageMediaType, resolveToolApprovalResponse, shouldContinue, stableStringifyToolArgs, symbolInnerMessage, toMediaWireUrl, toMessagePartStatus, trackToolArgsKeyOrder, updateStatusReducer };
|
|
51
|
+
export { AssistantRuntimeImpl, AttachmentRuntimeImpl, BaseAssistantRuntimeCore, BaseComposerRuntimeCore, BaseSubject, BaseSubscribable, BaseThreadRuntimeCore, type ComposerRuntimeCoreBinding, ComposerRuntimeImpl, CompositeContextProvider, type ConverterCallback, DefaultEditComposerRuntimeCore, DefaultThreadComposerRuntimeCore, EMPTY_THREAD_CORE, EditComposerAttachmentRuntimeImpl, type EditComposerRuntimeCoreBinding, EditComposerRuntimeImpl, type EventSubscribable, EventSubscriptionSubject, ExportedMessageRepository, type ExportedMessageRepositoryItem, ExternalStoreRuntimeCore, type ExternalStoreThreadFactory, ExternalStoreThreadListRuntimeCore, ExternalStoreThreadRuntimeCore, LazyMemoizeSubject, LocalRuntimeCore, type LocalRuntimeOptionsBase, type LocalThreadFactory, LocalThreadListRuntimeCore, LocalThreadRuntimeCore, MessageAttachmentRuntimeImpl, MessagePartRuntimeImpl, MessageRepository, MessageRuntimeImpl, type MessageStateBinding, type NestedSubscribable, NestedSubscriptionSubject, OptimisticState, ReadonlyThreadRuntimeCore, type RemoteThreadData, type RemoteThreadInitializeResponse, type RemoteThreadListOptions, type RemoteThreadState, SKIP_UPDATE, type SKIP_UPDATE as SKIP_UPDATE_TYPE, ShallowMemoizeSubject, type Subscribable, type SubscribableWithState, type THREAD_MAPPING_ID, ThreadComposerAttachmentRuntimeImpl, type ThreadComposerRuntimeCoreBinding, ThreadComposerRuntimeImpl, type ThreadListItemRuntimeBinding, ThreadListItemRuntimeImpl, type ThreadListItemStateBinding, type ThreadListRuntimeCoreBinding, ThreadListRuntimeImpl, ThreadMessageConverter, type ThreadRuntimeCoreBinding, ThreadRuntimeImpl, ToolInvocationTracker, consumeSuggestionResult, createThreadMappingId, dataUrlMediaType, detectImageMediaType, fileMatchesAccept, fromThreadMessageLike, generateErrorMessageId, generateId, getAutoStatus, getFileDataURL, getThreadData, getThreadMessageText, getThreadState, hasUpcomingMessage, httpUrlPattern, isAutoStatus, isCreateAttachment, isErrorMessageId, isJSONValue, isParsableUrl, isRecord, notifyEventListeners, parseDataUrl, resolveFileMediaType, resolveImageMediaType, resolveToolApprovalResponse, shouldContinue, stableStringifyToolArgs, symbolInnerMessage, toMediaWireUrl, toMessagePartStatus, trackToolArgsKeyOrder, updateStatusReducer };
|
package/dist/internal.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isJSONValue, isRecord } from "./utils/json/is-json.js";
|
|
2
|
+
import { notifyEventListeners } from "./utils/notify-event-listeners.js";
|
|
2
3
|
import { BaseSubject, BaseSubscribable, EventSubscriptionSubject, LazyMemoizeSubject, NestedSubscriptionSubject, SKIP_UPDATE, ShallowMemoizeSubject } from "./subscribable/subscribable.js";
|
|
3
4
|
import { generateErrorMessageId, generateId, isErrorMessageId } from "./utils/id.js";
|
|
4
5
|
import { fileMatchesAccept, getFileDataURL } from "./adapters/attachment.js";
|
|
@@ -42,4 +43,4 @@ import { ReadonlyThreadRuntimeCore } from "./runtimes/readonly/ReadonlyThreadRun
|
|
|
42
43
|
import { OptimisticState } from "./runtimes/remote-thread-list/optimistic-state.js";
|
|
43
44
|
import { EMPTY_THREAD_CORE } from "./runtimes/remote-thread-list/empty-thread-core.js";
|
|
44
45
|
import { createThreadMappingId, getThreadData, updateStatusReducer } from "./runtimes/remote-thread-list/remote-thread-state.js";
|
|
45
|
-
export { AssistantRuntimeImpl, AttachmentRuntimeImpl, BaseAssistantRuntimeCore, BaseComposerRuntimeCore, BaseSubject, BaseSubscribable, BaseThreadRuntimeCore, ComposerRuntimeImpl, CompositeContextProvider, DefaultEditComposerRuntimeCore, DefaultThreadComposerRuntimeCore, EMPTY_THREAD_CORE, EditComposerAttachmentRuntimeImpl, EditComposerRuntimeImpl, EventSubscriptionSubject, ExportedMessageRepository, ExternalStoreRuntimeCore, ExternalStoreThreadListRuntimeCore, ExternalStoreThreadRuntimeCore, LazyMemoizeSubject, LocalRuntimeCore, LocalThreadListRuntimeCore, LocalThreadRuntimeCore, MessageAttachmentRuntimeImpl, MessagePartRuntimeImpl, MessageRepository, MessageRuntimeImpl, NestedSubscriptionSubject, OptimisticState, ReadonlyThreadRuntimeCore, SKIP_UPDATE, ShallowMemoizeSubject, ThreadComposerAttachmentRuntimeImpl, ThreadComposerRuntimeImpl, ThreadListItemRuntimeImpl, ThreadListRuntimeImpl, ThreadMessageConverter, ThreadRuntimeImpl, ToolInvocationTracker, consumeSuggestionResult, createThreadMappingId, dataUrlMediaType, detectImageMediaType, fileMatchesAccept, fromThreadMessageLike, generateErrorMessageId, generateId, getAutoStatus, getFileDataURL, getThreadData, getThreadMessageText, getThreadState, hasUpcomingMessage, httpUrlPattern, isAutoStatus, isCreateAttachment, isErrorMessageId, isJSONValue, isParsableUrl, isRecord, parseDataUrl, resolveFileMediaType, resolveImageMediaType, resolveToolApprovalResponse, shouldContinue, stableStringifyToolArgs, symbolInnerMessage, toMediaWireUrl, toMessagePartStatus, trackToolArgsKeyOrder, updateStatusReducer };
|
|
46
|
+
export { AssistantRuntimeImpl, AttachmentRuntimeImpl, BaseAssistantRuntimeCore, BaseComposerRuntimeCore, BaseSubject, BaseSubscribable, BaseThreadRuntimeCore, ComposerRuntimeImpl, CompositeContextProvider, DefaultEditComposerRuntimeCore, DefaultThreadComposerRuntimeCore, EMPTY_THREAD_CORE, EditComposerAttachmentRuntimeImpl, EditComposerRuntimeImpl, EventSubscriptionSubject, ExportedMessageRepository, ExternalStoreRuntimeCore, ExternalStoreThreadListRuntimeCore, ExternalStoreThreadRuntimeCore, LazyMemoizeSubject, LocalRuntimeCore, LocalThreadListRuntimeCore, LocalThreadRuntimeCore, MessageAttachmentRuntimeImpl, MessagePartRuntimeImpl, MessageRepository, MessageRuntimeImpl, NestedSubscriptionSubject, OptimisticState, ReadonlyThreadRuntimeCore, SKIP_UPDATE, ShallowMemoizeSubject, ThreadComposerAttachmentRuntimeImpl, ThreadComposerRuntimeImpl, ThreadListItemRuntimeImpl, ThreadListRuntimeImpl, ThreadMessageConverter, ThreadRuntimeImpl, ToolInvocationTracker, consumeSuggestionResult, createThreadMappingId, dataUrlMediaType, detectImageMediaType, fileMatchesAccept, fromThreadMessageLike, generateErrorMessageId, generateId, getAutoStatus, getFileDataURL, getThreadData, getThreadMessageText, getThreadState, hasUpcomingMessage, httpUrlPattern, isAutoStatus, isCreateAttachment, isErrorMessageId, isJSONValue, isParsableUrl, isRecord, notifyEventListeners, parseDataUrl, resolveFileMediaType, resolveImageMediaType, resolveToolApprovalResponse, shouldContinue, stableStringifyToolArgs, symbolInnerMessage, toMediaWireUrl, toMessagePartStatus, trackToolArgsKeyOrder, updateStatusReducer };
|
|
@@ -5,7 +5,6 @@ declare class AssistantFrameHost implements ModelContextProvider {
|
|
|
5
5
|
private _context;
|
|
6
6
|
private _subscribers;
|
|
7
7
|
private _pendingRequests;
|
|
8
|
-
private _requestCounter;
|
|
9
8
|
private _iframeWindow;
|
|
10
9
|
private _targetOrigin;
|
|
11
10
|
private _disposed;
|
|
@@ -14,6 +13,7 @@ declare class AssistantFrameHost implements ModelContextProvider {
|
|
|
14
13
|
private updateContext;
|
|
15
14
|
private callTool;
|
|
16
15
|
private sendRequest;
|
|
16
|
+
private cancelToolCall;
|
|
17
17
|
private requestContext;
|
|
18
18
|
private notifySubscribers;
|
|
19
19
|
getModelContext(): ModelContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","names":[],"sources":["../../../src/model-context/frame/host.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"host.d.ts","names":[],"sources":["../../../src/model-context/frame/host.ts"],"mappings":";;;cAmDa,8BAA8B;UACjC;UACA;UACA;UAOA;UACA;UACA;EAEI,YAAA,cAAc,QAAQ;UAU1B;UA6BA;UAoBA;UAkBA;UAyDA;UAUA;UAYA;EAIR,mBAAmB;EAInB,UAAU,uBAAuB;EAKjC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { notifySubscribers } from "../../subscribable/subscribable.js";
|
|
2
|
+
import { generateId } from "../../utils/id.js";
|
|
2
3
|
import { FRAME_MESSAGE_CHANNEL } from "./types.js";
|
|
3
4
|
//#region src/model-context/frame/host.ts
|
|
4
5
|
/**
|
|
@@ -27,7 +28,6 @@ var AssistantFrameHost = class {
|
|
|
27
28
|
_context = {};
|
|
28
29
|
_subscribers = /* @__PURE__ */ new Set();
|
|
29
30
|
_pendingRequests = /* @__PURE__ */ new Map();
|
|
30
|
-
_requestCounter = 0;
|
|
31
31
|
_iframeWindow;
|
|
32
32
|
_targetOrigin;
|
|
33
33
|
_disposed = false;
|
|
@@ -72,7 +72,7 @@ var AssistantFrameHost = class {
|
|
|
72
72
|
callTool(toolName, args, abortSignal) {
|
|
73
73
|
return this.sendRequest({
|
|
74
74
|
type: "tool-call",
|
|
75
|
-
id: `tool-${
|
|
75
|
+
id: `tool-${generateId()}`,
|
|
76
76
|
toolName,
|
|
77
77
|
args
|
|
78
78
|
}, 3e4, `Tool call "${toolName}" timed out`, abortSignal);
|
|
@@ -86,6 +86,7 @@ var AssistantFrameHost = class {
|
|
|
86
86
|
if (!abortSignal) return;
|
|
87
87
|
const pending = this._pendingRequests.get(message.id);
|
|
88
88
|
if (pending) {
|
|
89
|
+
this.cancelToolCall(message.id);
|
|
89
90
|
pending.reject(getAbortReason(abortSignal));
|
|
90
91
|
this._pendingRequests.delete(message.id);
|
|
91
92
|
}
|
|
@@ -107,6 +108,7 @@ var AssistantFrameHost = class {
|
|
|
107
108
|
timeoutId = setTimeout(() => {
|
|
108
109
|
const pending = this._pendingRequests.get(message.id);
|
|
109
110
|
if (pending) {
|
|
111
|
+
this.cancelToolCall(message.id);
|
|
110
112
|
pending.reject(new Error(timeoutMessage));
|
|
111
113
|
this._pendingRequests.delete(message.id);
|
|
112
114
|
}
|
|
@@ -118,6 +120,15 @@ var AssistantFrameHost = class {
|
|
|
118
120
|
}, this._targetOrigin);
|
|
119
121
|
});
|
|
120
122
|
}
|
|
123
|
+
cancelToolCall(id) {
|
|
124
|
+
this._iframeWindow.postMessage({
|
|
125
|
+
channel: FRAME_MESSAGE_CHANNEL,
|
|
126
|
+
message: {
|
|
127
|
+
type: "tool-cancel",
|
|
128
|
+
id
|
|
129
|
+
}
|
|
130
|
+
}, this._targetOrigin);
|
|
131
|
+
}
|
|
121
132
|
requestContext() {
|
|
122
133
|
this._iframeWindow.postMessage({
|
|
123
134
|
channel: FRAME_MESSAGE_CHANNEL,
|
|
@@ -139,7 +150,10 @@ var AssistantFrameHost = class {
|
|
|
139
150
|
window.removeEventListener("message", this.handleMessage);
|
|
140
151
|
this._subscribers.clear();
|
|
141
152
|
const error = /* @__PURE__ */ new Error("AssistantFrameHost has been disposed");
|
|
142
|
-
for (const pending of this._pendingRequests
|
|
153
|
+
for (const [id, pending] of this._pendingRequests) {
|
|
154
|
+
this.cancelToolCall(id);
|
|
155
|
+
pending.reject(error);
|
|
156
|
+
}
|
|
143
157
|
this._pendingRequests.clear();
|
|
144
158
|
}
|
|
145
159
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","names":["ModelContextProvider","ModelContext","Unsubscribe","Tool","notifySubscribers","notifyStateSubscribers","FrameMessage","FRAME_MESSAGE_CHANNEL","SerializedModelContext","SerializedTool","deserializeTool","serializedTool","parameters","description","disabled","undefined","type","deserializeModelContext","serialized","system","tools","Object","fromEntries","entries","map","name","tool","getAbortReason","signal","AbortSignal","reason","error","Error","AssistantFrameHost","_context","_subscribers","Set","_pendingRequests","Map","resolve","value","reject","_requestCounter","_iframeWindow","Window","_targetOrigin","_disposed","constructor","iframeWindow","targetOrigin","handleMessage","bind","window","addEventListener","requestContext","event","MessageEvent","origin","source","data","channel","message","updateContext","context","pending","get","id","result","delete","serializedContext","execute","args","abortSignal","callTool","toolName","Promise","sendRequest","T","timeout","timeoutMessage","aborted","timeoutId","ReturnType","setTimeout","onAbort","cleanup","clearTimeout","removeEventListener","set","once","postMessage","getModelContext","subscribe","callback","add","dispose","clear","values"],"sources":["../../../src/model-context/frame/host.ts"],"sourcesContent":["import type { ModelContextProvider, ModelContext } from \"../types\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { Tool } from \"assistant-stream\";\nimport { notifySubscribers as notifyStateSubscribers } from \"../../subscribable/subscribable\";\nimport {\n type FrameMessage,\n FRAME_MESSAGE_CHANNEL,\n type SerializedModelContext,\n type SerializedTool,\n} from \"./types\";\n\n/**\n * Deserializes tools from JSON Schema format back to Tool objects\n */\nconst deserializeTool = (serializedTool: SerializedTool): Tool<any, any> =>\n ({\n parameters: serializedTool.parameters,\n ...(serializedTool.description && {\n description: serializedTool.description,\n }),\n ...(serializedTool.disabled !== undefined && {\n disabled: serializedTool.disabled,\n }),\n ...(serializedTool.type && { type: serializedTool.type }),\n }) as Tool<any, any>;\n\n/**\n * Deserializes a ModelContext from transmission format\n */\nconst deserializeModelContext = (\n serialized: SerializedModelContext,\n): ModelContext => ({\n ...(serialized.system !== undefined && { system: serialized.system }),\n ...(serialized.tools && {\n tools: Object.fromEntries(\n Object.entries(serialized.tools).map(([name, tool]) => [\n name,\n deserializeTool(tool),\n ]),\n ),\n }),\n});\n\nconst getAbortReason = (signal: AbortSignal): unknown => {\n if (signal.reason !== undefined) return signal.reason;\n const error = new Error(\"Tool call was aborted\");\n error.name = \"AbortError\";\n return error;\n};\n\nexport class AssistantFrameHost implements ModelContextProvider {\n private _context: ModelContext = {};\n private _subscribers = new Set<() => void>();\n private _pendingRequests = new Map<\n string,\n {\n resolve: (value: any) => void;\n reject: (error: any) => void;\n }\n >();\n private _requestCounter = 0;\n private _iframeWindow: Window;\n private _targetOrigin: string;\n private _disposed = false;\n\n constructor(iframeWindow: Window, targetOrigin: string = \"*\") {\n this._iframeWindow = iframeWindow;\n this._targetOrigin = targetOrigin;\n\n this.handleMessage = this.handleMessage.bind(this);\n window.addEventListener(\"message\", this.handleMessage);\n\n this.requestContext();\n }\n\n private handleMessage(event: MessageEvent) {\n if (this._targetOrigin !== \"*\" && event.origin !== this._targetOrigin)\n return;\n if (event.source !== this._iframeWindow) 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-update\": {\n this.updateContext(message.context);\n break;\n }\n\n case \"tool-result\": {\n const pending = this._pendingRequests.get(message.id);\n if (pending) {\n if (message.error) {\n pending.reject(new Error(message.error));\n } else {\n pending.resolve(message.result);\n }\n this._pendingRequests.delete(message.id);\n }\n break;\n }\n }\n }\n\n private updateContext(serializedContext: SerializedModelContext) {\n const context = deserializeModelContext(serializedContext);\n this._context = {\n ...context,\n tools:\n context.tools &&\n Object.fromEntries(\n Object.entries(context.tools).map(([name, tool]) => [\n name,\n {\n ...tool,\n execute: (args: any, context: { abortSignal: AbortSignal }) =>\n this.callTool(name, args, context.abortSignal),\n } as Tool<any, any>,\n ]),\n ),\n };\n this.notifySubscribers();\n }\n\n private callTool(\n toolName: string,\n args: any,\n abortSignal: AbortSignal,\n ): Promise<any> {\n return this.sendRequest(\n {\n type: \"tool-call\",\n id: `tool-${this._requestCounter++}`,\n toolName,\n args,\n },\n 30000,\n `Tool call \"${toolName}\" timed out`,\n abortSignal,\n );\n }\n\n private sendRequest<T extends FrameMessage & { id: string }>(\n message: T,\n timeout = 30000,\n timeoutMessage = \"Request timed out\",\n abortSignal?: AbortSignal,\n ): Promise<any> {\n if (this._disposed) {\n return Promise.reject(new Error(\"AssistantFrameHost has been disposed\"));\n }\n if (abortSignal?.aborted) {\n return Promise.reject(getAbortReason(abortSignal));\n }\n\n return new Promise((resolve, reject) => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const onAbort = () => {\n if (!abortSignal) return;\n const pending = this._pendingRequests.get(message.id);\n if (pending) {\n pending.reject(getAbortReason(abortSignal));\n this._pendingRequests.delete(message.id);\n }\n };\n const cleanup = () => {\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n abortSignal?.removeEventListener(\"abort\", onAbort);\n };\n\n this._pendingRequests.set(message.id, {\n resolve: (value: any) => {\n cleanup();\n resolve(value);\n },\n reject: (error: any) => {\n cleanup();\n reject(error);\n },\n });\n\n timeoutId = setTimeout(() => {\n const pending = this._pendingRequests.get(message.id);\n if (pending) {\n pending.reject(new Error(timeoutMessage));\n this._pendingRequests.delete(message.id);\n }\n }, timeout);\n abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n this._iframeWindow.postMessage(\n { channel: FRAME_MESSAGE_CHANNEL, message },\n this._targetOrigin,\n );\n });\n }\n\n private requestContext() {\n this._iframeWindow.postMessage(\n {\n channel: FRAME_MESSAGE_CHANNEL,\n message: {\n type: \"model-context-request\",\n } as FrameMessage,\n },\n this._targetOrigin,\n );\n }\n\n private notifySubscribers() {\n notifyStateSubscribers(this._subscribers);\n }\n\n getModelContext(): ModelContext {\n return this._context;\n }\n\n subscribe(callback: () => void): Unsubscribe {\n this._subscribers.add(callback);\n return () => this._subscribers.delete(callback);\n }\n\n dispose() {\n this._disposed = true;\n window.removeEventListener(\"message\", this.handleMessage);\n this._subscribers.clear();\n const error = new Error(\"AssistantFrameHost has been disposed\");\n for (const pending of this._pendingRequests.values()) {\n pending.reject(error);\n }\n this._pendingRequests.clear();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"host.js","names":["ModelContextProvider","ModelContext","Unsubscribe","Tool","notifySubscribers","notifyStateSubscribers","generateId","FrameMessage","FRAME_MESSAGE_CHANNEL","SerializedModelContext","SerializedTool","deserializeTool","serializedTool","parameters","description","disabled","undefined","type","deserializeModelContext","serialized","system","tools","Object","fromEntries","entries","map","name","tool","getAbortReason","signal","AbortSignal","reason","error","Error","AssistantFrameHost","_context","_subscribers","Set","_pendingRequests","Map","resolve","value","reject","_iframeWindow","Window","_targetOrigin","_disposed","constructor","iframeWindow","targetOrigin","handleMessage","bind","window","addEventListener","requestContext","event","MessageEvent","origin","source","data","channel","message","updateContext","context","pending","get","id","result","delete","serializedContext","execute","args","abortSignal","callTool","toolName","Promise","sendRequest","T","timeout","timeoutMessage","aborted","timeoutId","ReturnType","setTimeout","onAbort","cancelToolCall","cleanup","clearTimeout","removeEventListener","set","once","postMessage","getModelContext","subscribe","callback","add","dispose","clear"],"sources":["../../../src/model-context/frame/host.ts"],"sourcesContent":["import type { ModelContextProvider, ModelContext } from \"../types\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { Tool } from \"assistant-stream\";\nimport { notifySubscribers as notifyStateSubscribers } from \"../../subscribable/subscribable\";\nimport { generateId } from \"../../utils/id\";\nimport {\n type FrameMessage,\n FRAME_MESSAGE_CHANNEL,\n type SerializedModelContext,\n type SerializedTool,\n} from \"./types\";\n\n/**\n * Deserializes tools from JSON Schema format back to Tool objects\n */\nconst deserializeTool = (serializedTool: SerializedTool): Tool<any, any> =>\n ({\n parameters: serializedTool.parameters,\n ...(serializedTool.description && {\n description: serializedTool.description,\n }),\n ...(serializedTool.disabled !== undefined && {\n disabled: serializedTool.disabled,\n }),\n ...(serializedTool.type && { type: serializedTool.type }),\n }) as Tool<any, any>;\n\n/**\n * Deserializes a ModelContext from transmission format\n */\nconst deserializeModelContext = (\n serialized: SerializedModelContext,\n): ModelContext => ({\n ...(serialized.system !== undefined && { system: serialized.system }),\n ...(serialized.tools && {\n tools: Object.fromEntries(\n Object.entries(serialized.tools).map(([name, tool]) => [\n name,\n deserializeTool(tool),\n ]),\n ),\n }),\n});\n\nconst getAbortReason = (signal: AbortSignal): unknown => {\n if (signal.reason !== undefined) return signal.reason;\n const error = new Error(\"Tool call was aborted\");\n error.name = \"AbortError\";\n return error;\n};\n\nexport class AssistantFrameHost implements ModelContextProvider {\n private _context: ModelContext = {};\n private _subscribers = new Set<() => void>();\n private _pendingRequests = new Map<\n string,\n {\n resolve: (value: any) => void;\n reject: (error: any) => void;\n }\n >();\n private _iframeWindow: Window;\n private _targetOrigin: string;\n private _disposed = false;\n\n constructor(iframeWindow: Window, targetOrigin: string = \"*\") {\n this._iframeWindow = iframeWindow;\n this._targetOrigin = targetOrigin;\n\n this.handleMessage = this.handleMessage.bind(this);\n window.addEventListener(\"message\", this.handleMessage);\n\n this.requestContext();\n }\n\n private handleMessage(event: MessageEvent) {\n if (this._targetOrigin !== \"*\" && event.origin !== this._targetOrigin)\n return;\n if (event.source !== this._iframeWindow) 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-update\": {\n this.updateContext(message.context);\n break;\n }\n\n case \"tool-result\": {\n const pending = this._pendingRequests.get(message.id);\n if (pending) {\n if (message.error) {\n pending.reject(new Error(message.error));\n } else {\n pending.resolve(message.result);\n }\n this._pendingRequests.delete(message.id);\n }\n break;\n }\n }\n }\n\n private updateContext(serializedContext: SerializedModelContext) {\n const context = deserializeModelContext(serializedContext);\n this._context = {\n ...context,\n tools:\n context.tools &&\n Object.fromEntries(\n Object.entries(context.tools).map(([name, tool]) => [\n name,\n {\n ...tool,\n execute: (args: any, context: { abortSignal: AbortSignal }) =>\n this.callTool(name, args, context.abortSignal),\n } as Tool<any, any>,\n ]),\n ),\n };\n this.notifySubscribers();\n }\n\n private callTool(\n toolName: string,\n args: any,\n abortSignal: AbortSignal,\n ): Promise<any> {\n return this.sendRequest(\n {\n type: \"tool-call\",\n id: `tool-${generateId()}`,\n toolName,\n args,\n },\n 30000,\n `Tool call \"${toolName}\" timed out`,\n abortSignal,\n );\n }\n\n private sendRequest<T extends FrameMessage & { id: string }>(\n message: T,\n timeout = 30000,\n timeoutMessage = \"Request timed out\",\n abortSignal?: AbortSignal,\n ): Promise<any> {\n if (this._disposed) {\n return Promise.reject(new Error(\"AssistantFrameHost has been disposed\"));\n }\n if (abortSignal?.aborted) {\n return Promise.reject(getAbortReason(abortSignal));\n }\n\n return new Promise((resolve, reject) => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const onAbort = () => {\n if (!abortSignal) return;\n const pending = this._pendingRequests.get(message.id);\n if (pending) {\n this.cancelToolCall(message.id);\n pending.reject(getAbortReason(abortSignal));\n this._pendingRequests.delete(message.id);\n }\n };\n const cleanup = () => {\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n abortSignal?.removeEventListener(\"abort\", onAbort);\n };\n\n this._pendingRequests.set(message.id, {\n resolve: (value: any) => {\n cleanup();\n resolve(value);\n },\n reject: (error: any) => {\n cleanup();\n reject(error);\n },\n });\n\n timeoutId = setTimeout(() => {\n const pending = this._pendingRequests.get(message.id);\n if (pending) {\n this.cancelToolCall(message.id);\n pending.reject(new Error(timeoutMessage));\n this._pendingRequests.delete(message.id);\n }\n }, timeout);\n abortSignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n this._iframeWindow.postMessage(\n { channel: FRAME_MESSAGE_CHANNEL, message },\n this._targetOrigin,\n );\n });\n }\n\n private cancelToolCall(id: string) {\n this._iframeWindow.postMessage(\n {\n channel: FRAME_MESSAGE_CHANNEL,\n message: { type: \"tool-cancel\", id } satisfies FrameMessage,\n },\n this._targetOrigin,\n );\n }\n\n private requestContext() {\n this._iframeWindow.postMessage(\n {\n channel: FRAME_MESSAGE_CHANNEL,\n message: {\n type: \"model-context-request\",\n } as FrameMessage,\n },\n this._targetOrigin,\n );\n }\n\n private notifySubscribers() {\n notifyStateSubscribers(this._subscribers);\n }\n\n getModelContext(): ModelContext {\n return this._context;\n }\n\n subscribe(callback: () => void): Unsubscribe {\n this._subscribers.add(callback);\n return () => this._subscribers.delete(callback);\n }\n\n dispose() {\n this._disposed = true;\n window.removeEventListener(\"message\", this.handleMessage);\n this._subscribers.clear();\n const error = new Error(\"AssistantFrameHost has been disposed\");\n for (const [id, pending] of this._pendingRequests) {\n this.cancelToolCall(id);\n pending.reject(error);\n }\n this._pendingRequests.clear();\n }\n}\n"],"mappings":"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"}
|
|
@@ -5,11 +5,15 @@ declare class AssistantFrameProvider {
|
|
|
5
5
|
private static _instance;
|
|
6
6
|
private _providers;
|
|
7
7
|
private _providerUnsubscribes;
|
|
8
|
+
private _activeToolCalls;
|
|
8
9
|
private _targetOrigin;
|
|
10
|
+
private _strictRegistrations;
|
|
9
11
|
private constructor();
|
|
10
12
|
private static getInstance;
|
|
13
|
+
private reconcileTargetOrigin;
|
|
11
14
|
private handleMessage;
|
|
12
15
|
private handleToolCall;
|
|
16
|
+
private cancelToolCall;
|
|
13
17
|
private sendMessage;
|
|
14
18
|
private getModelContext;
|
|
15
19
|
private broadcastUpdate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","names":[],"sources":["../../../src/model-context/frame/provider.ts"],"mappings":";;;cA+Ba;iBACI;UAEP;UACA;UAIA;UAED;iBAQQ;
|
|
1
|
+
{"version":3,"file":"provider.d.ts","names":[],"sources":["../../../src/model-context/frame/provider.ts"],"mappings":";;;cA+Ba;iBACI;UAEP;UACA;UAIA;UAIA;UACA;UAED;iBAQQ;UAWP;UAaA;UA0BM;UA2CN;UAOA;UAOA;UAkBA;SAcD,wBACL,UAAU,sBACV,wBACC;SA4BI"}
|
|
@@ -15,7 +15,9 @@ var AssistantFrameProvider = class AssistantFrameProvider {
|
|
|
15
15
|
static _instance = null;
|
|
16
16
|
_providers = /* @__PURE__ */ new Set();
|
|
17
17
|
_providerUnsubscribes = /* @__PURE__ */ new Map();
|
|
18
|
+
_activeToolCalls = /* @__PURE__ */ new Map();
|
|
18
19
|
_targetOrigin;
|
|
20
|
+
_strictRegistrations = 0;
|
|
19
21
|
constructor(targetOrigin = "*") {
|
|
20
22
|
this._targetOrigin = targetOrigin;
|
|
21
23
|
this.handleMessage = this.handleMessage.bind(this);
|
|
@@ -24,8 +26,17 @@ var AssistantFrameProvider = class AssistantFrameProvider {
|
|
|
24
26
|
}
|
|
25
27
|
static getInstance(targetOrigin) {
|
|
26
28
|
if (!AssistantFrameProvider._instance) AssistantFrameProvider._instance = new AssistantFrameProvider(targetOrigin);
|
|
29
|
+
else AssistantFrameProvider._instance.reconcileTargetOrigin(targetOrigin);
|
|
27
30
|
return AssistantFrameProvider._instance;
|
|
28
31
|
}
|
|
32
|
+
reconcileTargetOrigin(targetOrigin = "*") {
|
|
33
|
+
if (targetOrigin === "*" || targetOrigin === this._targetOrigin) return;
|
|
34
|
+
if (this._targetOrigin === "*") {
|
|
35
|
+
this._targetOrigin = targetOrigin;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
throw new Error(`AssistantFrameProvider cannot register conflicting target origins: "${this._targetOrigin}" and "${targetOrigin}"`);
|
|
39
|
+
}
|
|
29
40
|
handleMessage(event) {
|
|
30
41
|
if (this._targetOrigin !== "*" && event.origin !== this._targetOrigin) return;
|
|
31
42
|
if (event.source !== window.parent) return;
|
|
@@ -38,18 +49,28 @@ var AssistantFrameProvider = class AssistantFrameProvider {
|
|
|
38
49
|
context: serializeModelContext(this.getModelContext())
|
|
39
50
|
});
|
|
40
51
|
break;
|
|
41
|
-
case "tool-call":
|
|
52
|
+
case "tool-call":
|
|
53
|
+
this.handleToolCall(message, event);
|
|
54
|
+
break;
|
|
55
|
+
case "tool-cancel": this.cancelToolCall(message.id);
|
|
42
56
|
}
|
|
43
57
|
}
|
|
44
58
|
async handleToolCall(message, event) {
|
|
45
59
|
const tool = this.getModelContext().tools?.[message.toolName];
|
|
60
|
+
const abortController = new AbortController();
|
|
61
|
+
this._activeToolCalls.get(message.id)?.abortController.abort();
|
|
62
|
+
const activeCall = {
|
|
63
|
+
abortController,
|
|
64
|
+
event
|
|
65
|
+
};
|
|
66
|
+
this._activeToolCalls.set(message.id, activeCall);
|
|
46
67
|
let result;
|
|
47
68
|
let error;
|
|
48
69
|
if (!tool) error = `Tool "${message.toolName}" not found`;
|
|
49
70
|
else try {
|
|
50
71
|
result = tool.execute ? await tool.execute(message.args, {
|
|
51
72
|
toolCallId: message.id,
|
|
52
|
-
abortSignal:
|
|
73
|
+
abortSignal: abortController.signal,
|
|
53
74
|
human: async () => {
|
|
54
75
|
throw new Error("Tool human input is not supported in frame context");
|
|
55
76
|
}
|
|
@@ -57,12 +78,20 @@ var AssistantFrameProvider = class AssistantFrameProvider {
|
|
|
57
78
|
} catch (e) {
|
|
58
79
|
error = e instanceof Error ? e.message : String(e);
|
|
59
80
|
}
|
|
81
|
+
if (this._activeToolCalls.get(message.id) !== activeCall) return;
|
|
82
|
+
this._activeToolCalls.delete(message.id);
|
|
60
83
|
this.sendMessage(event, {
|
|
61
84
|
type: "tool-result",
|
|
62
85
|
id: message.id,
|
|
63
86
|
...error ? { error } : { result }
|
|
64
87
|
});
|
|
65
88
|
}
|
|
89
|
+
cancelToolCall(id) {
|
|
90
|
+
const activeCall = this._activeToolCalls.get(id);
|
|
91
|
+
if (!activeCall) return;
|
|
92
|
+
this._activeToolCalls.delete(id);
|
|
93
|
+
activeCall.abortController.abort();
|
|
94
|
+
}
|
|
66
95
|
sendMessage(event, message) {
|
|
67
96
|
event.source?.postMessage({
|
|
68
97
|
channel: FRAME_MESSAGE_CHANNEL,
|
|
@@ -91,15 +120,24 @@ var AssistantFrameProvider = class AssistantFrameProvider {
|
|
|
91
120
|
}
|
|
92
121
|
}
|
|
93
122
|
static addModelContextProvider(provider, targetOrigin) {
|
|
94
|
-
const
|
|
123
|
+
const origin = targetOrigin ?? "*";
|
|
124
|
+
const instance = AssistantFrameProvider.getInstance(origin);
|
|
95
125
|
instance._providers.add(provider);
|
|
126
|
+
if (origin !== "*") instance._strictRegistrations += 1;
|
|
96
127
|
const unsubscribe = provider.subscribe?.(() => instance.broadcastUpdate());
|
|
97
128
|
if (unsubscribe) instance._providerUnsubscribes.set(provider, unsubscribe);
|
|
98
129
|
instance.broadcastUpdate();
|
|
130
|
+
let released = false;
|
|
99
131
|
return () => {
|
|
132
|
+
if (released) return;
|
|
133
|
+
released = true;
|
|
100
134
|
instance._providers.delete(provider);
|
|
101
135
|
instance._providerUnsubscribes.get(provider)?.();
|
|
102
136
|
instance._providerUnsubscribes.delete(provider);
|
|
137
|
+
if (origin !== "*") {
|
|
138
|
+
instance._strictRegistrations -= 1;
|
|
139
|
+
if (instance._strictRegistrations === 0) instance._targetOrigin = "*";
|
|
140
|
+
}
|
|
103
141
|
instance.broadcastUpdate();
|
|
104
142
|
};
|
|
105
143
|
}
|
|
@@ -110,6 +148,15 @@ var AssistantFrameProvider = class AssistantFrameProvider {
|
|
|
110
148
|
instance._providerUnsubscribes.forEach((unsubscribe) => unsubscribe?.());
|
|
111
149
|
instance._providerUnsubscribes.clear();
|
|
112
150
|
instance._providers.clear();
|
|
151
|
+
instance._activeToolCalls.forEach(({ abortController, event }, id) => {
|
|
152
|
+
abortController.abort();
|
|
153
|
+
instance.sendMessage(event, {
|
|
154
|
+
type: "tool-result",
|
|
155
|
+
id,
|
|
156
|
+
error: "AssistantFrameProvider has been disposed"
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
instance._activeToolCalls.clear();
|
|
113
160
|
AssistantFrameProvider._instance = null;
|
|
114
161
|
}
|
|
115
162
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","names":["ModelContextProvider","ModelContext","Unsubscribe","Tool","toJSONSchema","FrameMessage","FRAME_MESSAGE_CHANNEL","SerializedModelContext","SerializedTool","serializeTool","tool","description","parameters","undefined","disabled","type","serializeModelContext","context","system","tools","Object","fromEntries","entries","map","name","AssistantFrameProvider","_instance","_providers","Set","_providerUnsubscribes","Map","_targetOrigin","constructor","targetOrigin","handleMessage","bind","window","addEventListener","setTimeout","broadcastUpdate","getInstance","event","MessageEvent","origin","source","parent","data","channel","message","sendMessage","getModelContext","handleToolCall","Extract","toolName","result","error","execute","args","toolCallId","id","abortSignal","AbortController","signal","human","Error","e","String","postMessage","contexts","Array","from","p","reduce","merged","updateMessage","addModelContextProvider","provider","instance","add","unsubscribe","subscribe","set","delete","get","dispose","removeEventListener","forEach","clear"],"sources":["../../../src/model-context/frame/provider.ts"],"sourcesContent":["import type { ModelContextProvider, ModelContext } from \"../types\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport { type Tool, toJSONSchema } from \"assistant-stream\";\nimport {\n type FrameMessage,\n FRAME_MESSAGE_CHANNEL,\n type SerializedModelContext,\n type SerializedTool,\n} from \"./types\";\n\nconst serializeTool = (tool: Tool<any, any>): SerializedTool => ({\n ...(tool.description && { description: tool.description }),\n parameters: tool.parameters ? toJSONSchema(tool.parameters) : undefined,\n ...(tool.disabled !== undefined && { disabled: tool.disabled }),\n ...(tool.type && { type: tool.type }),\n});\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\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 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 if (this._targetOrigin !== \"*\" && event.origin !== this._targetOrigin)\n return;\n if (event.source !== window.parent) 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 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 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 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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"}
|
|
1
|
+
{"version":3,"file":"provider.js","names":["ModelContextProvider","ModelContext","Unsubscribe","Tool","toJSONSchema","FrameMessage","FRAME_MESSAGE_CHANNEL","SerializedModelContext","SerializedTool","serializeTool","tool","description","parameters","undefined","disabled","type","serializeModelContext","context","system","tools","Object","fromEntries","entries","map","name","AssistantFrameProvider","_instance","_providers","Set","_providerUnsubscribes","Map","_activeToolCalls","abortController","AbortController","event","MessageEvent","_targetOrigin","_strictRegistrations","constructor","targetOrigin","handleMessage","bind","window","addEventListener","setTimeout","broadcastUpdate","getInstance","reconcileTargetOrigin","Error","origin","source","parent","data","channel","message","sendMessage","getModelContext","handleToolCall","cancelToolCall","id","Extract","toolName","get","abort","activeCall","set","result","error","execute","args","toolCallId","abortSignal","signal","human","e","String","delete","postMessage","contexts","Array","from","p","reduce","merged","updateMessage","addModelContextProvider","provider","instance","add","unsubscribe","subscribe","released","dispose","removeEventListener","forEach","clear"],"sources":["../../../src/model-context/frame/provider.ts"],"sourcesContent":["import type { ModelContextProvider, ModelContext } from \"../types\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport { type Tool, toJSONSchema } from \"assistant-stream\";\nimport {\n type FrameMessage,\n FRAME_MESSAGE_CHANNEL,\n type SerializedModelContext,\n type SerializedTool,\n} from \"./types\";\n\nconst serializeTool = (tool: Tool<any, any>): SerializedTool => ({\n ...(tool.description && { description: tool.description }),\n parameters: tool.parameters ? toJSONSchema(tool.parameters) : undefined,\n ...(tool.disabled !== undefined && { disabled: tool.disabled }),\n ...(tool.type && { type: tool.type }),\n});\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\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 _activeToolCalls = new Map<\n string,\n { abortController: AbortController; event: MessageEvent }\n >();\n private _targetOrigin: string;\n private _strictRegistrations = 0;\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 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 } else {\n AssistantFrameProvider._instance.reconcileTargetOrigin(targetOrigin);\n }\n return AssistantFrameProvider._instance;\n }\n\n private reconcileTargetOrigin(targetOrigin: string = \"*\") {\n if (targetOrigin === \"*\" || targetOrigin === this._targetOrigin) return;\n\n if (this._targetOrigin === \"*\") {\n this._targetOrigin = targetOrigin;\n return;\n }\n\n throw new Error(\n `AssistantFrameProvider cannot register conflicting target origins: \"${this._targetOrigin}\" and \"${targetOrigin}\"`,\n );\n }\n\n private handleMessage(event: MessageEvent) {\n if (this._targetOrigin !== \"*\" && event.origin !== this._targetOrigin)\n return;\n if (event.source !== window.parent) 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 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 case \"tool-cancel\":\n this.cancelToolCall(message.id);\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 const abortController = new AbortController();\n this._activeToolCalls.get(message.id)?.abortController.abort();\n const activeCall = { abortController, event };\n this._activeToolCalls.set(message.id, activeCall);\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: 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 if (this._activeToolCalls.get(message.id) !== activeCall) return;\n this._activeToolCalls.delete(message.id);\n\n this.sendMessage(event, {\n type: \"tool-result\",\n id: message.id,\n ...(error ? { error } : { result }),\n });\n }\n\n private cancelToolCall(id: string) {\n const activeCall = this._activeToolCalls.get(id);\n if (!activeCall) return;\n this._activeToolCalls.delete(id);\n activeCall.abortController.abort();\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 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 origin = targetOrigin ?? \"*\";\n const instance = AssistantFrameProvider.getInstance(origin);\n instance._providers.add(provider);\n if (origin !== \"*\") instance._strictRegistrations += 1;\n\n const unsubscribe = provider.subscribe?.(() => instance.broadcastUpdate());\n if (unsubscribe) {\n instance._providerUnsubscribes.set(provider, unsubscribe);\n }\n\n instance.broadcastUpdate();\n\n let released = false;\n return () => {\n if (released) return;\n released = true;\n instance._providers.delete(provider);\n instance._providerUnsubscribes.get(provider)?.();\n instance._providerUnsubscribes.delete(provider);\n if (origin !== \"*\") {\n instance._strictRegistrations -= 1;\n if (instance._strictRegistrations === 0) instance._targetOrigin = \"*\";\n }\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 instance._providerUnsubscribes.forEach((unsubscribe) => unsubscribe?.());\n instance._providerUnsubscribes.clear();\n instance._providers.clear();\n instance._activeToolCalls.forEach(({ abortController, event }, id) => {\n abortController.abort();\n instance.sendMessage(event, {\n type: \"tool-result\",\n id,\n error: \"AssistantFrameProvider has been disposed\",\n });\n });\n instance._activeToolCalls.clear();\n\n AssistantFrameProvider._instance = null;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ type SerializedModelContext = {
|
|
|
9
9
|
system?: string;
|
|
10
10
|
tools?: Record<string, SerializedTool>;
|
|
11
11
|
};
|
|
12
|
-
type FrameMessageType = "model-context-request" | "model-context-update" | "tool-call" | "tool-result";
|
|
12
|
+
type FrameMessageType = "model-context-request" | "model-context-update" | "tool-call" | "tool-cancel" | "tool-result";
|
|
13
13
|
type FrameMessage = {
|
|
14
14
|
type: "model-context-request";
|
|
15
15
|
} | {
|
|
@@ -20,6 +20,9 @@ type FrameMessage = {
|
|
|
20
20
|
id: string;
|
|
21
21
|
toolName: string;
|
|
22
22
|
args: unknown;
|
|
23
|
+
} | {
|
|
24
|
+
type: "tool-cancel";
|
|
25
|
+
id: string;
|
|
23
26
|
} | {
|
|
24
27
|
type: "tool-result";
|
|
25
28
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/model-context/frame/types.ts"],"mappings":";KAAY;EACV;EACA;EACA;EACA;;KAGU;EACV;EACA,QAAQ,eAAe;;KAGb;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/model-context/frame/types.ts"],"mappings":";KAAY;EACV;EACA;EACA;EACA;;KAGU;EACV;EACA,QAAQ,eAAe;;KAGb;KAOA;EAEN;;EAGA;EACA,SAAS;;EAGT;EACA;EACA;EACA;;EAGA;EACA;;EAGA;EACA;EACA;EACA;;cAGO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":["SerializedTool","description","parameters","disabled","type","SerializedModelContext","system","tools","Record","FrameMessageType","FrameMessage","context","id","toolName","args","result","error","FRAME_MESSAGE_CHANNEL"],"sources":["../../../src/model-context/frame/types.ts"],"sourcesContent":["export type SerializedTool = {\n description?: string;\n parameters: any; // JSON Schema\n disabled?: boolean;\n type?: string;\n};\n\nexport type SerializedModelContext = {\n system?: string;\n tools?: Record<string, SerializedTool>;\n};\n\nexport type FrameMessageType =\n | \"model-context-request\"\n | \"model-context-update\"\n | \"tool-call\"\n | \"tool-result\";\n\nexport type FrameMessage =\n | {\n type: \"model-context-request\";\n }\n | {\n type: \"model-context-update\";\n context: SerializedModelContext;\n }\n | {\n type: \"tool-call\";\n id: string;\n toolName: string;\n args: unknown;\n }\n | {\n type: \"tool-result\";\n id: string;\n result?: unknown;\n error?: string;\n };\n\nexport const FRAME_MESSAGE_CHANNEL = \"assistant-ui-frame\";\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.js","names":["SerializedTool","description","parameters","disabled","type","SerializedModelContext","system","tools","Record","FrameMessageType","FrameMessage","context","id","toolName","args","result","error","FRAME_MESSAGE_CHANNEL"],"sources":["../../../src/model-context/frame/types.ts"],"sourcesContent":["export type SerializedTool = {\n description?: string;\n parameters: any; // JSON Schema\n disabled?: boolean;\n type?: string;\n};\n\nexport type SerializedModelContext = {\n system?: string;\n tools?: Record<string, SerializedTool>;\n};\n\nexport type FrameMessageType =\n | \"model-context-request\"\n | \"model-context-update\"\n | \"tool-call\"\n | \"tool-cancel\"\n | \"tool-result\";\n\nexport type FrameMessage =\n | {\n type: \"model-context-request\";\n }\n | {\n type: \"model-context-update\";\n context: SerializedModelContext;\n }\n | {\n type: \"tool-call\";\n id: string;\n toolName: string;\n args: unknown;\n }\n | {\n type: \"tool-cancel\";\n id: string;\n }\n | {\n type: \"tool-result\";\n id: string;\n result?: unknown;\n error?: string;\n };\n\nexport const FRAME_MESSAGE_CHANNEL = \"assistant-ui-frame\";\n"],"mappings":";AA4CA,MAAaiB,wBAAwB"}
|
|
@@ -4,7 +4,7 @@ import { ClientOutput } from "@assistant-ui/store";
|
|
|
4
4
|
//#region src/react/client/RemoteThreadList.d.ts
|
|
5
5
|
type RemoteThreadListProps = {
|
|
6
6
|
/**
|
|
7
|
-
* Swapping this to a different backing store does not reload the list. Call `reload()` after a genuine swap. A recreated object for the same store is a no-op.
|
|
7
|
+
* Swapping this to a different backing store does not reload the list. Call `reload()` after a genuine swap. A recreated object for the same store is a no-op. `reload()` after a different adapter instance resets selection and cached records before loading.
|
|
8
8
|
*/
|
|
9
9
|
adapter: RemoteThreadListAdapter;
|
|
10
10
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteThreadList.d.ts","names":[],"sources":["../../../src/react/client/RemoteThreadList.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"RemoteThreadList.d.ts","names":[],"sources":["../../../src/react/client/RemoteThreadList.ts"],"mappings":";;;;KAqDY;;;;EAIV,SAAS;;;;;;;EAOT,QAAQ;EACR;EACA,qBAAqB;EACrB,qBAAqB;EACrB;EACA,aAAa;;;;;;;;;;cAwiCF,8CAAgB,SAAA,0BAAA,OAAA"}
|