@assistant-ui/core 0.2.5 → 0.2.7
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/index.d.ts +4 -2
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/duplicate-detection.d.ts +5 -0
- package/dist/internal/duplicate-detection.d.ts.map +1 -0
- package/dist/internal/duplicate-detection.js +11 -0
- package/dist/internal/duplicate-detection.js.map +1 -0
- package/dist/react/AssistantProvider.d.ts.map +1 -1
- package/dist/react/AssistantProvider.js.map +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +2 -2
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.d.ts +25 -21
- package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js +6 -7
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts +2 -1
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +9 -4
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
- package/dist/react/providers/TextMessagePartProvider.js +3 -0
- package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +3 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +7 -3
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/types/MessagePartComponentTypes.d.ts +8 -0
- package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
- package/dist/react/utils/groupParts.d.ts +40 -12
- package/dist/react/utils/groupParts.d.ts.map +1 -1
- package/dist/react/utils/groupParts.js +51 -9
- package/dist/react/utils/groupParts.js.map +1 -1
- package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
- package/dist/runtime/api/attachment-runtime.js.map +1 -1
- package/dist/runtime/api/message-part-runtime.d.ts +8 -0
- package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-part-runtime.js +13 -0
- package/dist/runtime/api/message-part-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +2 -1
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +15 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +10 -0
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtimes/external-store/external-store-adapter.d.ts +33 -1
- package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +27 -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 +98 -3
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +2 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +3 -0
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
- package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +168 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +449 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -0
- package/dist/store/clients/thread-message-client.d.ts.map +1 -1
- package/dist/store/clients/thread-message-client.js +3 -0
- package/dist/store/clients/thread-message-client.js.map +1 -1
- package/dist/store/runtime-clients/message-part-runtime-client.js +1 -0
- package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
- package/dist/store/scopes/part.d.ts +7 -0
- package/dist/store/scopes/part.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/message.d.ts +6 -0
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js.map +1 -1
- package/package.json +4 -4
- package/src/adapters/index.ts +1 -4
- package/src/index.ts +11 -0
- package/src/internal/duplicate-detection.ts +26 -0
- package/src/react/AssistantProvider.tsx +2 -3
- package/src/react/index.ts +2 -6
- package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -2
- package/src/react/primitives/message/MessageAttachments.test.tsx +1 -1
- package/src/react/primitives/message/MessageGroupedParts.tsx +38 -31
- package/src/react/primitives/message/MessageParts.tsx +14 -1
- package/src/react/providers/TextMessagePartProvider.tsx +3 -0
- package/src/react/runtimes/external-message-converter.ts +26 -13
- package/src/react/types/MessagePartComponentTypes.ts +8 -0
- package/src/react/utils/groupParts.ts +67 -22
- package/src/runtime/api/attachment-runtime.ts +1 -2
- package/src/runtime/api/message-part-runtime.ts +26 -0
- package/src/runtime/base/base-thread-runtime-core.ts +4 -0
- package/src/runtime/interfaces/thread-runtime-core.ts +15 -0
- package/src/runtime/internal.ts +1 -4
- package/src/runtime/utils/thread-message-like.ts +7 -0
- package/src/runtimes/external-store/external-store-adapter.ts +37 -0
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +1 -3
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +168 -4
- package/src/runtimes/local/local-thread-runtime-core.ts +5 -0
- package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
- package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
- package/src/runtimes/tool-invocations/EDGE_CASES.md +194 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +1054 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +783 -0
- package/src/store/clients/thread-message-client.ts +3 -0
- package/src/store/runtime-clients/message-part-runtime-client.ts +2 -0
- package/src/store/scopes/part.ts +4 -0
- package/src/subscribable/subscribable.ts +3 -3
- package/src/tests/OptimisticState-delete-crash.test.ts +2 -0
- package/src/tests/OptimisticState-list-race.test.ts +2 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +5 -5
- package/src/tests/auiV0Encode.test.ts +1 -1
- package/src/tests/composer-can-send.test.ts +8 -4
- package/src/tests/duplicate-detection.test.ts +34 -0
- package/src/tests/external-store-thread-list-runtime-core.test.ts +1 -1
- package/src/tests/external-store-thread-runtime-core.test.ts +7 -6
- package/src/tests/groupParts.test.ts +118 -32
- package/src/tests/no-unsafe-process-env.test.ts +1 -0
- package/src/tests/remote-thread-list-isLoading.test.ts +2 -0
- package/src/tests/thread-message-like.test.ts +4 -1
- package/src/types/index.ts +1 -4
- package/src/types/message.ts +7 -0
- package/dist/react/runtimes/useToolInvocations.d.ts +0 -53
- package/dist/react/runtimes/useToolInvocations.d.ts.map +0 -1
- package/dist/react/runtimes/useToolInvocations.js +0 -380
- package/dist/react/runtimes/useToolInvocations.js.map +0 -1
- package/src/react/runtimes/useToolInvocations.ts +0 -694
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscribable.js","names":[],"sources":["../../src/subscribable/subscribable.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\n\nexport const SKIP_UPDATE = Symbol(\"skip-update\");\nexport type SKIP_UPDATE = typeof SKIP_UPDATE;\n\nexport type Subscribable = {\n subscribe: (callback: () => void) => Unsubscribe;\n};\n\nexport type SubscribableWithState<TState, TPath> = Subscribable & {\n path: TPath;\n getState: () => TState;\n};\n\nexport type NestedSubscribable<\n TState extends Subscribable | undefined,\n TPath,\n> = SubscribableWithState<TState, TPath>;\n\nexport type EventSubscribable<TEvent extends string> = {\n event: TEvent;\n binding: SubscribableWithState<\n | {\n unstable_on: (\n event: TEvent,\n callback: (payload?: unknown) => void,\n ) => Unsubscribe;\n }\n | undefined,\n unknown\n >;\n};\n\nfunction shallowEqual<T extends object>(\n objA: T | undefined,\n objB: T | undefined,\n) {\n if (objA === undefined && objB === undefined) return true;\n if (objA === undefined) return false;\n if (objB === undefined) return false;\n\n for (const key of Object.keys(objA)) {\n const valueA = objA[key as keyof T];\n const valueB = objB[key as keyof T];\n if (!Object.is(valueA, valueB)) return false;\n }\n\n return true;\n}\n\nexport class BaseSubscribable {\n private _subscribers = new Set<() => void>();\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscribers.add(callback);\n return () => this._subscribers.delete(callback);\n }\n\n public waitForUpdate() {\n return new Promise<void>((resolve) => {\n const unsubscribe = this.subscribe(() => {\n unsubscribe();\n resolve();\n });\n });\n }\n\n protected _notifySubscribers() {\n const errors = [];\n for (const callback of this._subscribers) {\n try {\n callback();\n } catch (error) {\n errors.push(error);\n }\n }\n\n if (errors.length > 0) {\n if (errors.length === 1) {\n throw errors[0];\n } else {\n for (const error of errors) {\n console.error(error);\n }\n throw new AggregateError(errors);\n }\n }\n }\n}\n\n// lazy connect/disconnect: only opens upstream subscription while it has subscribers\nexport abstract class BaseSubject {\n private _subscriptions = new Set<(payload?: unknown) => void>();\n private _connection: Unsubscribe | undefined;\n\n protected get isConnected() {\n return !!this._connection;\n }\n\n protected abstract _connect(): Unsubscribe;\n\n protected notifySubscribers(payload?: unknown) {\n for (const callback of this._subscriptions) callback(payload);\n }\n\n private _updateConnection() {\n if (this._subscriptions.size > 0) {\n if (this._connection) return;\n this._connection = this._connect();\n } else {\n this._connection?.();\n this._connection = undefined;\n }\n }\n\n public subscribe(callback: (payload?: unknown) => void) {\n this._subscriptions.add(callback);\n this._updateConnection();\n\n return () => {\n this._subscriptions.delete(callback);\n this._updateConnection();\n };\n }\n}\n\nexport class ShallowMemoizeSubject<TState extends object, TPath>\n extends BaseSubject\n implements SubscribableWithState<TState, TPath>\n{\n public get path() {\n return this.binding.path;\n }\n\n constructor(\n private binding: SubscribableWithState<TState | SKIP_UPDATE, TPath>,\n ) {\n super();\n const state = binding.getState();\n if (state === SKIP_UPDATE)\n throw new Error(\"Entry not available in the store\");\n this._previousState = state;\n }\n\n private _previousState: TState;\n public getState = () => {\n if (!this.isConnected) this._syncState();\n return this._previousState;\n };\n\n private _syncState() {\n const state = this.binding.getState();\n if (state === SKIP_UPDATE) return false;\n if (shallowEqual(state, this._previousState)) return false;\n this._previousState = state;\n return true;\n }\n\n protected _connect() {\n const callback = () => {\n if (this._syncState()) {\n this.notifySubscribers();\n }\n };\n\n return this.binding.subscribe(callback);\n }\n}\n\nexport class LazyMemoizeSubject<TState extends object, TPath>\n extends BaseSubject\n implements SubscribableWithState<TState, TPath>\n{\n public get path() {\n return this.binding.path;\n }\n\n constructor(\n private binding: SubscribableWithState<TState | SKIP_UPDATE, TPath>,\n ) {\n super();\n }\n\n private _previousStateDirty = true;\n private _previousState: TState | undefined;\n public getState = () => {\n if (!this.isConnected || this._previousStateDirty) {\n const newState = this.binding.getState();\n if (newState !== SKIP_UPDATE) {\n this._previousState = newState;\n }\n this._previousStateDirty = false;\n }\n if (this._previousState === undefined)\n throw new Error(\"Entry not available in the store\");\n return this._previousState;\n };\n\n protected _connect() {\n const callback = () => {\n this._previousStateDirty = true;\n this.notifySubscribers();\n };\n\n return this.binding.subscribe(callback);\n }\n}\n\nexport class NestedSubscriptionSubject<\n TState extends Subscribable | undefined,\n TPath,\n >\n extends BaseSubject\n implements\n SubscribableWithState<TState, TPath>,\n NestedSubscribable<TState, TPath>\n{\n public get path() {\n return this.binding.path;\n }\n\n constructor(private binding: NestedSubscribable<TState, TPath>) {\n super();\n }\n\n public getState() {\n return this.binding.getState();\n }\n\n public outerSubscribe(callback: () => void) {\n return this.binding.subscribe(callback);\n }\n\n protected _connect(): Unsubscribe {\n const callback = () => {\n this.notifySubscribers();\n };\n\n let lastState = this.binding.getState();\n let innerUnsubscribe = lastState?.subscribe(callback);\n const onRuntimeUpdate = () => {\n const newState = this.binding.getState();\n if (newState === lastState) return;\n lastState = newState;\n\n innerUnsubscribe?.();\n innerUnsubscribe = newState?.subscribe(callback);\n\n callback();\n };\n\n const outerUnsubscribe = this.outerSubscribe(onRuntimeUpdate);\n return () => {\n outerUnsubscribe?.();\n innerUnsubscribe?.();\n };\n }\n}\n\nexport class EventSubscriptionSubject<\n TEvent extends string,\n> extends BaseSubject {\n constructor(private config: EventSubscribable<TEvent>) {\n super();\n }\n\n public getState() {\n return this.config.binding.getState();\n }\n\n public outerSubscribe(callback: () => void) {\n return this.config.binding.subscribe(callback);\n }\n\n protected _connect(): Unsubscribe {\n const callback = (payload?: unknown) => {\n this.notifySubscribers(payload);\n };\n\n let lastState = this.config.binding.getState();\n let innerUnsubscribe = lastState?.unstable_on(this.config.event, callback);\n const onRuntimeUpdate = () => {\n const newState = this.config.binding.getState();\n if (newState === lastState) return;\n lastState = newState;\n\n innerUnsubscribe?.();\n innerUnsubscribe = newState?.unstable_on(this.config.event, callback);\n };\n\n const outerUnsubscribe = this.outerSubscribe(onRuntimeUpdate);\n return () => {\n outerUnsubscribe?.();\n innerUnsubscribe?.();\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"subscribable.js","names":[],"sources":["../../src/subscribable/subscribable.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\n\nexport const SKIP_UPDATE = Symbol(\"skip-update\");\nexport type SKIP_UPDATE = typeof SKIP_UPDATE;\n\nexport type Subscribable = {\n subscribe: (callback: () => void) => Unsubscribe;\n};\n\nexport type SubscribableWithState<TState, TPath> = Subscribable & {\n path: TPath;\n getState: () => TState;\n};\n\nexport type NestedSubscribable<\n TState extends Subscribable | undefined,\n TPath,\n> = SubscribableWithState<TState, TPath>;\n\nexport type EventSubscribable<TEvent extends string> = {\n event: TEvent;\n binding: SubscribableWithState<\n | {\n unstable_on: (\n event: TEvent,\n callback: (payload?: unknown) => void,\n ) => Unsubscribe;\n }\n | undefined,\n unknown\n >;\n};\n\nfunction shallowEqual<T extends object>(\n objA: T | undefined,\n objB: T | undefined,\n) {\n if (objA === undefined && objB === undefined) return true;\n if (objA === undefined) return false;\n if (objB === undefined) return false;\n\n for (const key of Object.keys(objA)) {\n const valueA = objA[key as keyof T];\n const valueB = objB[key as keyof T];\n if (!Object.is(valueA, valueB)) return false;\n }\n\n return true;\n}\n\nexport class BaseSubscribable {\n private _subscribers = new Set<() => void>();\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscribers.add(callback);\n return () => this._subscribers.delete(callback);\n }\n\n public waitForUpdate() {\n return new Promise<void>((resolve) => {\n const unsubscribe = this.subscribe(() => {\n unsubscribe();\n resolve();\n });\n });\n }\n\n protected _notifySubscribers() {\n const errors = [];\n for (const callback of this._subscribers) {\n try {\n callback();\n } catch (error) {\n errors.push(error);\n }\n }\n\n if (errors.length > 0) {\n if (errors.length === 1) {\n throw errors[0];\n } else {\n for (const error of errors) {\n console.error(error);\n }\n throw new AggregateError(errors);\n }\n }\n }\n}\n\n// lazy connect/disconnect: only opens upstream subscription while it has subscribers\nexport abstract class BaseSubject {\n private _subscriptions = new Set<(payload?: unknown) => void>();\n private _connection: Unsubscribe | undefined;\n\n protected get isConnected() {\n return !!this._connection;\n }\n\n protected abstract _connect(): Unsubscribe;\n\n protected notifySubscribers(payload?: unknown) {\n for (const callback of this._subscriptions) callback(payload);\n }\n\n private _updateConnection() {\n if (this._subscriptions.size > 0) {\n if (this._connection) return;\n this._connection = this._connect();\n } else {\n this._connection?.();\n this._connection = undefined;\n }\n }\n\n public subscribe(callback: (payload?: unknown) => void) {\n this._subscriptions.add(callback);\n this._updateConnection();\n\n return () => {\n this._subscriptions.delete(callback);\n this._updateConnection();\n };\n }\n}\n\nexport class ShallowMemoizeSubject<TState extends object, TPath>\n extends BaseSubject\n implements SubscribableWithState<TState, TPath>\n{\n public get path() {\n return this.binding.path;\n }\n\n constructor(\n private binding: SubscribableWithState<TState | SKIP_UPDATE, TPath>,\n ) {\n super();\n const state = binding.getState();\n if (state === SKIP_UPDATE)\n throw new Error(\"Entry not available in the store\");\n this._previousState = state;\n }\n\n private _previousState: TState;\n public getState = () => {\n if (!this.isConnected) this._syncState();\n return this._previousState;\n };\n\n private _syncState() {\n const state = this.binding.getState();\n if (state === SKIP_UPDATE) return false;\n if (shallowEqual(state, this._previousState)) return false;\n this._previousState = state;\n return true;\n }\n\n protected _connect() {\n const callback = () => {\n if (this._syncState()) {\n this.notifySubscribers();\n }\n };\n\n return this.binding.subscribe(callback);\n }\n}\n\nexport class LazyMemoizeSubject<TState extends object, TPath>\n extends BaseSubject\n implements SubscribableWithState<TState, TPath>\n{\n public get path() {\n return this.binding.path;\n }\n\n constructor(\n private binding: SubscribableWithState<TState | SKIP_UPDATE, TPath>,\n ) {\n super();\n }\n\n private _previousStateDirty = true;\n private _previousState: TState | undefined;\n public getState = () => {\n if (!this.isConnected || this._previousStateDirty) {\n const newState = this.binding.getState();\n if (newState !== SKIP_UPDATE) {\n this._previousState = newState;\n }\n this._previousStateDirty = false;\n }\n if (this._previousState === undefined)\n throw new Error(\"Entry not available in the store\");\n return this._previousState;\n };\n\n protected _connect() {\n const callback = () => {\n this._previousStateDirty = true;\n this.notifySubscribers();\n };\n\n return this.binding.subscribe(callback);\n }\n}\n\nexport class NestedSubscriptionSubject<\n TState extends Subscribable | undefined,\n TPath,\n>\n extends BaseSubject\n implements\n SubscribableWithState<TState, TPath>,\n NestedSubscribable<TState, TPath>\n{\n public get path() {\n return this.binding.path;\n }\n\n constructor(private binding: NestedSubscribable<TState, TPath>) {\n super();\n }\n\n public getState() {\n return this.binding.getState();\n }\n\n public outerSubscribe(callback: () => void) {\n return this.binding.subscribe(callback);\n }\n\n protected _connect(): Unsubscribe {\n const callback = () => {\n this.notifySubscribers();\n };\n\n let lastState = this.binding.getState();\n let innerUnsubscribe = lastState?.subscribe(callback);\n const onRuntimeUpdate = () => {\n const newState = this.binding.getState();\n if (newState === lastState) return;\n lastState = newState;\n\n innerUnsubscribe?.();\n innerUnsubscribe = newState?.subscribe(callback);\n\n callback();\n };\n\n const outerUnsubscribe = this.outerSubscribe(onRuntimeUpdate);\n return () => {\n outerUnsubscribe?.();\n innerUnsubscribe?.();\n };\n }\n}\n\nexport class EventSubscriptionSubject<\n TEvent extends string,\n> extends BaseSubject {\n constructor(private config: EventSubscribable<TEvent>) {\n super();\n }\n\n public getState() {\n return this.config.binding.getState();\n }\n\n public outerSubscribe(callback: () => void) {\n return this.config.binding.subscribe(callback);\n }\n\n protected _connect(): Unsubscribe {\n const callback = (payload?: unknown) => {\n this.notifySubscribers(payload);\n };\n\n let lastState = this.config.binding.getState();\n let innerUnsubscribe = lastState?.unstable_on(this.config.event, callback);\n const onRuntimeUpdate = () => {\n const newState = this.config.binding.getState();\n if (newState === lastState) return;\n lastState = newState;\n\n innerUnsubscribe?.();\n innerUnsubscribe = newState?.unstable_on(this.config.event, callback);\n };\n\n const outerUnsubscribe = this.outerSubscribe(onRuntimeUpdate);\n return () => {\n outerUnsubscribe?.();\n innerUnsubscribe?.();\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/types/message.d.ts
CHANGED
|
@@ -123,6 +123,12 @@ type ToolCallMessagePart<TArgs = ReadonlyJSONObject, TResult = unknown> = {
|
|
|
123
123
|
readonly interrupt?: {
|
|
124
124
|
type: "human";
|
|
125
125
|
payload: unknown;
|
|
126
|
+
}; /** Server-side approval gate. `approved === undefined` is the only state in which `respondToApproval` may be called. */
|
|
127
|
+
readonly approval?: {
|
|
128
|
+
readonly id: string;
|
|
129
|
+
readonly approved?: boolean;
|
|
130
|
+
readonly reason?: string;
|
|
131
|
+
readonly isAutomatic?: boolean;
|
|
126
132
|
}; /** Parent message-part ID when this part belongs to a nested structure. */
|
|
127
133
|
readonly parentId?: string;
|
|
128
134
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","names":[],"sources":["../../src/types/message.ts"],"mappings":";;;;;KASY,eAAA;EAAA,SACD,IAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,oBAAA;EAAA,SACD,IAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,sBAAA;EAAA,UACA,YAAA,WAAuB,kBAAkB;AAAA;AAAA,KAGzC,iBAAA;EAAA,SAEG,IAAA;EAAA,SACA,UAAA;EAAA,SACA,EAAA;EAAA,SACA,GAAA;EAAA,SACA,KAAA;EAAA,SACA,gBAAA,GAAmB,sBAAA;EAAA,SACnB,QAAA;AAAA;EAAA,SAGA,IAAA;EAAA,SACA,UAAA;EAAA,SACA,EAAA;EAAA,SACA,GAAA;EAAA,SACA,KAAA;EAAA,SACA,SAAA;EAAA,SACA,QAAA;EAAA,SACA,gBAAA,GAAmB,sBAAsB;EAAA,SACzC,QAAA;AAAA;AAAA,KAGH,gBAAA;EAAA,SACD,IAAA;EAAA,SACA,KAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,eAAA;EAAA,SACD,IAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,yBAAA;EAAA,SACD,IAAA;EAAA,SACA,KAAA;IAAA,SACE,IAAA;IAAA,SACA,MAAA;EAAA;AAAA;AAAA,KAID,eAAA;EAAA,SACD,IAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA,EAAM,CAAC;AAAA;AAtBC;AAGnB;;;;;;;;AAHmB,KAkCP,gBAAA;EA1BO,oFA8BJ,SAAA,UA3BH;EAAA,SA6BG,KAAA,GAAQ,MAAA;WAER,QAAA,YAAoB,gBAAgB,IA9BxC;EAAA,SAgCI,GAAA;AAAA;;;AA7BI;KAmCP,gBAAA;EA/Be,uCAiChB,IAAA,EAAM,gBAAA,YAA4B,gBAAgB;AAAA;;;;;;;AA9B3C;AAYlB;KA6BY,uBAAA;EAAA,SACD,IAAA,mBAtBwC;EAAA,SAwBxC,IAAA,EAAM,gBAAgB,EA1BlB;EAAA,SA4BJ,EAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,cAAA;EAAA,SACD,WAAA;EAAA,SACA,QAAA;EAAA,SACA,UAAA;AAAA;AAAA,cAGE,kBAAA;AAAA,cAEA,WAAA,GAAe,GAAuB;AAAA,KAGvC,8BAAA;EAAA,SACD,GAAA,GAAM,cAAc;AAAA;AAAA,KAGnB,mBAAA,SACF,kBAAA;EApCmD,oDAwClD,IAAA,eA7BwB;EAAA,SA+BxB,UAAA,UA5BsB;EAAA,SA8BtB,QAAA;EA9BA;;;;;EAAA,SAoCA,IAAA,EAAM,KAAA,EA9BL;EAAA,SAgCD,MAAA,GAAS,OAAA;WAET,OAAA,wBAjCA;EAAA,SAmCA,QAAA,UAjCA;EAAA,SAmCA,QAAA,YAnCU;EAAA,SAqCV,GAAA,GAAM,8BAAA,EAlCc;EAAA,SAoCpB,YAAA,YAAwB,oBAAA,gBApCJ;EAAA,SAsCpB,SAAA;IAAc,IAAA;IAAe,OAAA;EAAA,GApCW;EAAA,SAsCxC,QAAA;
|
|
1
|
+
{"version":3,"file":"message.d.ts","names":[],"sources":["../../src/types/message.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","names":[],"sources":["../../src/types/message.ts"],"sourcesContent":["import type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\nimport type { ToolModelContentPart } from \"assistant-stream\";\nimport type { CompleteAttachment } from \"./attachment\";\n\nexport type { ToolModelContentPart };\n\nexport type TextMessagePart = {\n readonly type: \"text\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type ReasoningMessagePart = {\n readonly type: \"reasoning\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type SourceProviderMetadata = {\n readonly [providerName: string]: ReadonlyJSONObject;\n};\n\nexport type SourceMessagePart =\n | {\n readonly type: \"source\";\n readonly sourceType: \"url\";\n readonly id: string;\n readonly url: string;\n readonly title?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n }\n | {\n readonly type: \"source\";\n readonly sourceType: \"document\";\n readonly id: string;\n readonly url?: undefined;\n readonly title: string;\n readonly mediaType: string;\n readonly filename?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n };\n\nexport type ImageMessagePart = {\n readonly type: \"image\";\n readonly image: string;\n readonly filename?: string;\n};\n\nexport type FileMessagePart = {\n readonly type: \"file\";\n readonly filename?: string;\n readonly data: string;\n readonly mimeType: string;\n readonly parentId?: string;\n};\n\nexport type Unstable_AudioMessagePart = {\n readonly type: \"audio\";\n readonly audio: {\n readonly data: string;\n readonly format: \"mp3\" | \"wav\";\n };\n};\n\nexport type DataMessagePart<T = any> = {\n readonly type: \"data\";\n readonly name: string;\n readonly data: T;\n};\n\n/**\n * A JSON spec describing a tree of UI components to render.\n *\n * The agent emits a {@link GenerativeUIMessagePart} containing this spec, and\n * the consumer-provided component allowlist is used to resolve `component`\n * names. Any component referenced that is not present in the allowlist is\n * rejected with a typed error — the allowlist is the security boundary in the\n * default same-realm rendering path.\n */\nexport type GenerativeUINode =\n | string\n | {\n /** Allowlisted component name (resolved against the consumer registry). */\n readonly component: string;\n /** Props passed to the resolved component (must be JSON-serializable). */\n readonly props?: Record<string, unknown>;\n /** Optional children — strings render as text, objects recurse. */\n readonly children?: readonly GenerativeUINode[];\n /** Optional stable key for React reconciliation. */\n readonly key?: string;\n };\n\n/**\n * The root spec for a generative UI tree.\n */\nexport type GenerativeUISpec = {\n /** Root node(s) to render. */\n readonly root: GenerativeUINode | readonly GenerativeUINode[];\n};\n\n/**\n * A message part that carries a JSON spec describing UI to render.\n *\n * Render with `<MessagePrimitive.GenerativeUI components={...} />`. The\n * primitive resolves component names against the consumer-provided allowlist\n * — any unknown name throws a typed error rather than rendering. Stream-\n * friendly: a partially-streamed spec renders progressively.\n */\nexport type GenerativeUIMessagePart = {\n readonly type: \"generative-ui\";\n /** The JSON spec describing the UI tree. */\n readonly spec: GenerativeUISpec;\n /** Optional id (useful for replays / stable keys). */\n readonly id?: string;\n readonly parentId?: string;\n};\n\nexport type McpAppMetadata = {\n readonly resourceUri: string;\n readonly mimeType?: string;\n readonly visibility?: readonly (\"model\" | \"app\")[];\n};\n\nexport const MCP_APP_URI_SCHEME = \"ui://\";\n\nexport const isMcpAppUri = (uri: string | undefined): boolean =>\n !!uri?.startsWith(MCP_APP_URI_SCHEME);\n\nexport type ToolCallMessagePartMcpMetadata = {\n readonly app?: McpAppMetadata;\n};\n\nexport type ToolCallMessagePart<\n TArgs = ReadonlyJSONObject,\n TResult = unknown,\n> = {\n /** Identifies this part as a tool call. */\n readonly type: \"tool-call\";\n /** Stable identifier for this invocation of the tool. */\n readonly toolCallId: string;\n /** Name of the tool requested by the model. */\n readonly toolName: string;\n /**\n * Arguments supplied by the model. During streaming this is a partial parse:\n * fields may be missing or incomplete. From a tool-call renderer, use\n * `useToolArgsStatus` to detect which fields are still arriving.\n */\n readonly args: TArgs;\n /** Result returned by the tool, if it has completed. */\n readonly result?: TResult | undefined;\n /** Whether the result represents a tool execution error. */\n readonly isError?: boolean | undefined;\n /** Raw JSON argument text streamed by the model. */\n readonly argsText: string;\n /** UI-only artifact associated with the tool result. */\n readonly artifact?: unknown;\n /** MCP app metadata associated with this tool call, when present. */\n readonly mcp?: ToolCallMessagePartMcpMetadata;\n /** Content returned to the model for this tool result. */\n readonly modelContent?: readonly ToolModelContentPart[] | undefined;\n /** Human-input request that must be resolved before the run can continue. */\n readonly interrupt?: { type: \"human\"; payload: unknown };\n /** Parent message-part ID when this part belongs to a nested structure. */\n readonly parentId?: string;\n /**\n * Nested thread messages produced by this tool call, for example a sub-agent\n * conversation.\n */\n readonly messages?: readonly ThreadMessage[];\n};\n\nexport type ThreadUserMessagePart =\n | TextMessagePart\n | ImageMessagePart\n | FileMessagePart\n | DataMessagePart\n | Unstable_AudioMessagePart;\n\nexport type ThreadAssistantMessagePart =\n | TextMessagePart\n | ReasoningMessagePart\n | ToolCallMessagePart\n | SourceMessagePart\n | FileMessagePart\n | ImageMessagePart\n | DataMessagePart\n | GenerativeUIMessagePart;\n\nexport type MessagePartStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"complete\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: unknown;\n };\n\nexport type ToolCallMessagePartStatus =\n | {\n /** The tool call is waiting for UI or human input before continuing. */\n readonly type: \"requires-action\";\n /** Reason the tool call requires action. */\n readonly reason: \"interrupt\";\n }\n | MessagePartStatus;\n\nexport type MessageStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"requires-action\";\n readonly reason: \"tool-calls\" | \"interrupt\";\n }\n | {\n readonly type: \"complete\";\n readonly reason: \"stop\" | \"unknown\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"tool-calls\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: ReadonlyJSONValue;\n };\n\nexport type MessageTiming = {\n readonly streamStartTime: number;\n readonly firstTokenTime?: number;\n readonly totalStreamTime?: number;\n readonly tokenCount?: number;\n readonly tokensPerSecond?: number;\n readonly totalChunks: number;\n readonly toolCallCount: number;\n};\n\nexport type ThreadStep = {\n readonly messageId?: string;\n readonly usage?:\n | {\n readonly inputTokens: number;\n readonly outputTokens: number;\n }\n | undefined;\n};\n\ntype MessageCommonProps = {\n readonly id: string;\n readonly createdAt: Date;\n};\n\nexport type ThreadSystemMessage = MessageCommonProps & {\n readonly role: \"system\";\n readonly content: readonly [TextMessagePart];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadUserMessage = MessageCommonProps & {\n readonly role: \"user\";\n readonly content: readonly ThreadUserMessagePart[];\n readonly attachments: readonly CompleteAttachment[];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadAssistantMessage = MessageCommonProps & {\n readonly role: \"assistant\";\n readonly content: readonly ThreadAssistantMessagePart[];\n readonly status: MessageStatus;\n readonly metadata: {\n readonly unstable_state: ReadonlyJSONValue;\n readonly unstable_annotations: readonly ReadonlyJSONValue[];\n readonly unstable_data: readonly ReadonlyJSONValue[];\n readonly steps: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n readonly custom: Record<string, unknown>;\n };\n};\n\ntype BaseThreadMessage = {\n readonly status?: ThreadAssistantMessage[\"status\"];\n readonly metadata: {\n readonly unstable_state?: ReadonlyJSONValue;\n readonly unstable_annotations?: readonly ReadonlyJSONValue[];\n readonly unstable_data?: readonly ReadonlyJSONValue[];\n readonly steps?: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n readonly custom: Record<string, unknown>;\n };\n readonly attachments?: ThreadUserMessage[\"attachments\"];\n};\n\nexport type ThreadMessage = BaseThreadMessage &\n (ThreadSystemMessage | ThreadUserMessage | ThreadAssistantMessage);\n\nexport type MessageRole = ThreadMessage[\"role\"];\n\nexport type RunConfig = {\n readonly custom?: Record<string, unknown>;\n};\n\nexport type AppendMessage = Omit<ThreadMessage, \"id\"> & {\n parentId: string | null;\n\n /** The ID of the message that was edited or undefined. */\n sourceId: string | null;\n runConfig: RunConfig | undefined;\n startRun?: boolean | undefined;\n};\n"],"mappings":";AAgIA,MAAa,qBAAqB;AAElC,MAAa,eAAe,QAC1B,CAAC,CAAC,KAAK,WAAW,kBAAkB"}
|
|
1
|
+
{"version":3,"file":"message.js","names":[],"sources":["../../src/types/message.ts"],"sourcesContent":["import type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\nimport type { ToolModelContentPart } from \"assistant-stream\";\nimport type { CompleteAttachment } from \"./attachment\";\n\nexport type { ToolModelContentPart };\n\nexport type TextMessagePart = {\n readonly type: \"text\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type ReasoningMessagePart = {\n readonly type: \"reasoning\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type SourceProviderMetadata = {\n readonly [providerName: string]: ReadonlyJSONObject;\n};\n\nexport type SourceMessagePart =\n | {\n readonly type: \"source\";\n readonly sourceType: \"url\";\n readonly id: string;\n readonly url: string;\n readonly title?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n }\n | {\n readonly type: \"source\";\n readonly sourceType: \"document\";\n readonly id: string;\n readonly url?: undefined;\n readonly title: string;\n readonly mediaType: string;\n readonly filename?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n };\n\nexport type ImageMessagePart = {\n readonly type: \"image\";\n readonly image: string;\n readonly filename?: string;\n};\n\nexport type FileMessagePart = {\n readonly type: \"file\";\n readonly filename?: string;\n readonly data: string;\n readonly mimeType: string;\n readonly parentId?: string;\n};\n\nexport type Unstable_AudioMessagePart = {\n readonly type: \"audio\";\n readonly audio: {\n readonly data: string;\n readonly format: \"mp3\" | \"wav\";\n };\n};\n\nexport type DataMessagePart<T = any> = {\n readonly type: \"data\";\n readonly name: string;\n readonly data: T;\n};\n\n/**\n * A JSON spec describing a tree of UI components to render.\n *\n * The agent emits a {@link GenerativeUIMessagePart} containing this spec, and\n * the consumer-provided component allowlist is used to resolve `component`\n * names. Any component referenced that is not present in the allowlist is\n * rejected with a typed error — the allowlist is the security boundary in the\n * default same-realm rendering path.\n */\nexport type GenerativeUINode =\n | string\n | {\n /** Allowlisted component name (resolved against the consumer registry). */\n readonly component: string;\n /** Props passed to the resolved component (must be JSON-serializable). */\n readonly props?: Record<string, unknown>;\n /** Optional children — strings render as text, objects recurse. */\n readonly children?: readonly GenerativeUINode[];\n /** Optional stable key for React reconciliation. */\n readonly key?: string;\n };\n\n/**\n * The root spec for a generative UI tree.\n */\nexport type GenerativeUISpec = {\n /** Root node(s) to render. */\n readonly root: GenerativeUINode | readonly GenerativeUINode[];\n};\n\n/**\n * A message part that carries a JSON spec describing UI to render.\n *\n * Render with `<MessagePrimitive.GenerativeUI components={...} />`. The\n * primitive resolves component names against the consumer-provided allowlist\n * — any unknown name throws a typed error rather than rendering. Stream-\n * friendly: a partially-streamed spec renders progressively.\n */\nexport type GenerativeUIMessagePart = {\n readonly type: \"generative-ui\";\n /** The JSON spec describing the UI tree. */\n readonly spec: GenerativeUISpec;\n /** Optional id (useful for replays / stable keys). */\n readonly id?: string;\n readonly parentId?: string;\n};\n\nexport type McpAppMetadata = {\n readonly resourceUri: string;\n readonly mimeType?: string;\n readonly visibility?: readonly (\"model\" | \"app\")[];\n};\n\nexport const MCP_APP_URI_SCHEME = \"ui://\";\n\nexport const isMcpAppUri = (uri: string | undefined): boolean =>\n !!uri?.startsWith(MCP_APP_URI_SCHEME);\n\nexport type ToolCallMessagePartMcpMetadata = {\n readonly app?: McpAppMetadata;\n};\n\nexport type ToolCallMessagePart<\n TArgs = ReadonlyJSONObject,\n TResult = unknown,\n> = {\n /** Identifies this part as a tool call. */\n readonly type: \"tool-call\";\n /** Stable identifier for this invocation of the tool. */\n readonly toolCallId: string;\n /** Name of the tool requested by the model. */\n readonly toolName: string;\n /**\n * Arguments supplied by the model. During streaming this is a partial parse:\n * fields may be missing or incomplete. From a tool-call renderer, use\n * `useToolArgsStatus` to detect which fields are still arriving.\n */\n readonly args: TArgs;\n /** Result returned by the tool, if it has completed. */\n readonly result?: TResult | undefined;\n /** Whether the result represents a tool execution error. */\n readonly isError?: boolean | undefined;\n /** Raw JSON argument text streamed by the model. */\n readonly argsText: string;\n /** UI-only artifact associated with the tool result. */\n readonly artifact?: unknown;\n /** MCP app metadata associated with this tool call, when present. */\n readonly mcp?: ToolCallMessagePartMcpMetadata;\n /** Content returned to the model for this tool result. */\n readonly modelContent?: readonly ToolModelContentPart[] | undefined;\n /** Human-input request that must be resolved before the run can continue. */\n readonly interrupt?: { type: \"human\"; payload: unknown };\n /** Server-side approval gate. `approved === undefined` is the only state in which `respondToApproval` may be called. */\n readonly approval?: {\n readonly id: string;\n readonly approved?: boolean;\n readonly reason?: string;\n readonly isAutomatic?: boolean;\n };\n /** Parent message-part ID when this part belongs to a nested structure. */\n readonly parentId?: string;\n /**\n * Nested thread messages produced by this tool call, for example a sub-agent\n * conversation.\n */\n readonly messages?: readonly ThreadMessage[];\n};\n\nexport type ThreadUserMessagePart =\n | TextMessagePart\n | ImageMessagePart\n | FileMessagePart\n | DataMessagePart\n | Unstable_AudioMessagePart;\n\nexport type ThreadAssistantMessagePart =\n | TextMessagePart\n | ReasoningMessagePart\n | ToolCallMessagePart\n | SourceMessagePart\n | FileMessagePart\n | ImageMessagePart\n | DataMessagePart\n | GenerativeUIMessagePart;\n\nexport type MessagePartStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"complete\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: unknown;\n };\n\nexport type ToolCallMessagePartStatus =\n | {\n /** The tool call is waiting for UI or human input before continuing. */\n readonly type: \"requires-action\";\n /** Reason the tool call requires action. */\n readonly reason: \"interrupt\";\n }\n | MessagePartStatus;\n\nexport type MessageStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"requires-action\";\n readonly reason: \"tool-calls\" | \"interrupt\";\n }\n | {\n readonly type: \"complete\";\n readonly reason: \"stop\" | \"unknown\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"tool-calls\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: ReadonlyJSONValue;\n };\n\nexport type MessageTiming = {\n readonly streamStartTime: number;\n readonly firstTokenTime?: number;\n readonly totalStreamTime?: number;\n readonly tokenCount?: number;\n readonly tokensPerSecond?: number;\n readonly totalChunks: number;\n readonly toolCallCount: number;\n};\n\nexport type ThreadStep = {\n readonly messageId?: string;\n readonly usage?:\n | {\n readonly inputTokens: number;\n readonly outputTokens: number;\n }\n | undefined;\n};\n\ntype MessageCommonProps = {\n readonly id: string;\n readonly createdAt: Date;\n};\n\nexport type ThreadSystemMessage = MessageCommonProps & {\n readonly role: \"system\";\n readonly content: readonly [TextMessagePart];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadUserMessage = MessageCommonProps & {\n readonly role: \"user\";\n readonly content: readonly ThreadUserMessagePart[];\n readonly attachments: readonly CompleteAttachment[];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadAssistantMessage = MessageCommonProps & {\n readonly role: \"assistant\";\n readonly content: readonly ThreadAssistantMessagePart[];\n readonly status: MessageStatus;\n readonly metadata: {\n readonly unstable_state: ReadonlyJSONValue;\n readonly unstable_annotations: readonly ReadonlyJSONValue[];\n readonly unstable_data: readonly ReadonlyJSONValue[];\n readonly steps: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n readonly custom: Record<string, unknown>;\n };\n};\n\ntype BaseThreadMessage = {\n readonly status?: ThreadAssistantMessage[\"status\"];\n readonly metadata: {\n readonly unstable_state?: ReadonlyJSONValue;\n readonly unstable_annotations?: readonly ReadonlyJSONValue[];\n readonly unstable_data?: readonly ReadonlyJSONValue[];\n readonly steps?: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n readonly custom: Record<string, unknown>;\n };\n readonly attachments?: ThreadUserMessage[\"attachments\"];\n};\n\nexport type ThreadMessage = BaseThreadMessage &\n (ThreadSystemMessage | ThreadUserMessage | ThreadAssistantMessage);\n\nexport type MessageRole = ThreadMessage[\"role\"];\n\nexport type RunConfig = {\n readonly custom?: Record<string, unknown>;\n};\n\nexport type AppendMessage = Omit<ThreadMessage, \"id\"> & {\n parentId: string | null;\n\n /** The ID of the message that was edited or undefined. */\n sourceId: string | null;\n runConfig: RunConfig | undefined;\n startRun?: boolean | undefined;\n};\n"],"mappings":";AAgIA,MAAa,qBAAqB;AAElC,MAAa,eAAe,QAC1B,CAAC,CAAC,KAAK,WAAW,kBAAkB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Framework-agnostic core runtime for assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"assistant",
|
|
@@ -59,12 +59,12 @@
|
|
|
59
59
|
],
|
|
60
60
|
"sideEffects": false,
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"assistant-stream": "^0.3.
|
|
62
|
+
"assistant-stream": "^0.3.17",
|
|
63
63
|
"nanoid": "^5.1.11"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"@assistant-ui/store": "^0.2.12",
|
|
67
|
-
"@assistant-ui/tap": "^0.5.
|
|
67
|
+
"@assistant-ui/tap": "^0.5.13",
|
|
68
68
|
"@types/react": "*",
|
|
69
69
|
"react": "^18 || ^19",
|
|
70
70
|
"assistant-cloud": "^0.1.29",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"vitest": "^4.1.7",
|
|
91
91
|
"zustand": "^5.0.13",
|
|
92
92
|
"@assistant-ui/store": "0.2.12",
|
|
93
|
-
"@assistant-ui/tap": "0.5.
|
|
93
|
+
"@assistant-ui/tap": "0.5.13",
|
|
94
94
|
"@assistant-ui/x-buildutils": "0.0.9",
|
|
95
95
|
"assistant-cloud": "0.1.29"
|
|
96
96
|
},
|
package/src/adapters/index.ts
CHANGED
|
@@ -8,10 +8,7 @@ export {
|
|
|
8
8
|
|
|
9
9
|
// Speech adapters
|
|
10
10
|
export type { SpeechSynthesisAdapter, DictationAdapter } from "./speech";
|
|
11
|
-
export {
|
|
12
|
-
WebSpeechSynthesisAdapter,
|
|
13
|
-
WebSpeechDictationAdapter,
|
|
14
|
-
} from "./speech";
|
|
11
|
+
export { WebSpeechSynthesisAdapter, WebSpeechDictationAdapter } from "./speech";
|
|
15
12
|
|
|
16
13
|
// Voice adapter
|
|
17
14
|
export type { RealtimeVoiceAdapter } from "./voice";
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
// @assistant-ui/core - Framework-agnostic core runtime (public API)
|
|
2
2
|
|
|
3
|
+
/// <reference path="./store/scope-registration.ts" />
|
|
4
|
+
|
|
5
|
+
import { checkDuplicateCore } from "./internal/duplicate-detection";
|
|
6
|
+
|
|
7
|
+
if (process.env.NODE_ENV !== "production") {
|
|
8
|
+
checkDuplicateCore();
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
export type {
|
|
4
12
|
// Message parts
|
|
5
13
|
TextMessagePart,
|
|
@@ -80,6 +88,8 @@ export { mergeModelContexts } from "./model-context/types";
|
|
|
80
88
|
|
|
81
89
|
export { tool } from "./model-context/tool";
|
|
82
90
|
|
|
91
|
+
export type { ToolExecutionStatus } from "./runtimes/tool-invocations/ToolInvocationTracker";
|
|
92
|
+
|
|
83
93
|
export { ModelContextRegistry } from "./model-context/registry";
|
|
84
94
|
export type {
|
|
85
95
|
ModelContextRegistryToolHandle,
|
|
@@ -170,6 +180,7 @@ export type {
|
|
|
170
180
|
RuntimeCapabilities,
|
|
171
181
|
AddToolResultOptions,
|
|
172
182
|
ResumeToolCallOptions,
|
|
183
|
+
RespondToToolApprovalOptions,
|
|
173
184
|
SubmitFeedbackOptions,
|
|
174
185
|
ThreadSuggestion,
|
|
175
186
|
SpeechState,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Warns once if a second copy of @assistant-ui/core is loaded into the
|
|
2
|
+
// same runtime. Mismatched transitive versions of core silently break
|
|
3
|
+
// runtime behavior — tools registered via `makeAssistantTool` don't reach
|
|
4
|
+
// the active runtime, context lookups resolve to the wrong provider,
|
|
5
|
+
// `instanceof` checks fail (see issue #4101). The actual version diagnosis
|
|
6
|
+
// lives in `npx assistant-ui doctor`.
|
|
7
|
+
//
|
|
8
|
+
// The caller is responsible for gating on `process.env.NODE_ENV` so this
|
|
9
|
+
// module tree-shakes out of production bundles.
|
|
10
|
+
|
|
11
|
+
const KEY = Symbol.for("@assistant-ui/core.loaded");
|
|
12
|
+
|
|
13
|
+
export function checkDuplicateCore(): void {
|
|
14
|
+
const g = globalThis as unknown as Record<symbol, boolean | undefined>;
|
|
15
|
+
if (g[KEY]) {
|
|
16
|
+
// eslint-disable-next-line no-console
|
|
17
|
+
console.warn(
|
|
18
|
+
"[@assistant-ui/core] Multiple copies of @assistant-ui/core are " +
|
|
19
|
+
"loaded into the same runtime. This causes subtle bugs (tools not " +
|
|
20
|
+
"reaching the runtime, context lookups returning the wrong " +
|
|
21
|
+
"provider, instanceof checks failing). Run " +
|
|
22
|
+
"`npx assistant-ui doctor` to diagnose.",
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
g[KEY] = true;
|
|
26
|
+
}
|
|
@@ -10,9 +10,8 @@ import type { AssistantRuntimeCore } from "../runtime/interfaces/assistant-runti
|
|
|
10
10
|
import { RuntimeAdapter } from "./RuntimeAdapter";
|
|
11
11
|
|
|
12
12
|
export const getRenderComponent = (runtime: AssistantRuntime) => {
|
|
13
|
-
return (runtime as { _core?: AssistantRuntimeCore })._core
|
|
14
|
-
|
|
|
15
|
-
| undefined;
|
|
13
|
+
return (runtime as { _core?: AssistantRuntimeCore })._core
|
|
14
|
+
?.RenderComponent as ComponentType | undefined;
|
|
16
15
|
};
|
|
17
16
|
|
|
18
17
|
export type AssistantProviderBaseProps = PropsWithChildren<{
|
package/src/react/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference path="../store/scope-registration.ts" />
|
|
1
2
|
/// <reference path="./types/store-augmentation.ts" />
|
|
2
3
|
|
|
3
4
|
// model-context
|
|
@@ -129,12 +130,6 @@ export {
|
|
|
129
130
|
useRuntimeAdapters,
|
|
130
131
|
type RuntimeAdapters,
|
|
131
132
|
} from "./runtimes/RuntimeAdapterProvider";
|
|
132
|
-
export {
|
|
133
|
-
useToolInvocations,
|
|
134
|
-
type ToolExecutionStatus,
|
|
135
|
-
type AssistantTransportState,
|
|
136
|
-
type AddToolResultCommand,
|
|
137
|
-
} from "./runtimes/useToolInvocations";
|
|
138
133
|
export { useExternalStoreRuntime } from "./runtimes/useExternalStoreRuntime";
|
|
139
134
|
export {
|
|
140
135
|
useExternalMessageConverter,
|
|
@@ -178,6 +173,7 @@ export {
|
|
|
178
173
|
type PartState,
|
|
179
174
|
} from "./primitives/message/MessageParts";
|
|
180
175
|
export { MessagePrimitiveGroupedParts } from "./primitives/message/MessageGroupedParts";
|
|
176
|
+
export { groupPartByType } from "./utils/groupParts";
|
|
181
177
|
export {
|
|
182
178
|
MessagePrimitiveGenerativeUI,
|
|
183
179
|
GenerativeUIRender,
|
|
@@ -86,8 +86,7 @@ export const ChainOfThoughtPrimitiveParts: FC<
|
|
|
86
86
|
);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
//
|
|
90
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage
|
|
89
|
+
// oxlint-disable-next-line react-hooks/rules-of-hooks -- intentional conditional hook below the early return above
|
|
91
90
|
const messageComponents = useMemo(
|
|
92
91
|
() => ({
|
|
93
92
|
Reasoning: components?.Reasoning,
|
|
@@ -4,7 +4,7 @@ import { MessagePrimitiveAttachments } from "./MessageAttachments";
|
|
|
4
4
|
|
|
5
5
|
const mockUseAuiState = vi.fn();
|
|
6
6
|
type UseAuiStateSelector = Parameters<
|
|
7
|
-
typeof import("@assistant-ui/store")["useAuiState"]
|
|
7
|
+
(typeof import("@assistant-ui/store"))["useAuiState"]
|
|
8
8
|
>[0];
|
|
9
9
|
type AttachmentsElement = ReactElement<{ children: () => null }>;
|
|
10
10
|
|
|
@@ -10,9 +10,8 @@ import type {
|
|
|
10
10
|
} from "../../../types/message";
|
|
11
11
|
import {
|
|
12
12
|
buildGroupTree,
|
|
13
|
-
|
|
13
|
+
GROUPBY_MEMO_KEY,
|
|
14
14
|
type GroupNode,
|
|
15
|
-
normalizeGroupKey,
|
|
16
15
|
} from "../../utils/groupParts";
|
|
17
16
|
import { MessagePartChildren, type EnrichedPartState } from "./MessageParts";
|
|
18
17
|
|
|
@@ -47,30 +46,32 @@ export namespace MessagePrimitiveGroupedParts {
|
|
|
47
46
|
|
|
48
47
|
export type Props<TKey extends `group-${string}` = `group-${string}`> = {
|
|
49
48
|
/**
|
|
50
|
-
* Maps each part to
|
|
51
|
-
* prefix coalesce
|
|
52
|
-
*
|
|
53
|
-
* through `children` with `part` set to its {@link EnrichedPartState}.
|
|
49
|
+
* Maps each part to a group-key path. Adjacent parts that share a
|
|
50
|
+
* prefix coalesce into the same group. Return `[]` (or `null`) to
|
|
51
|
+
* leave a part ungrouped.
|
|
54
52
|
*
|
|
55
|
-
*
|
|
56
|
-
* `switch (part.type)` can
|
|
53
|
+
* Group keys must start with `"group-"` so the renderer's
|
|
54
|
+
* `switch (part.type)` can tell groups apart from real part types.
|
|
57
55
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
56
|
+
* **Prefer {@link groupPartByType}** for the common case of mapping by
|
|
57
|
+
* `part.type` — it ships a stable memo fingerprint so the tree
|
|
58
|
+
* survives unrelated re-renders. Use an inline function only when
|
|
59
|
+
* the helper isn't expressive enough (e.g. branching on
|
|
60
|
+
* `part.toolName` or part metadata).
|
|
60
61
|
*
|
|
61
62
|
* @example
|
|
62
|
-
* ```
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
63
|
+
* ```tsx
|
|
64
|
+
* import { groupPartByType } from "@assistant-ui/react";
|
|
65
|
+
*
|
|
66
|
+
* <MessagePrimitive.GroupedParts
|
|
67
|
+
* groupBy={groupPartByType({
|
|
68
|
+
* reasoning: ["group-thought", "group-reasoning"],
|
|
69
|
+
* "tool-call": ["group-thought", "group-tool"],
|
|
70
|
+
* })}
|
|
71
|
+
* >
|
|
67
72
|
* ```
|
|
68
73
|
*/
|
|
69
|
-
readonly groupBy: (
|
|
70
|
-
part: PartState,
|
|
71
|
-
index: number,
|
|
72
|
-
parts: readonly PartState[],
|
|
73
|
-
) => GroupKey<TKey>;
|
|
74
|
+
readonly groupBy: (part: PartState) => readonly TKey[] | null;
|
|
74
75
|
|
|
75
76
|
/**
|
|
76
77
|
* Render function called once per group node and once per leaf part.
|
|
@@ -79,7 +80,7 @@ export namespace MessagePrimitiveGroupedParts {
|
|
|
79
80
|
*
|
|
80
81
|
* Leaf parts receive the same {@link EnrichedPartState} that
|
|
81
82
|
* `<MessagePrimitive.Parts>` would produce (`toolUI`, `addResult`,
|
|
82
|
-
* `resume`, `dataRendererUI`).
|
|
83
|
+
* `resume`, `respondToApproval`, `dataRendererUI`).
|
|
83
84
|
*/
|
|
84
85
|
readonly children: (info: RenderInfo<TKey>) => ReactNode;
|
|
85
86
|
};
|
|
@@ -148,11 +149,10 @@ const renderNode = <TKey extends `group-${string}`>(
|
|
|
148
149
|
* @example
|
|
149
150
|
* ```tsx
|
|
150
151
|
* <MessagePrimitive.GroupedParts
|
|
151
|
-
* groupBy={(
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* }
|
|
152
|
+
* groupBy={groupPartByType({
|
|
153
|
+
* reasoning: ["group-thought", "group-reasoning"],
|
|
154
|
+
* "tool-call": ["group-thought", "group-tool"],
|
|
155
|
+
* })}
|
|
156
156
|
* >
|
|
157
157
|
* {({ part, children }) => {
|
|
158
158
|
* switch (part.type) {
|
|
@@ -173,12 +173,19 @@ export const MessagePrimitiveGroupedParts = <TKey extends `group-${string}`>({
|
|
|
173
173
|
}: MessagePrimitiveGroupedParts.Props<TKey>): ReactNode => {
|
|
174
174
|
const parts = useAuiState(useShallow((s) => s.message.parts));
|
|
175
175
|
|
|
176
|
+
// Helpers like `groupPartByType` tag the function with `GROUPBY_MEMO_KEY`
|
|
177
|
+
// (a stable string fingerprint of the helper config). When present,
|
|
178
|
+
// memo on `[parts, memoKey]` so the tree survives unrelated renders.
|
|
179
|
+
// For inline `groupBy`, fall back to recomputing each render — O(n)
|
|
180
|
+
// and cheap.
|
|
181
|
+
const memoKey = (groupBy as { [GROUPBY_MEMO_KEY]?: string })[
|
|
182
|
+
GROUPBY_MEMO_KEY
|
|
183
|
+
];
|
|
184
|
+
const memoDep = memoKey ?? groupBy;
|
|
176
185
|
const tree = useMemo(
|
|
177
|
-
() =>
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
),
|
|
181
|
-
[parts, groupBy],
|
|
186
|
+
() => buildGroupTree(parts.map((part) => groupBy(part) ?? [])),
|
|
187
|
+
// oxlint-disable-next-line tap-hooks/exhaustive-deps -- groupBy is captured via memoDep (either its identity or the helper's memoKey fingerprint); listing it directly would defeat the helper-tagged memo path
|
|
188
|
+
[parts, memoDep],
|
|
182
189
|
);
|
|
183
190
|
|
|
184
191
|
return <>{tree.map((node) => renderNode(node, parts, children))}</>;
|
|
@@ -379,8 +379,16 @@ export const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
|
379
379
|
if (type === "tool-call") {
|
|
380
380
|
const addResult = aui.part().addToolResult;
|
|
381
381
|
const resume = aui.part().resumeToolCall;
|
|
382
|
+
const respondToApproval = aui.part().respondToToolApproval;
|
|
382
383
|
if ("Override" in tools)
|
|
383
|
-
return
|
|
384
|
+
return (
|
|
385
|
+
<tools.Override
|
|
386
|
+
{...part}
|
|
387
|
+
addResult={addResult}
|
|
388
|
+
resume={resume}
|
|
389
|
+
respondToApproval={respondToApproval}
|
|
390
|
+
/>
|
|
391
|
+
);
|
|
384
392
|
const Tool = tools.by_name?.[part.toolName] ?? tools.Fallback;
|
|
385
393
|
return (
|
|
386
394
|
<ToolUIDisplay
|
|
@@ -388,6 +396,7 @@ export const MessagePartComponent: FC<MessagePartComponentProps> = ({
|
|
|
388
396
|
Fallback={Tool}
|
|
389
397
|
addResult={addResult}
|
|
390
398
|
resume={resume}
|
|
399
|
+
respondToApproval={respondToApproval}
|
|
391
400
|
/>
|
|
392
401
|
);
|
|
393
402
|
}
|
|
@@ -592,6 +601,7 @@ const RegisteredToolUI: FC = () => {
|
|
|
592
601
|
{...part}
|
|
593
602
|
addResult={aui.part().addToolResult}
|
|
594
603
|
resume={aui.part().resumeToolCall}
|
|
604
|
+
respondToApproval={aui.part().respondToToolApproval}
|
|
595
605
|
/>
|
|
596
606
|
);
|
|
597
607
|
};
|
|
@@ -657,6 +667,8 @@ export type EnrichedPartState =
|
|
|
657
667
|
addResult: ToolCallMessagePartProps["addResult"];
|
|
658
668
|
/** Resume a tool call waiting for human input. */
|
|
659
669
|
resume: ToolCallMessagePartProps["resume"];
|
|
670
|
+
/** Respond to a server-side tool approval gate. */
|
|
671
|
+
respondToApproval: ToolCallMessagePartProps["respondToApproval"];
|
|
660
672
|
})
|
|
661
673
|
| (Extract<PartState, { type: "data" }> & {
|
|
662
674
|
/** The registered data renderer UI element, or null if none registered. */
|
|
@@ -706,6 +718,7 @@ export const MessagePartChildren: FC<{
|
|
|
706
718
|
toolUI: hasUI ? <RegisteredToolUI /> : null,
|
|
707
719
|
addResult: partMethods.addToolResult,
|
|
708
720
|
resume: partMethods.resumeToolCall,
|
|
721
|
+
respondToApproval: partMethods.respondToToolApproval,
|
|
709
722
|
};
|
|
710
723
|
}
|
|
711
724
|
if (state.type === "data") {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type ThreadMessageLike,
|
|
13
13
|
} from "../../runtime/utils/thread-message-like";
|
|
14
14
|
import { getAutoStatus, isAutoStatus } from "../../runtime/utils/auto-status";
|
|
15
|
-
import type { ToolExecutionStatus } from "
|
|
15
|
+
import type { ToolExecutionStatus } from "../../runtimes/tool-invocations/ToolInvocationTracker";
|
|
16
16
|
import type { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
17
17
|
import { generateErrorMessageId } from "../../utils/id";
|
|
18
18
|
import type {
|
|
@@ -22,6 +22,22 @@ import type {
|
|
|
22
22
|
} from "../../types/message";
|
|
23
23
|
import type { MessageTiming } from "../../types/message";
|
|
24
24
|
|
|
25
|
+
type ThreadMessageLikeContentItem = Exclude<
|
|
26
|
+
ThreadMessageLike["content"],
|
|
27
|
+
string
|
|
28
|
+
>[number];
|
|
29
|
+
|
|
30
|
+
const isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>
|
|
31
|
+
c.type === "tool-call" && c.result === undefined;
|
|
32
|
+
|
|
33
|
+
const isInterruptedToolCall = (c: ThreadMessageLikeContentItem): boolean => {
|
|
34
|
+
if (c.type !== "tool-call" || c.result !== undefined) return false;
|
|
35
|
+
return (
|
|
36
|
+
c.interrupt != null ||
|
|
37
|
+
(c.approval != null && c.approval.approved === undefined)
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
25
41
|
export namespace useExternalMessageConverter {
|
|
26
42
|
export type Message =
|
|
27
43
|
| (ThreadMessageLike & {
|
|
@@ -335,15 +351,16 @@ export const convertExternalMessages = <T extends WeakKey>(
|
|
|
335
351
|
const result = chunks.map((message, idx) => {
|
|
336
352
|
const isLast = idx === chunks.length - 1;
|
|
337
353
|
const joined = joinExternalMessages(message.outputs);
|
|
354
|
+
const hasInterruptedToolCalls =
|
|
355
|
+
typeof joined.content === "object" &&
|
|
356
|
+
joined.content.some(isInterruptedToolCall);
|
|
338
357
|
const hasPendingToolCalls =
|
|
339
358
|
typeof joined.content === "object" &&
|
|
340
|
-
joined.content.some(
|
|
341
|
-
(c) => c.type === "tool-call" && c.result === undefined,
|
|
342
|
-
);
|
|
359
|
+
joined.content.some(isPendingToolCall);
|
|
343
360
|
const autoStatus = getAutoStatus(
|
|
344
361
|
isLast,
|
|
345
362
|
isRunning,
|
|
346
|
-
|
|
363
|
+
hasInterruptedToolCalls,
|
|
347
364
|
hasPendingToolCalls,
|
|
348
365
|
isLast ? metadata.error : undefined,
|
|
349
366
|
);
|
|
@@ -425,20 +442,16 @@ export const useExternalMessageConverter = <T extends WeakKey>({
|
|
|
425
442
|
const isLast = idx === chunks.length - 1;
|
|
426
443
|
|
|
427
444
|
const joined = joinExternalMessages(message.outputs);
|
|
428
|
-
const
|
|
445
|
+
const hasInterruptedToolCalls =
|
|
429
446
|
typeof joined.content === "object" &&
|
|
430
|
-
joined.content.some(
|
|
431
|
-
(c) => c.type === "tool-call" && c.result === undefined,
|
|
432
|
-
);
|
|
447
|
+
joined.content.some(isInterruptedToolCall);
|
|
433
448
|
const hasPendingToolCalls =
|
|
434
449
|
typeof joined.content === "object" &&
|
|
435
|
-
joined.content.some(
|
|
436
|
-
(c) => c.type === "tool-call" && c.result === undefined,
|
|
437
|
-
);
|
|
450
|
+
joined.content.some(isPendingToolCall);
|
|
438
451
|
const autoStatus = getAutoStatus(
|
|
439
452
|
isLast,
|
|
440
453
|
isRunning,
|
|
441
|
-
|
|
454
|
+
hasInterruptedToolCalls,
|
|
442
455
|
hasPendingToolCalls,
|
|
443
456
|
isLast ? state.metadata.error : undefined,
|
|
444
457
|
);
|
|
@@ -71,6 +71,14 @@ export type ToolCallMessagePartProps<
|
|
|
71
71
|
* paused frontend tool execution.
|
|
72
72
|
*/
|
|
73
73
|
resume: (payload: unknown) => void;
|
|
74
|
+
/**
|
|
75
|
+
* Responds to a server-side tool approval gate. Only valid while
|
|
76
|
+
* `approval` is set on the part and `approval.approved === undefined`.
|
|
77
|
+
*/
|
|
78
|
+
respondToApproval: (response: {
|
|
79
|
+
approved: boolean;
|
|
80
|
+
reason?: string;
|
|
81
|
+
}) => void;
|
|
74
82
|
};
|
|
75
83
|
|
|
76
84
|
/** Component used to render a tool-call message part. */
|