@copilotkit/runtime 1.55.0 → 1.55.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/v2/runtime/open-generative-ui-middleware.cjs +1 -1
- package/dist/v2/runtime/open-generative-ui-middleware.cjs.map +1 -1
- package/dist/v2/runtime/open-generative-ui-middleware.mjs +1 -1
- package/dist/v2/runtime/open-generative-ui-middleware.mjs.map +1 -1
- package/package.json +2 -2
- package/src/v2/runtime/open-generative-ui-middleware.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @copilotkit/runtime
|
|
2
2
|
|
|
3
|
+
## 1.55.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e6e8ef8: Fix an incorrect import in open-generative-ui middleware
|
|
8
|
+
- @copilotkit/shared@1.55.1
|
|
9
|
+
|
|
10
|
+
## 1.55.1-next.0
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- e6e8ef8: Fix an incorrect import in open-generative-ui middleware
|
|
15
|
+
- @copilotkit/shared@1.55.1-next.0
|
|
16
|
+
|
|
3
17
|
## 1.55.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/dist/package.cjs
CHANGED
|
@@ -5,7 +5,7 @@ const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
|
5
5
|
var require_package = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
|
|
6
6
|
module.exports = {
|
|
7
7
|
"name": "@copilotkit/runtime",
|
|
8
|
-
"version": "1.55.
|
|
8
|
+
"version": "1.55.1",
|
|
9
9
|
"private": false,
|
|
10
10
|
"keywords": [
|
|
11
11
|
"ai",
|
package/dist/package.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { __commonJSMin } from "./_virtual/_rolldown/runtime.mjs";
|
|
|
5
5
|
var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
6
6
|
module.exports = {
|
|
7
7
|
"name": "@copilotkit/runtime",
|
|
8
|
-
"version": "1.55.
|
|
8
|
+
"version": "1.55.1",
|
|
9
9
|
"private": false,
|
|
10
10
|
"keywords": [
|
|
11
11
|
"ai",
|
|
@@ -24,7 +24,7 @@ var ArgsParser = class {
|
|
|
24
24
|
this.params = {};
|
|
25
25
|
this.messageId = `${toolCallId}-activity`;
|
|
26
26
|
this.onEvent = onEvent;
|
|
27
|
-
this.parser = clarinet.parser();
|
|
27
|
+
this.parser = clarinet.default.parser();
|
|
28
28
|
this.parser.onopenobject = (key) => {
|
|
29
29
|
this.depth++;
|
|
30
30
|
if (key !== void 0 && this.depth === 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-generative-ui-middleware.cjs","names":["EventType","Middleware","Observable"],"sources":["../../../src/v2/runtime/open-generative-ui-middleware.ts"],"sourcesContent":["import {\n Middleware,\n RunAgentInput,\n AbstractAgent,\n BaseEvent,\n EventType,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ActivitySnapshotEvent,\n ActivityDeltaEvent,\n} from \"@ag-ui/client\";\nimport { Observable } from \"rxjs\";\nimport * as clarinet from \"clarinet\";\n\nconst TOOL_NAME = \"generateSandboxedUi\";\nconst ACTIVITY_TYPE = \"open-generative-ui\";\n\n/**\n * Parsed parameters from the generateSandboxedUi tool call.\n */\nexport interface GenerateSandboxedUIParams {\n initialHeight?: number;\n placeholderMessages?: string[];\n css?: string;\n html?: string;\n jsFunctions?: string;\n jsExpressions?: string[];\n}\n\n/**\n * Callback invoked by ArgsParser whenever a parameter (or array item) finishes parsing.\n */\nexport type OnParamEvent = (event: BaseEvent) => void;\n\n/**\n * Tracks incremental JSON parsing state for a single tool call's arguments.\n * Emits activity events via the onEvent callback as parameters complete.\n */\nexport class ArgsParser {\n private parser: ReturnType<typeof clarinet.parser>;\n private currentKey: string | null = null;\n private depth = 0;\n private currentArrayKey: string | null = null;\n private snapshotEmitted = false;\n\n // Streaming html state — reads parser.textNode to emit incremental chunks\n private streamingHtmlKey = false;\n private htmlEmittedLength = 0;\n private htmlArrayEmitted = false;\n\n public readonly params: GenerateSandboxedUIParams = {};\n public readonly messageId: string;\n private readonly onEvent: OnParamEvent;\n\n constructor(toolCallId: string, onEvent: OnParamEvent) {\n this.messageId = `${toolCallId}-activity`;\n this.onEvent = onEvent;\n this.parser = clarinet.parser();\n\n this.parser.onopenobject = (key: string | undefined) => {\n this.depth++;\n if (key !== undefined && this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onkey = (key: string) => {\n if (this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onvalue = (value: string | boolean | number | null) => {\n if (this.depth === 1 && this.currentKey) {\n if (this.currentArrayKey) {\n const strValue = String(value);\n if (this.currentArrayKey === \"jsExpressions\") {\n if (!this.params.jsExpressions) this.params.jsExpressions = [];\n this.params.jsExpressions.push(strValue);\n } else if (this.currentArrayKey === \"placeholderMessages\") {\n if (!this.params.placeholderMessages)\n this.params.placeholderMessages = [];\n this.params.placeholderMessages.push(strValue);\n }\n this.emitArrayItemDelta(this.currentArrayKey, strValue);\n } else if (this.streamingHtmlKey) {\n // HTML string completed — flush any remaining content immediately + htmlComplete\n const fullHtml = value != null ? String(value) : \"\";\n this.params.html = fullHtml || undefined;\n this.emitPendingHtml(fullHtml);\n this.emitParamDelta(\"htmlComplete\", true);\n this.streamingHtmlKey = false;\n } else {\n this.setParam(this.currentKey, value);\n }\n }\n };\n\n this.parser.onopenarray = () => {\n if (this.depth === 1 && this.currentKey) {\n const key = this.currentKey;\n if (key === \"jsExpressions\" || key === \"placeholderMessages\") {\n this.currentArrayKey = key;\n if (key === \"jsExpressions\") this.params.jsExpressions = [];\n else this.params.placeholderMessages = [];\n // Emit a delta to create the array in the activity content.\n // Subsequent \"add\" ops with path \"/<key>/-\" append to this array.\n this.emitParamDelta(key, []);\n }\n }\n };\n\n this.parser.onclosearray = () => {\n if (this.depth === 1) {\n if (this.currentArrayKey === \"jsExpressions\") {\n this.emitParamDelta(\"jsExpressionsComplete\", true);\n }\n this.currentArrayKey = null;\n }\n };\n\n this.parser.oncloseobject = () => {\n this.depth--;\n };\n\n this.parser.onerror = (err: Error) => {\n console.warn(\n \"[OpenGenerativeUI] JSON parse error in streaming args, resuming:\",\n err?.message ?? err,\n );\n // Reset error state so parsing can continue with the next chunk\n this.parser.error = null;\n this.parser.resume();\n };\n }\n\n write(chunk: string): void {\n this.parser.write(chunk);\n this.flushHtmlChunks();\n }\n\n private initHtmlStreaming(key: string): void {\n if (key === \"html\") {\n this.streamingHtmlKey = true;\n this.htmlEmittedLength = 0;\n this.htmlArrayEmitted = false;\n }\n }\n\n /**\n * Read clarinet's internal textNode buffer to emit html chunks incrementally.\n * Called after every write() so partial string content is emitted as it streams in.\n */\n private flushHtmlChunks(): void {\n if (!this.streamingHtmlKey) return;\n const textNode = (this.parser as any).textNode;\n if (typeof textNode !== \"string\") return;\n if (textNode.length === this.htmlEmittedLength) return;\n\n this.emitPendingHtml(textNode);\n }\n\n /**\n * Emit accumulated html content since the last emission.\n * Called by flushHtmlChunks and directly when html completes.\n */\n private emitPendingHtml(textNode: string): void {\n const newContent = textNode.slice(this.htmlEmittedLength);\n if (newContent.length === 0) return;\n\n if (!this.htmlArrayEmitted) {\n this.htmlArrayEmitted = true;\n this.emitParamDelta(\"html\", []);\n }\n this.emitArrayItemDelta(\"html\", newContent);\n this.htmlEmittedLength = textNode.length;\n }\n\n private setParam(key: string, value: string | boolean | number | null): void {\n switch (key) {\n case \"initialHeight\":\n this.params.initialHeight =\n typeof value === \"number\" ? value : undefined;\n this.emitSnapshot();\n break;\n case \"css\":\n this.params.css = value != null ? String(value) : undefined;\n this.emitParamDelta(\"css\", this.params.css);\n this.emitParamDelta(\"cssComplete\", true);\n break;\n case \"jsFunctions\":\n this.params.jsFunctions = value != null ? String(value) : undefined;\n this.emitParamDelta(\"jsFunctions\", this.params.jsFunctions);\n this.emitParamDelta(\"jsFunctionsComplete\", true);\n break;\n }\n }\n\n private emitSnapshot(): void {\n if (this.snapshotEmitted) return;\n this.snapshotEmitted = true;\n\n const event: ActivitySnapshotEvent = {\n type: EventType.ACTIVITY_SNAPSHOT,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n content: { initialHeight: this.params.initialHeight, generating: true },\n };\n this.onEvent(event);\n }\n\n private emitParamDelta(key: string, value: unknown): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${key}`, value }],\n };\n this.onEvent(event);\n }\n\n private emitArrayItemDelta(arrayKey: string, value: string): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${arrayKey}/-`, value }],\n };\n this.onEvent(event);\n }\n}\n\n/**\n * Extract EventWithState type from Middleware.runNextWithState return type\n */\ntype ExtractObservableType<T> = T extends Observable<infer U> ? U : never;\ntype RunNextWithStateReturn = ReturnType<Middleware[\"runNextWithState\"]>;\ntype EventWithState = ExtractObservableType<RunNextWithStateReturn>;\n\nexport class OpenGenerativeUIMiddleware extends Middleware {\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return this.processStream(this.runNextWithState(input, next));\n }\n\n private processStream(\n source: Observable<EventWithState>,\n ): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n let heldRunFinished: EventWithState | null = null;\n // Track active generateSandboxedUi tool call IDs → their streaming parser\n const activeParsers = new Map<string, ArgsParser>();\n // Hold genui tool call events until the first activity event is emitted\n const heldToolCallEvents = new Map<string, BaseEvent[]>();\n const flushedToolCalls = new Set<string>();\n\n const flushHeldEvents = (toolCallId: string) => {\n if (flushedToolCalls.has(toolCallId)) return;\n flushedToolCalls.add(toolCallId);\n const held = heldToolCallEvents.get(toolCallId);\n if (held) {\n for (const e of held) {\n subscriber.next(e);\n }\n heldToolCallEvents.delete(toolCallId);\n }\n };\n\n const subscription = source.subscribe({\n next: (eventWithState) => {\n const event = eventWithState.event;\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n\n if (event.type === EventType.RUN_FINISHED) {\n heldRunFinished = eventWithState;\n return;\n }\n\n // Hold TOOL_CALL_START for genui until the first activity event\n if (event.type === EventType.TOOL_CALL_START) {\n const startEvent = event as ToolCallStartEvent;\n if (startEvent.toolCallName === TOOL_NAME) {\n heldToolCallEvents.set(startEvent.toolCallId, [event]);\n activeParsers.set(\n startEvent.toolCallId,\n new ArgsParser(startEvent.toolCallId, (activityEvent) => {\n subscriber.next(activityEvent);\n flushHeldEvents(startEvent.toolCallId);\n }),\n );\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_ARGS for genui tool calls\n if (event.type === EventType.TOOL_CALL_ARGS) {\n const argsEvent = event as ToolCallArgsEvent;\n const parser = activeParsers.get(argsEvent.toolCallId);\n if (parser) {\n if (!flushedToolCalls.has(argsEvent.toolCallId)) {\n heldToolCallEvents.get(argsEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n parser.write(argsEvent.delta);\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_END for genui tool calls\n if (event.type === EventType.TOOL_CALL_END) {\n const endEvent = event as { toolCallId: string } & BaseEvent;\n const parser = activeParsers.get(endEvent.toolCallId);\n if (parser) {\n // Mark generation complete\n const completeEvent: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: parser.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: \"/generating\", value: false }],\n };\n subscriber.next(completeEvent);\n\n if (!flushedToolCalls.has(endEvent.toolCallId)) {\n heldToolCallEvents.get(endEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n return;\n }\n }\n\n subscriber.next(event);\n },\n error: (err) => {\n // Flush any held tool call events so downstream sees them before the error\n for (const [, events] of heldToolCallEvents) {\n for (const event of events) {\n subscriber.next(event);\n }\n }\n heldToolCallEvents.clear();\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n subscriber.error(err);\n },\n complete: () => {\n // Flush any remaining held tool call events (e.g. parser never emitted)\n heldToolCallEvents.forEach((_, toolCallId) => {\n flushHeldEvents(toolCallId);\n });\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n activeParsers.clear();\n subscriber.complete();\n },\n });\n\n return () => subscription.unsubscribe();\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"open-generative-ui-middleware.cjs","names":["EventType","Middleware","Observable"],"sources":["../../../src/v2/runtime/open-generative-ui-middleware.ts"],"sourcesContent":["import {\n Middleware,\n RunAgentInput,\n AbstractAgent,\n BaseEvent,\n EventType,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ActivitySnapshotEvent,\n ActivityDeltaEvent,\n} from \"@ag-ui/client\";\nimport { Observable } from \"rxjs\";\nimport clarinet from \"clarinet\";\n\nconst TOOL_NAME = \"generateSandboxedUi\";\nconst ACTIVITY_TYPE = \"open-generative-ui\";\n\n/**\n * Parsed parameters from the generateSandboxedUi tool call.\n */\nexport interface GenerateSandboxedUIParams {\n initialHeight?: number;\n placeholderMessages?: string[];\n css?: string;\n html?: string;\n jsFunctions?: string;\n jsExpressions?: string[];\n}\n\n/**\n * Callback invoked by ArgsParser whenever a parameter (or array item) finishes parsing.\n */\nexport type OnParamEvent = (event: BaseEvent) => void;\n\n/**\n * Tracks incremental JSON parsing state for a single tool call's arguments.\n * Emits activity events via the onEvent callback as parameters complete.\n */\nexport class ArgsParser {\n private parser: ReturnType<typeof clarinet.parser>;\n private currentKey: string | null = null;\n private depth = 0;\n private currentArrayKey: string | null = null;\n private snapshotEmitted = false;\n\n // Streaming html state — reads parser.textNode to emit incremental chunks\n private streamingHtmlKey = false;\n private htmlEmittedLength = 0;\n private htmlArrayEmitted = false;\n\n public readonly params: GenerateSandboxedUIParams = {};\n public readonly messageId: string;\n private readonly onEvent: OnParamEvent;\n\n constructor(toolCallId: string, onEvent: OnParamEvent) {\n this.messageId = `${toolCallId}-activity`;\n this.onEvent = onEvent;\n this.parser = clarinet.parser();\n\n this.parser.onopenobject = (key: string | undefined) => {\n this.depth++;\n if (key !== undefined && this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onkey = (key: string) => {\n if (this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onvalue = (value: string | boolean | number | null) => {\n if (this.depth === 1 && this.currentKey) {\n if (this.currentArrayKey) {\n const strValue = String(value);\n if (this.currentArrayKey === \"jsExpressions\") {\n if (!this.params.jsExpressions) this.params.jsExpressions = [];\n this.params.jsExpressions.push(strValue);\n } else if (this.currentArrayKey === \"placeholderMessages\") {\n if (!this.params.placeholderMessages)\n this.params.placeholderMessages = [];\n this.params.placeholderMessages.push(strValue);\n }\n this.emitArrayItemDelta(this.currentArrayKey, strValue);\n } else if (this.streamingHtmlKey) {\n // HTML string completed — flush any remaining content immediately + htmlComplete\n const fullHtml = value != null ? String(value) : \"\";\n this.params.html = fullHtml || undefined;\n this.emitPendingHtml(fullHtml);\n this.emitParamDelta(\"htmlComplete\", true);\n this.streamingHtmlKey = false;\n } else {\n this.setParam(this.currentKey, value);\n }\n }\n };\n\n this.parser.onopenarray = () => {\n if (this.depth === 1 && this.currentKey) {\n const key = this.currentKey;\n if (key === \"jsExpressions\" || key === \"placeholderMessages\") {\n this.currentArrayKey = key;\n if (key === \"jsExpressions\") this.params.jsExpressions = [];\n else this.params.placeholderMessages = [];\n // Emit a delta to create the array in the activity content.\n // Subsequent \"add\" ops with path \"/<key>/-\" append to this array.\n this.emitParamDelta(key, []);\n }\n }\n };\n\n this.parser.onclosearray = () => {\n if (this.depth === 1) {\n if (this.currentArrayKey === \"jsExpressions\") {\n this.emitParamDelta(\"jsExpressionsComplete\", true);\n }\n this.currentArrayKey = null;\n }\n };\n\n this.parser.oncloseobject = () => {\n this.depth--;\n };\n\n this.parser.onerror = (err: Error) => {\n console.warn(\n \"[OpenGenerativeUI] JSON parse error in streaming args, resuming:\",\n err?.message ?? err,\n );\n // Reset error state so parsing can continue with the next chunk\n this.parser.error = null;\n this.parser.resume();\n };\n }\n\n write(chunk: string): void {\n this.parser.write(chunk);\n this.flushHtmlChunks();\n }\n\n private initHtmlStreaming(key: string): void {\n if (key === \"html\") {\n this.streamingHtmlKey = true;\n this.htmlEmittedLength = 0;\n this.htmlArrayEmitted = false;\n }\n }\n\n /**\n * Read clarinet's internal textNode buffer to emit html chunks incrementally.\n * Called after every write() so partial string content is emitted as it streams in.\n */\n private flushHtmlChunks(): void {\n if (!this.streamingHtmlKey) return;\n const textNode = (this.parser as any).textNode;\n if (typeof textNode !== \"string\") return;\n if (textNode.length === this.htmlEmittedLength) return;\n\n this.emitPendingHtml(textNode);\n }\n\n /**\n * Emit accumulated html content since the last emission.\n * Called by flushHtmlChunks and directly when html completes.\n */\n private emitPendingHtml(textNode: string): void {\n const newContent = textNode.slice(this.htmlEmittedLength);\n if (newContent.length === 0) return;\n\n if (!this.htmlArrayEmitted) {\n this.htmlArrayEmitted = true;\n this.emitParamDelta(\"html\", []);\n }\n this.emitArrayItemDelta(\"html\", newContent);\n this.htmlEmittedLength = textNode.length;\n }\n\n private setParam(key: string, value: string | boolean | number | null): void {\n switch (key) {\n case \"initialHeight\":\n this.params.initialHeight =\n typeof value === \"number\" ? value : undefined;\n this.emitSnapshot();\n break;\n case \"css\":\n this.params.css = value != null ? String(value) : undefined;\n this.emitParamDelta(\"css\", this.params.css);\n this.emitParamDelta(\"cssComplete\", true);\n break;\n case \"jsFunctions\":\n this.params.jsFunctions = value != null ? String(value) : undefined;\n this.emitParamDelta(\"jsFunctions\", this.params.jsFunctions);\n this.emitParamDelta(\"jsFunctionsComplete\", true);\n break;\n }\n }\n\n private emitSnapshot(): void {\n if (this.snapshotEmitted) return;\n this.snapshotEmitted = true;\n\n const event: ActivitySnapshotEvent = {\n type: EventType.ACTIVITY_SNAPSHOT,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n content: { initialHeight: this.params.initialHeight, generating: true },\n };\n this.onEvent(event);\n }\n\n private emitParamDelta(key: string, value: unknown): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${key}`, value }],\n };\n this.onEvent(event);\n }\n\n private emitArrayItemDelta(arrayKey: string, value: string): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${arrayKey}/-`, value }],\n };\n this.onEvent(event);\n }\n}\n\n/**\n * Extract EventWithState type from Middleware.runNextWithState return type\n */\ntype ExtractObservableType<T> = T extends Observable<infer U> ? U : never;\ntype RunNextWithStateReturn = ReturnType<Middleware[\"runNextWithState\"]>;\ntype EventWithState = ExtractObservableType<RunNextWithStateReturn>;\n\nexport class OpenGenerativeUIMiddleware extends Middleware {\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return this.processStream(this.runNextWithState(input, next));\n }\n\n private processStream(\n source: Observable<EventWithState>,\n ): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n let heldRunFinished: EventWithState | null = null;\n // Track active generateSandboxedUi tool call IDs → their streaming parser\n const activeParsers = new Map<string, ArgsParser>();\n // Hold genui tool call events until the first activity event is emitted\n const heldToolCallEvents = new Map<string, BaseEvent[]>();\n const flushedToolCalls = new Set<string>();\n\n const flushHeldEvents = (toolCallId: string) => {\n if (flushedToolCalls.has(toolCallId)) return;\n flushedToolCalls.add(toolCallId);\n const held = heldToolCallEvents.get(toolCallId);\n if (held) {\n for (const e of held) {\n subscriber.next(e);\n }\n heldToolCallEvents.delete(toolCallId);\n }\n };\n\n const subscription = source.subscribe({\n next: (eventWithState) => {\n const event = eventWithState.event;\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n\n if (event.type === EventType.RUN_FINISHED) {\n heldRunFinished = eventWithState;\n return;\n }\n\n // Hold TOOL_CALL_START for genui until the first activity event\n if (event.type === EventType.TOOL_CALL_START) {\n const startEvent = event as ToolCallStartEvent;\n if (startEvent.toolCallName === TOOL_NAME) {\n heldToolCallEvents.set(startEvent.toolCallId, [event]);\n activeParsers.set(\n startEvent.toolCallId,\n new ArgsParser(startEvent.toolCallId, (activityEvent) => {\n subscriber.next(activityEvent);\n flushHeldEvents(startEvent.toolCallId);\n }),\n );\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_ARGS for genui tool calls\n if (event.type === EventType.TOOL_CALL_ARGS) {\n const argsEvent = event as ToolCallArgsEvent;\n const parser = activeParsers.get(argsEvent.toolCallId);\n if (parser) {\n if (!flushedToolCalls.has(argsEvent.toolCallId)) {\n heldToolCallEvents.get(argsEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n parser.write(argsEvent.delta);\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_END for genui tool calls\n if (event.type === EventType.TOOL_CALL_END) {\n const endEvent = event as { toolCallId: string } & BaseEvent;\n const parser = activeParsers.get(endEvent.toolCallId);\n if (parser) {\n // Mark generation complete\n const completeEvent: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: parser.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: \"/generating\", value: false }],\n };\n subscriber.next(completeEvent);\n\n if (!flushedToolCalls.has(endEvent.toolCallId)) {\n heldToolCallEvents.get(endEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n return;\n }\n }\n\n subscriber.next(event);\n },\n error: (err) => {\n // Flush any held tool call events so downstream sees them before the error\n for (const [, events] of heldToolCallEvents) {\n for (const event of events) {\n subscriber.next(event);\n }\n }\n heldToolCallEvents.clear();\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n subscriber.error(err);\n },\n complete: () => {\n // Flush any remaining held tool call events (e.g. parser never emitted)\n heldToolCallEvents.forEach((_, toolCallId) => {\n flushHeldEvents(toolCallId);\n });\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n activeParsers.clear();\n subscriber.complete();\n },\n });\n\n return () => subscription.unsubscribe();\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import { Observable } from "rxjs";
|
|
3
3
|
import { EventType, Middleware } from "@ag-ui/client";
|
|
4
|
-
import
|
|
4
|
+
import clarinet from "clarinet";
|
|
5
5
|
|
|
6
6
|
//#region src/v2/runtime/open-generative-ui-middleware.ts
|
|
7
7
|
const TOOL_NAME = "generateSandboxedUi";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-generative-ui-middleware.mjs","names":[],"sources":["../../../src/v2/runtime/open-generative-ui-middleware.ts"],"sourcesContent":["import {\n Middleware,\n RunAgentInput,\n AbstractAgent,\n BaseEvent,\n EventType,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ActivitySnapshotEvent,\n ActivityDeltaEvent,\n} from \"@ag-ui/client\";\nimport { Observable } from \"rxjs\";\nimport * as clarinet from \"clarinet\";\n\nconst TOOL_NAME = \"generateSandboxedUi\";\nconst ACTIVITY_TYPE = \"open-generative-ui\";\n\n/**\n * Parsed parameters from the generateSandboxedUi tool call.\n */\nexport interface GenerateSandboxedUIParams {\n initialHeight?: number;\n placeholderMessages?: string[];\n css?: string;\n html?: string;\n jsFunctions?: string;\n jsExpressions?: string[];\n}\n\n/**\n * Callback invoked by ArgsParser whenever a parameter (or array item) finishes parsing.\n */\nexport type OnParamEvent = (event: BaseEvent) => void;\n\n/**\n * Tracks incremental JSON parsing state for a single tool call's arguments.\n * Emits activity events via the onEvent callback as parameters complete.\n */\nexport class ArgsParser {\n private parser: ReturnType<typeof clarinet.parser>;\n private currentKey: string | null = null;\n private depth = 0;\n private currentArrayKey: string | null = null;\n private snapshotEmitted = false;\n\n // Streaming html state — reads parser.textNode to emit incremental chunks\n private streamingHtmlKey = false;\n private htmlEmittedLength = 0;\n private htmlArrayEmitted = false;\n\n public readonly params: GenerateSandboxedUIParams = {};\n public readonly messageId: string;\n private readonly onEvent: OnParamEvent;\n\n constructor(toolCallId: string, onEvent: OnParamEvent) {\n this.messageId = `${toolCallId}-activity`;\n this.onEvent = onEvent;\n this.parser = clarinet.parser();\n\n this.parser.onopenobject = (key: string | undefined) => {\n this.depth++;\n if (key !== undefined && this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onkey = (key: string) => {\n if (this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onvalue = (value: string | boolean | number | null) => {\n if (this.depth === 1 && this.currentKey) {\n if (this.currentArrayKey) {\n const strValue = String(value);\n if (this.currentArrayKey === \"jsExpressions\") {\n if (!this.params.jsExpressions) this.params.jsExpressions = [];\n this.params.jsExpressions.push(strValue);\n } else if (this.currentArrayKey === \"placeholderMessages\") {\n if (!this.params.placeholderMessages)\n this.params.placeholderMessages = [];\n this.params.placeholderMessages.push(strValue);\n }\n this.emitArrayItemDelta(this.currentArrayKey, strValue);\n } else if (this.streamingHtmlKey) {\n // HTML string completed — flush any remaining content immediately + htmlComplete\n const fullHtml = value != null ? String(value) : \"\";\n this.params.html = fullHtml || undefined;\n this.emitPendingHtml(fullHtml);\n this.emitParamDelta(\"htmlComplete\", true);\n this.streamingHtmlKey = false;\n } else {\n this.setParam(this.currentKey, value);\n }\n }\n };\n\n this.parser.onopenarray = () => {\n if (this.depth === 1 && this.currentKey) {\n const key = this.currentKey;\n if (key === \"jsExpressions\" || key === \"placeholderMessages\") {\n this.currentArrayKey = key;\n if (key === \"jsExpressions\") this.params.jsExpressions = [];\n else this.params.placeholderMessages = [];\n // Emit a delta to create the array in the activity content.\n // Subsequent \"add\" ops with path \"/<key>/-\" append to this array.\n this.emitParamDelta(key, []);\n }\n }\n };\n\n this.parser.onclosearray = () => {\n if (this.depth === 1) {\n if (this.currentArrayKey === \"jsExpressions\") {\n this.emitParamDelta(\"jsExpressionsComplete\", true);\n }\n this.currentArrayKey = null;\n }\n };\n\n this.parser.oncloseobject = () => {\n this.depth--;\n };\n\n this.parser.onerror = (err: Error) => {\n console.warn(\n \"[OpenGenerativeUI] JSON parse error in streaming args, resuming:\",\n err?.message ?? err,\n );\n // Reset error state so parsing can continue with the next chunk\n this.parser.error = null;\n this.parser.resume();\n };\n }\n\n write(chunk: string): void {\n this.parser.write(chunk);\n this.flushHtmlChunks();\n }\n\n private initHtmlStreaming(key: string): void {\n if (key === \"html\") {\n this.streamingHtmlKey = true;\n this.htmlEmittedLength = 0;\n this.htmlArrayEmitted = false;\n }\n }\n\n /**\n * Read clarinet's internal textNode buffer to emit html chunks incrementally.\n * Called after every write() so partial string content is emitted as it streams in.\n */\n private flushHtmlChunks(): void {\n if (!this.streamingHtmlKey) return;\n const textNode = (this.parser as any).textNode;\n if (typeof textNode !== \"string\") return;\n if (textNode.length === this.htmlEmittedLength) return;\n\n this.emitPendingHtml(textNode);\n }\n\n /**\n * Emit accumulated html content since the last emission.\n * Called by flushHtmlChunks and directly when html completes.\n */\n private emitPendingHtml(textNode: string): void {\n const newContent = textNode.slice(this.htmlEmittedLength);\n if (newContent.length === 0) return;\n\n if (!this.htmlArrayEmitted) {\n this.htmlArrayEmitted = true;\n this.emitParamDelta(\"html\", []);\n }\n this.emitArrayItemDelta(\"html\", newContent);\n this.htmlEmittedLength = textNode.length;\n }\n\n private setParam(key: string, value: string | boolean | number | null): void {\n switch (key) {\n case \"initialHeight\":\n this.params.initialHeight =\n typeof value === \"number\" ? value : undefined;\n this.emitSnapshot();\n break;\n case \"css\":\n this.params.css = value != null ? String(value) : undefined;\n this.emitParamDelta(\"css\", this.params.css);\n this.emitParamDelta(\"cssComplete\", true);\n break;\n case \"jsFunctions\":\n this.params.jsFunctions = value != null ? String(value) : undefined;\n this.emitParamDelta(\"jsFunctions\", this.params.jsFunctions);\n this.emitParamDelta(\"jsFunctionsComplete\", true);\n break;\n }\n }\n\n private emitSnapshot(): void {\n if (this.snapshotEmitted) return;\n this.snapshotEmitted = true;\n\n const event: ActivitySnapshotEvent = {\n type: EventType.ACTIVITY_SNAPSHOT,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n content: { initialHeight: this.params.initialHeight, generating: true },\n };\n this.onEvent(event);\n }\n\n private emitParamDelta(key: string, value: unknown): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${key}`, value }],\n };\n this.onEvent(event);\n }\n\n private emitArrayItemDelta(arrayKey: string, value: string): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${arrayKey}/-`, value }],\n };\n this.onEvent(event);\n }\n}\n\n/**\n * Extract EventWithState type from Middleware.runNextWithState return type\n */\ntype ExtractObservableType<T> = T extends Observable<infer U> ? U : never;\ntype RunNextWithStateReturn = ReturnType<Middleware[\"runNextWithState\"]>;\ntype EventWithState = ExtractObservableType<RunNextWithStateReturn>;\n\nexport class OpenGenerativeUIMiddleware extends Middleware {\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return this.processStream(this.runNextWithState(input, next));\n }\n\n private processStream(\n source: Observable<EventWithState>,\n ): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n let heldRunFinished: EventWithState | null = null;\n // Track active generateSandboxedUi tool call IDs → their streaming parser\n const activeParsers = new Map<string, ArgsParser>();\n // Hold genui tool call events until the first activity event is emitted\n const heldToolCallEvents = new Map<string, BaseEvent[]>();\n const flushedToolCalls = new Set<string>();\n\n const flushHeldEvents = (toolCallId: string) => {\n if (flushedToolCalls.has(toolCallId)) return;\n flushedToolCalls.add(toolCallId);\n const held = heldToolCallEvents.get(toolCallId);\n if (held) {\n for (const e of held) {\n subscriber.next(e);\n }\n heldToolCallEvents.delete(toolCallId);\n }\n };\n\n const subscription = source.subscribe({\n next: (eventWithState) => {\n const event = eventWithState.event;\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n\n if (event.type === EventType.RUN_FINISHED) {\n heldRunFinished = eventWithState;\n return;\n }\n\n // Hold TOOL_CALL_START for genui until the first activity event\n if (event.type === EventType.TOOL_CALL_START) {\n const startEvent = event as ToolCallStartEvent;\n if (startEvent.toolCallName === TOOL_NAME) {\n heldToolCallEvents.set(startEvent.toolCallId, [event]);\n activeParsers.set(\n startEvent.toolCallId,\n new ArgsParser(startEvent.toolCallId, (activityEvent) => {\n subscriber.next(activityEvent);\n flushHeldEvents(startEvent.toolCallId);\n }),\n );\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_ARGS for genui tool calls\n if (event.type === EventType.TOOL_CALL_ARGS) {\n const argsEvent = event as ToolCallArgsEvent;\n const parser = activeParsers.get(argsEvent.toolCallId);\n if (parser) {\n if (!flushedToolCalls.has(argsEvent.toolCallId)) {\n heldToolCallEvents.get(argsEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n parser.write(argsEvent.delta);\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_END for genui tool calls\n if (event.type === EventType.TOOL_CALL_END) {\n const endEvent = event as { toolCallId: string } & BaseEvent;\n const parser = activeParsers.get(endEvent.toolCallId);\n if (parser) {\n // Mark generation complete\n const completeEvent: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: parser.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: \"/generating\", value: false }],\n };\n subscriber.next(completeEvent);\n\n if (!flushedToolCalls.has(endEvent.toolCallId)) {\n heldToolCallEvents.get(endEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n return;\n }\n }\n\n subscriber.next(event);\n },\n error: (err) => {\n // Flush any held tool call events so downstream sees them before the error\n for (const [, events] of heldToolCallEvents) {\n for (const event of events) {\n subscriber.next(event);\n }\n }\n heldToolCallEvents.clear();\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n subscriber.error(err);\n },\n complete: () => {\n // Flush any remaining held tool call events (e.g. parser never emitted)\n heldToolCallEvents.forEach((_, toolCallId) => {\n flushHeldEvents(toolCallId);\n });\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n activeParsers.clear();\n subscriber.complete();\n },\n });\n\n return () => subscription.unsubscribe();\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"open-generative-ui-middleware.mjs","names":[],"sources":["../../../src/v2/runtime/open-generative-ui-middleware.ts"],"sourcesContent":["import {\n Middleware,\n RunAgentInput,\n AbstractAgent,\n BaseEvent,\n EventType,\n ToolCallStartEvent,\n ToolCallArgsEvent,\n ActivitySnapshotEvent,\n ActivityDeltaEvent,\n} from \"@ag-ui/client\";\nimport { Observable } from \"rxjs\";\nimport clarinet from \"clarinet\";\n\nconst TOOL_NAME = \"generateSandboxedUi\";\nconst ACTIVITY_TYPE = \"open-generative-ui\";\n\n/**\n * Parsed parameters from the generateSandboxedUi tool call.\n */\nexport interface GenerateSandboxedUIParams {\n initialHeight?: number;\n placeholderMessages?: string[];\n css?: string;\n html?: string;\n jsFunctions?: string;\n jsExpressions?: string[];\n}\n\n/**\n * Callback invoked by ArgsParser whenever a parameter (or array item) finishes parsing.\n */\nexport type OnParamEvent = (event: BaseEvent) => void;\n\n/**\n * Tracks incremental JSON parsing state for a single tool call's arguments.\n * Emits activity events via the onEvent callback as parameters complete.\n */\nexport class ArgsParser {\n private parser: ReturnType<typeof clarinet.parser>;\n private currentKey: string | null = null;\n private depth = 0;\n private currentArrayKey: string | null = null;\n private snapshotEmitted = false;\n\n // Streaming html state — reads parser.textNode to emit incremental chunks\n private streamingHtmlKey = false;\n private htmlEmittedLength = 0;\n private htmlArrayEmitted = false;\n\n public readonly params: GenerateSandboxedUIParams = {};\n public readonly messageId: string;\n private readonly onEvent: OnParamEvent;\n\n constructor(toolCallId: string, onEvent: OnParamEvent) {\n this.messageId = `${toolCallId}-activity`;\n this.onEvent = onEvent;\n this.parser = clarinet.parser();\n\n this.parser.onopenobject = (key: string | undefined) => {\n this.depth++;\n if (key !== undefined && this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onkey = (key: string) => {\n if (this.depth === 1) {\n this.currentKey = key;\n this.initHtmlStreaming(key);\n }\n };\n\n this.parser.onvalue = (value: string | boolean | number | null) => {\n if (this.depth === 1 && this.currentKey) {\n if (this.currentArrayKey) {\n const strValue = String(value);\n if (this.currentArrayKey === \"jsExpressions\") {\n if (!this.params.jsExpressions) this.params.jsExpressions = [];\n this.params.jsExpressions.push(strValue);\n } else if (this.currentArrayKey === \"placeholderMessages\") {\n if (!this.params.placeholderMessages)\n this.params.placeholderMessages = [];\n this.params.placeholderMessages.push(strValue);\n }\n this.emitArrayItemDelta(this.currentArrayKey, strValue);\n } else if (this.streamingHtmlKey) {\n // HTML string completed — flush any remaining content immediately + htmlComplete\n const fullHtml = value != null ? String(value) : \"\";\n this.params.html = fullHtml || undefined;\n this.emitPendingHtml(fullHtml);\n this.emitParamDelta(\"htmlComplete\", true);\n this.streamingHtmlKey = false;\n } else {\n this.setParam(this.currentKey, value);\n }\n }\n };\n\n this.parser.onopenarray = () => {\n if (this.depth === 1 && this.currentKey) {\n const key = this.currentKey;\n if (key === \"jsExpressions\" || key === \"placeholderMessages\") {\n this.currentArrayKey = key;\n if (key === \"jsExpressions\") this.params.jsExpressions = [];\n else this.params.placeholderMessages = [];\n // Emit a delta to create the array in the activity content.\n // Subsequent \"add\" ops with path \"/<key>/-\" append to this array.\n this.emitParamDelta(key, []);\n }\n }\n };\n\n this.parser.onclosearray = () => {\n if (this.depth === 1) {\n if (this.currentArrayKey === \"jsExpressions\") {\n this.emitParamDelta(\"jsExpressionsComplete\", true);\n }\n this.currentArrayKey = null;\n }\n };\n\n this.parser.oncloseobject = () => {\n this.depth--;\n };\n\n this.parser.onerror = (err: Error) => {\n console.warn(\n \"[OpenGenerativeUI] JSON parse error in streaming args, resuming:\",\n err?.message ?? err,\n );\n // Reset error state so parsing can continue with the next chunk\n this.parser.error = null;\n this.parser.resume();\n };\n }\n\n write(chunk: string): void {\n this.parser.write(chunk);\n this.flushHtmlChunks();\n }\n\n private initHtmlStreaming(key: string): void {\n if (key === \"html\") {\n this.streamingHtmlKey = true;\n this.htmlEmittedLength = 0;\n this.htmlArrayEmitted = false;\n }\n }\n\n /**\n * Read clarinet's internal textNode buffer to emit html chunks incrementally.\n * Called after every write() so partial string content is emitted as it streams in.\n */\n private flushHtmlChunks(): void {\n if (!this.streamingHtmlKey) return;\n const textNode = (this.parser as any).textNode;\n if (typeof textNode !== \"string\") return;\n if (textNode.length === this.htmlEmittedLength) return;\n\n this.emitPendingHtml(textNode);\n }\n\n /**\n * Emit accumulated html content since the last emission.\n * Called by flushHtmlChunks and directly when html completes.\n */\n private emitPendingHtml(textNode: string): void {\n const newContent = textNode.slice(this.htmlEmittedLength);\n if (newContent.length === 0) return;\n\n if (!this.htmlArrayEmitted) {\n this.htmlArrayEmitted = true;\n this.emitParamDelta(\"html\", []);\n }\n this.emitArrayItemDelta(\"html\", newContent);\n this.htmlEmittedLength = textNode.length;\n }\n\n private setParam(key: string, value: string | boolean | number | null): void {\n switch (key) {\n case \"initialHeight\":\n this.params.initialHeight =\n typeof value === \"number\" ? value : undefined;\n this.emitSnapshot();\n break;\n case \"css\":\n this.params.css = value != null ? String(value) : undefined;\n this.emitParamDelta(\"css\", this.params.css);\n this.emitParamDelta(\"cssComplete\", true);\n break;\n case \"jsFunctions\":\n this.params.jsFunctions = value != null ? String(value) : undefined;\n this.emitParamDelta(\"jsFunctions\", this.params.jsFunctions);\n this.emitParamDelta(\"jsFunctionsComplete\", true);\n break;\n }\n }\n\n private emitSnapshot(): void {\n if (this.snapshotEmitted) return;\n this.snapshotEmitted = true;\n\n const event: ActivitySnapshotEvent = {\n type: EventType.ACTIVITY_SNAPSHOT,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n content: { initialHeight: this.params.initialHeight, generating: true },\n };\n this.onEvent(event);\n }\n\n private emitParamDelta(key: string, value: unknown): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${key}`, value }],\n };\n this.onEvent(event);\n }\n\n private emitArrayItemDelta(arrayKey: string, value: string): void {\n const event: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: this.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: `/${arrayKey}/-`, value }],\n };\n this.onEvent(event);\n }\n}\n\n/**\n * Extract EventWithState type from Middleware.runNextWithState return type\n */\ntype ExtractObservableType<T> = T extends Observable<infer U> ? U : never;\ntype RunNextWithStateReturn = ReturnType<Middleware[\"runNextWithState\"]>;\ntype EventWithState = ExtractObservableType<RunNextWithStateReturn>;\n\nexport class OpenGenerativeUIMiddleware extends Middleware {\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n return this.processStream(this.runNextWithState(input, next));\n }\n\n private processStream(\n source: Observable<EventWithState>,\n ): Observable<BaseEvent> {\n return new Observable<BaseEvent>((subscriber) => {\n let heldRunFinished: EventWithState | null = null;\n // Track active generateSandboxedUi tool call IDs → their streaming parser\n const activeParsers = new Map<string, ArgsParser>();\n // Hold genui tool call events until the first activity event is emitted\n const heldToolCallEvents = new Map<string, BaseEvent[]>();\n const flushedToolCalls = new Set<string>();\n\n const flushHeldEvents = (toolCallId: string) => {\n if (flushedToolCalls.has(toolCallId)) return;\n flushedToolCalls.add(toolCallId);\n const held = heldToolCallEvents.get(toolCallId);\n if (held) {\n for (const e of held) {\n subscriber.next(e);\n }\n heldToolCallEvents.delete(toolCallId);\n }\n };\n\n const subscription = source.subscribe({\n next: (eventWithState) => {\n const event = eventWithState.event;\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n\n if (event.type === EventType.RUN_FINISHED) {\n heldRunFinished = eventWithState;\n return;\n }\n\n // Hold TOOL_CALL_START for genui until the first activity event\n if (event.type === EventType.TOOL_CALL_START) {\n const startEvent = event as ToolCallStartEvent;\n if (startEvent.toolCallName === TOOL_NAME) {\n heldToolCallEvents.set(startEvent.toolCallId, [event]);\n activeParsers.set(\n startEvent.toolCallId,\n new ArgsParser(startEvent.toolCallId, (activityEvent) => {\n subscriber.next(activityEvent);\n flushHeldEvents(startEvent.toolCallId);\n }),\n );\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_ARGS for genui tool calls\n if (event.type === EventType.TOOL_CALL_ARGS) {\n const argsEvent = event as ToolCallArgsEvent;\n const parser = activeParsers.get(argsEvent.toolCallId);\n if (parser) {\n if (!flushedToolCalls.has(argsEvent.toolCallId)) {\n heldToolCallEvents.get(argsEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n parser.write(argsEvent.delta);\n return;\n }\n }\n\n // Hold or emit TOOL_CALL_END for genui tool calls\n if (event.type === EventType.TOOL_CALL_END) {\n const endEvent = event as { toolCallId: string } & BaseEvent;\n const parser = activeParsers.get(endEvent.toolCallId);\n if (parser) {\n // Mark generation complete\n const completeEvent: ActivityDeltaEvent = {\n type: EventType.ACTIVITY_DELTA,\n messageId: parser.messageId,\n activityType: ACTIVITY_TYPE,\n patch: [{ op: \"add\", path: \"/generating\", value: false }],\n };\n subscriber.next(completeEvent);\n\n if (!flushedToolCalls.has(endEvent.toolCallId)) {\n heldToolCallEvents.get(endEvent.toolCallId)!.push(event);\n } else {\n subscriber.next(event);\n }\n return;\n }\n }\n\n subscriber.next(event);\n },\n error: (err) => {\n // Flush any held tool call events so downstream sees them before the error\n for (const [, events] of heldToolCallEvents) {\n for (const event of events) {\n subscriber.next(event);\n }\n }\n heldToolCallEvents.clear();\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n subscriber.error(err);\n },\n complete: () => {\n // Flush any remaining held tool call events (e.g. parser never emitted)\n heldToolCallEvents.forEach((_, toolCallId) => {\n flushHeldEvents(toolCallId);\n });\n\n if (heldRunFinished) {\n subscriber.next(heldRunFinished.event);\n heldRunFinished = null;\n }\n activeParsers.clear();\n subscriber.complete();\n },\n });\n\n return () => subscription.unsubscribe();\n });\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkit/runtime",
|
|
3
|
-
"version": "1.55.
|
|
3
|
+
"version": "1.55.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"uuid": "^10.0.0",
|
|
116
116
|
"ws": "^8.18.0",
|
|
117
117
|
"zod": "^3.23.3",
|
|
118
|
-
"@copilotkit/shared": "1.55.
|
|
118
|
+
"@copilotkit/shared": "1.55.1"
|
|
119
119
|
},
|
|
120
120
|
"devDependencies": {
|
|
121
121
|
"@swc/core": "1.5.28",
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
ActivityDeltaEvent,
|
|
11
11
|
} from "@ag-ui/client";
|
|
12
12
|
import { Observable } from "rxjs";
|
|
13
|
-
import
|
|
13
|
+
import clarinet from "clarinet";
|
|
14
14
|
|
|
15
15
|
const TOOL_NAME = "generateSandboxedUi";
|
|
16
16
|
const ACTIVITY_TYPE = "open-generative-ui";
|