@tambo-ai/react 1.0.0-rc.4 → 1.0.0

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.
@@ -55,10 +55,19 @@ export interface PendingToolCall {
55
55
  export type RunAwaitingInputEvent = TamboCustomEventEnvelope<"tambo.run.awaiting_input", {
56
56
  pendingToolCalls: PendingToolCall[];
57
57
  }>;
58
+ /**
59
+ * Message parent event (custom: tambo.message.parent)
60
+ * Emitted when a message was created during the generation of another message
61
+ * (e.g., MCP sampling or elicitation).
62
+ */
63
+ export type MessageParentEvent = TamboCustomEventEnvelope<"tambo.message.parent", {
64
+ messageId: string;
65
+ parentMessageId: string;
66
+ }>;
58
67
  /**
59
68
  * Union type of Tambo-specific custom events
60
69
  */
61
- export type TamboCustomEvent = ComponentStartEvent | ComponentPropsDeltaEvent | ComponentStateDeltaEvent | ComponentEndEvent | RunAwaitingInputEvent;
70
+ export type TamboCustomEvent = ComponentStartEvent | ComponentPropsDeltaEvent | ComponentStateDeltaEvent | ComponentEndEvent | RunAwaitingInputEvent | MessageParentEvent;
62
71
  /**
63
72
  * Type guard to check if an event is a Tambo custom event.
64
73
  * Validates that the event has a name matching known Tambo custom event types.
@@ -1 +1 @@
1
- {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,KAAK,wBAAwB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,IAAI,IAAI,CAChE,WAAW,EACX,MAAM,GAAG,OAAO,CACjB,GAAG;IACF,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,CACxD,uBAAuB,EACvB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CACtD,qBAAqB,EACrB;IACE,WAAW,EAAE,MAAM,CAAC;CACrB,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAC1D,0BAA0B,EAC1B;IACE,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GACnB,wBAAwB,GACxB,wBAAwB,GACxB,iBAAiB,GACjB,qBAAqB,CAAC;AAa1B;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,KAAK,IAAI,gBAAgB,CAK5B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,GACjB,gBAAgB,GAAG,SAAS,CAe9B"}
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,KAAK,wBAAwB,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,IAAI,IAAI,CAChE,WAAW,EACX,MAAM,GAAG,OAAO,CACjB,GAAG;IACF,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,CACxD,uBAAuB,EACvB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAC7D,6BAA6B,EAC7B;IACE,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,CACtD,qBAAqB,EACrB;IACE,WAAW,EAAE,MAAM,CAAC;CACrB,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAC1D,0BAA0B,EAC1B;IACE,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC,CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,wBAAwB,CACvD,sBAAsB,EACtB;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,mBAAmB,GACnB,wBAAwB,GACxB,wBAAwB,GACxB,iBAAiB,GACjB,qBAAqB,GACrB,kBAAkB,CAAC;AAcvB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,KAAK,IAAI,gBAAgB,CAK5B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,GACjB,gBAAgB,GAAG,SAAS,CAiB9B"}
@@ -17,6 +17,7 @@ const TAMBO_CUSTOM_EVENT_NAMES = [
17
17
  "tambo.component.state_delta",
18
18
  "tambo.component.end",
19
19
  "tambo.run.awaiting_input",
20
+ "tambo.message.parent",
20
21
  ];
21
22
  /**
22
23
  * Type guard to check if an event is a Tambo custom event.
@@ -47,6 +48,8 @@ function asTamboCustomEvent(event) {
47
48
  return event;
48
49
  case "tambo.run.awaiting_input":
49
50
  return event;
51
+ case "tambo.message.parent":
52
+ return event;
50
53
  default:
51
54
  return undefined;
52
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"event.js","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA2GH,gDAOC;AAQD,gDAiBC;AAlDD;;GAEG;AACH,MAAM,wBAAwB,GAAG;IAC/B,uBAAuB;IACvB,6BAA6B;IAC7B,6BAA6B;IAC7B,qBAAqB;IACrB,0BAA0B;CAClB,CAAC;AAEX;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,KAElC;IACC,OAAO,CACL,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC7B,wBAA8C,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CACrE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAChC,KAAkB;IAElB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,uBAAuB;YAC1B,OAAO,KAA4B,CAAC;QACtC,KAAK,6BAA6B;YAChC,OAAO,KAAiC,CAAC;QAC3C,KAAK,6BAA6B;YAChC,OAAO,KAAiC,CAAC;QAC3C,KAAK,qBAAqB;YACxB,OAAO,KAA0B,CAAC;QACpC,KAAK,0BAA0B;YAC7B,OAAO,KAA8B,CAAC;QACxC;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Tambo-specific Custom Event Types for Streaming API\n *\n * Defines custom events specific to Tambo functionality.\n * For standard AG-UI events, import directly from `@ag-ui/core`.\n */\n\nimport type { CustomEvent } from \"@ag-ui/core\";\nimport type { Operation } from \"fast-json-patch\";\n\ntype TamboCustomEventEnvelope<TName extends string, TValue> = Omit<\n CustomEvent,\n \"name\" | \"value\"\n> & {\n name: TName;\n value: TValue;\n};\n\n/**\n * Component start event (custom: tambo.component.start)\n */\nexport type ComponentStartEvent = TamboCustomEventEnvelope<\n \"tambo.component.start\",\n {\n messageId: string;\n componentId: string;\n componentName: string;\n }\n>;\n\n/**\n * Component props delta event (custom: tambo.component.props_delta)\n * Uses JSON Patch (RFC 6902) to update component props\n */\nexport type ComponentPropsDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.props_delta\",\n {\n componentId: string;\n operations: Operation[];\n }\n>;\n\n/**\n * Component state delta event (custom: tambo.component.state_delta)\n * Uses JSON Patch (RFC 6902) to update component state\n */\nexport type ComponentStateDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.state_delta\",\n {\n componentId: string;\n operations: Operation[];\n }\n>;\n\n/**\n * Component end event (custom: tambo.component.end)\n */\nexport type ComponentEndEvent = TamboCustomEventEnvelope<\n \"tambo.component.end\",\n {\n componentId: string;\n }\n>;\n\n/**\n * Pending tool call information from awaiting_input event\n */\nexport interface PendingToolCall {\n toolCallId: string;\n toolName: string;\n arguments: string;\n}\n\n/**\n * Run awaiting input event (custom: tambo.run.awaiting_input)\n * Signals that the run is paused waiting for client-side tool execution\n */\nexport type RunAwaitingInputEvent = TamboCustomEventEnvelope<\n \"tambo.run.awaiting_input\",\n {\n pendingToolCalls: PendingToolCall[];\n }\n>;\n\n/**\n * Union type of Tambo-specific custom events\n */\nexport type TamboCustomEvent =\n | ComponentStartEvent\n | ComponentPropsDeltaEvent\n | ComponentStateDeltaEvent\n | ComponentEndEvent\n | RunAwaitingInputEvent;\n\n/**\n * Known Tambo custom event names for type narrowing\n */\nconst TAMBO_CUSTOM_EVENT_NAMES = [\n \"tambo.component.start\",\n \"tambo.component.props_delta\",\n \"tambo.component.state_delta\",\n \"tambo.component.end\",\n \"tambo.run.awaiting_input\",\n] as const;\n\n/**\n * Type guard to check if an event is a Tambo custom event.\n * Validates that the event has a name matching known Tambo custom event types.\n * @param event - Event object to check\n * @param event.name - Event name to match against known Tambo event types\n * @returns True if event is a TamboCustomEvent\n */\nexport function isTamboCustomEvent(event: {\n name?: string;\n}): event is TamboCustomEvent {\n return (\n typeof event.name === \"string\" &&\n (TAMBO_CUSTOM_EVENT_NAMES as readonly string[]).includes(event.name)\n );\n}\n\n/**\n * Casts a CustomEvent to the specific TamboCustomEvent type based on its name.\n * Uses exhaustive type checking to ensure all event types are handled.\n * @param event - The CustomEvent to cast\n * @returns The properly typed TamboCustomEvent, or undefined if not a known Tambo event\n */\nexport function asTamboCustomEvent(\n event: CustomEvent,\n): TamboCustomEvent | undefined {\n switch (event.name) {\n case \"tambo.component.start\":\n return event as ComponentStartEvent;\n case \"tambo.component.props_delta\":\n return event as ComponentPropsDeltaEvent;\n case \"tambo.component.state_delta\":\n return event as ComponentStateDeltaEvent;\n case \"tambo.component.end\":\n return event as ComponentEndEvent;\n case \"tambo.run.awaiting_input\":\n return event as RunAwaitingInputEvent;\n default:\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../../../src/v1/types/event.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA0HH,gDAOC;AAQD,gDAmBC;AArDD;;GAEG;AACH,MAAM,wBAAwB,GAAG;IAC/B,uBAAuB;IACvB,6BAA6B;IAC7B,6BAA6B;IAC7B,qBAAqB;IACrB,0BAA0B;IAC1B,sBAAsB;CACd,CAAC;AAEX;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,KAElC;IACC,OAAO,CACL,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC7B,wBAA8C,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CACrE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAChC,KAAkB;IAElB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,uBAAuB;YAC1B,OAAO,KAA4B,CAAC;QACtC,KAAK,6BAA6B;YAChC,OAAO,KAAiC,CAAC;QAC3C,KAAK,6BAA6B;YAChC,OAAO,KAAiC,CAAC;QAC3C,KAAK,qBAAqB;YACxB,OAAO,KAA0B,CAAC;QACpC,KAAK,0BAA0B;YAC7B,OAAO,KAA8B,CAAC;QACxC,KAAK,sBAAsB;YACzB,OAAO,KAA2B,CAAC;QACrC;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Tambo-specific Custom Event Types for Streaming API\n *\n * Defines custom events specific to Tambo functionality.\n * For standard AG-UI events, import directly from `@ag-ui/core`.\n */\n\nimport type { CustomEvent } from \"@ag-ui/core\";\nimport type { Operation } from \"fast-json-patch\";\n\ntype TamboCustomEventEnvelope<TName extends string, TValue> = Omit<\n CustomEvent,\n \"name\" | \"value\"\n> & {\n name: TName;\n value: TValue;\n};\n\n/**\n * Component start event (custom: tambo.component.start)\n */\nexport type ComponentStartEvent = TamboCustomEventEnvelope<\n \"tambo.component.start\",\n {\n messageId: string;\n componentId: string;\n componentName: string;\n }\n>;\n\n/**\n * Component props delta event (custom: tambo.component.props_delta)\n * Uses JSON Patch (RFC 6902) to update component props\n */\nexport type ComponentPropsDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.props_delta\",\n {\n componentId: string;\n operations: Operation[];\n }\n>;\n\n/**\n * Component state delta event (custom: tambo.component.state_delta)\n * Uses JSON Patch (RFC 6902) to update component state\n */\nexport type ComponentStateDeltaEvent = TamboCustomEventEnvelope<\n \"tambo.component.state_delta\",\n {\n componentId: string;\n operations: Operation[];\n }\n>;\n\n/**\n * Component end event (custom: tambo.component.end)\n */\nexport type ComponentEndEvent = TamboCustomEventEnvelope<\n \"tambo.component.end\",\n {\n componentId: string;\n }\n>;\n\n/**\n * Pending tool call information from awaiting_input event\n */\nexport interface PendingToolCall {\n toolCallId: string;\n toolName: string;\n arguments: string;\n}\n\n/**\n * Run awaiting input event (custom: tambo.run.awaiting_input)\n * Signals that the run is paused waiting for client-side tool execution\n */\nexport type RunAwaitingInputEvent = TamboCustomEventEnvelope<\n \"tambo.run.awaiting_input\",\n {\n pendingToolCalls: PendingToolCall[];\n }\n>;\n\n/**\n * Message parent event (custom: tambo.message.parent)\n * Emitted when a message was created during the generation of another message\n * (e.g., MCP sampling or elicitation).\n */\nexport type MessageParentEvent = TamboCustomEventEnvelope<\n \"tambo.message.parent\",\n {\n messageId: string;\n parentMessageId: string;\n }\n>;\n\n/**\n * Union type of Tambo-specific custom events\n */\nexport type TamboCustomEvent =\n | ComponentStartEvent\n | ComponentPropsDeltaEvent\n | ComponentStateDeltaEvent\n | ComponentEndEvent\n | RunAwaitingInputEvent\n | MessageParentEvent;\n\n/**\n * Known Tambo custom event names for type narrowing\n */\nconst TAMBO_CUSTOM_EVENT_NAMES = [\n \"tambo.component.start\",\n \"tambo.component.props_delta\",\n \"tambo.component.state_delta\",\n \"tambo.component.end\",\n \"tambo.run.awaiting_input\",\n \"tambo.message.parent\",\n] as const;\n\n/**\n * Type guard to check if an event is a Tambo custom event.\n * Validates that the event has a name matching known Tambo custom event types.\n * @param event - Event object to check\n * @param event.name - Event name to match against known Tambo event types\n * @returns True if event is a TamboCustomEvent\n */\nexport function isTamboCustomEvent(event: {\n name?: string;\n}): event is TamboCustomEvent {\n return (\n typeof event.name === \"string\" &&\n (TAMBO_CUSTOM_EVENT_NAMES as readonly string[]).includes(event.name)\n );\n}\n\n/**\n * Casts a CustomEvent to the specific TamboCustomEvent type based on its name.\n * Uses exhaustive type checking to ensure all event types are handled.\n * @param event - The CustomEvent to cast\n * @returns The properly typed TamboCustomEvent, or undefined if not a known Tambo event\n */\nexport function asTamboCustomEvent(\n event: CustomEvent,\n): TamboCustomEvent | undefined {\n switch (event.name) {\n case \"tambo.component.start\":\n return event as ComponentStartEvent;\n case \"tambo.component.props_delta\":\n return event as ComponentPropsDeltaEvent;\n case \"tambo.component.state_delta\":\n return event as ComponentStateDeltaEvent;\n case \"tambo.component.end\":\n return event as ComponentEndEvent;\n case \"tambo.run.awaiting_input\":\n return event as RunAwaitingInputEvent;\n case \"tambo.message.parent\":\n return event as MessageParentEvent;\n default:\n return undefined;\n }\n}\n"]}
@@ -47,6 +47,14 @@ describe("isTamboCustomEvent", () => {
47
47
  };
48
48
  expect((0, event_1.isTamboCustomEvent)(event)).toBe(true);
49
49
  });
50
+ it("returns true for tambo.message.parent event", () => {
51
+ const event = {
52
+ type: core_1.EventType.CUSTOM,
53
+ name: "tambo.message.parent",
54
+ value: { messageId: "msg1", parentMessageId: "parent1" },
55
+ };
56
+ expect((0, event_1.isTamboCustomEvent)(event)).toBe(true);
57
+ });
50
58
  it("returns false for unknown custom event name", () => {
51
59
  const event = {
52
60
  type: core_1.EventType.CUSTOM,
@@ -71,4 +79,26 @@ describe("isTamboCustomEvent", () => {
71
79
  expect((0, event_1.isTamboCustomEvent)({})).toBe(false);
72
80
  });
73
81
  });
82
+ describe("asTamboCustomEvent", () => {
83
+ it("casts tambo.message.parent event", () => {
84
+ const event = {
85
+ type: core_1.EventType.CUSTOM,
86
+ name: "tambo.message.parent",
87
+ value: { messageId: "msg1", parentMessageId: "parent1" },
88
+ timestamp: 1234,
89
+ };
90
+ const result = (0, event_1.asTamboCustomEvent)(event);
91
+ expect(result).toBeDefined();
92
+ expect(result?.name).toBe("tambo.message.parent");
93
+ });
94
+ it("returns undefined for unknown event name", () => {
95
+ const event = {
96
+ type: core_1.EventType.CUSTOM,
97
+ name: "unknown.event",
98
+ value: {},
99
+ timestamp: 1234,
100
+ };
101
+ expect((0, event_1.asTamboCustomEvent)(event)).toBeUndefined();
102
+ });
103
+ });
74
104
  //# sourceMappingURL=event.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"event.test.js","sourceRoot":"","sources":["../../../src/v1/types/event.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventType } from \"@ag-ui/core\";\nimport { isTamboCustomEvent } from \"./event\";\n\ndescribe(\"isTamboCustomEvent\", () => {\n it(\"returns true for tambo.component.start event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.start\",\n value: { messageId: \"msg1\", componentId: \"comp1\", componentName: \"Test\" },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.props_delta event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.props_delta\",\n value: { componentId: \"comp1\", operations: [] },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.state_delta event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.state_delta\",\n value: { componentId: \"comp1\", operations: [] },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.end event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.end\",\n value: { componentId: \"comp1\" },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.run.awaiting_input event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: {\n pendingToolCalls: [\n { toolCallId: \"tool1\", toolName: \"test\", arguments: \"{}\" },\n ],\n },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns false for unknown custom event name\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"unknown.event\",\n value: {},\n };\n expect(isTamboCustomEvent(event)).toBe(false);\n });\n\n it(\"returns false when name is undefined\", () => {\n const event: { name?: string } = {};\n expect(isTamboCustomEvent(event)).toBe(false);\n });\n\n it(\"returns false when name is not a string\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: 123,\n value: {},\n };\n expect(isTamboCustomEvent(event as unknown as { name?: string })).toBe(\n false,\n );\n });\n\n it(\"returns false for empty object\", () => {\n expect(isTamboCustomEvent({})).toBe(false);\n });\n});\n"]}
1
+ {"version":3,"file":"event.test.js","sourceRoot":"","sources":["../../../src/v1/types/event.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventType, type CustomEvent } from \"@ag-ui/core\";\nimport { asTamboCustomEvent, isTamboCustomEvent } from \"./event\";\n\ndescribe(\"isTamboCustomEvent\", () => {\n it(\"returns true for tambo.component.start event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.start\",\n value: { messageId: \"msg1\", componentId: \"comp1\", componentName: \"Test\" },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.props_delta event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.props_delta\",\n value: { componentId: \"comp1\", operations: [] },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.state_delta event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.state_delta\",\n value: { componentId: \"comp1\", operations: [] },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.component.end event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.component.end\",\n value: { componentId: \"comp1\" },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.run.awaiting_input event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.run.awaiting_input\",\n value: {\n pendingToolCalls: [\n { toolCallId: \"tool1\", toolName: \"test\", arguments: \"{}\" },\n ],\n },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns true for tambo.message.parent event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.message.parent\",\n value: { messageId: \"msg1\", parentMessageId: \"parent1\" },\n };\n expect(isTamboCustomEvent(event)).toBe(true);\n });\n\n it(\"returns false for unknown custom event name\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"unknown.event\",\n value: {},\n };\n expect(isTamboCustomEvent(event)).toBe(false);\n });\n\n it(\"returns false when name is undefined\", () => {\n const event: { name?: string } = {};\n expect(isTamboCustomEvent(event)).toBe(false);\n });\n\n it(\"returns false when name is not a string\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: 123,\n value: {},\n };\n expect(isTamboCustomEvent(event as unknown as { name?: string })).toBe(\n false,\n );\n });\n\n it(\"returns false for empty object\", () => {\n expect(isTamboCustomEvent({})).toBe(false);\n });\n});\n\ndescribe(\"asTamboCustomEvent\", () => {\n it(\"casts tambo.message.parent event\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"tambo.message.parent\",\n value: { messageId: \"msg1\", parentMessageId: \"parent1\" },\n timestamp: 1234,\n } as CustomEvent;\n\n const result = asTamboCustomEvent(event);\n expect(result).toBeDefined();\n expect(result?.name).toBe(\"tambo.message.parent\");\n });\n\n it(\"returns undefined for unknown event name\", () => {\n const event = {\n type: EventType.CUSTOM,\n name: \"unknown.event\",\n value: {},\n timestamp: 1234,\n } as CustomEvent;\n\n expect(asTamboCustomEvent(event)).toBeUndefined();\n });\n});\n"]}
@@ -107,6 +107,11 @@ export interface TamboThreadMessage {
107
107
  createdAt?: string;
108
108
  /** Message metadata */
109
109
  metadata?: Record<string, unknown>;
110
+ /**
111
+ * The id of the parent message, if this message was created during
112
+ * generation of another message (e.g., MCP sampling or elicitation).
113
+ */
114
+ parentMessageId?: string;
110
115
  /**
111
116
  * Reasoning content from the model (transient - only during streaming).
112
117
  * Each element is a reasoning "chunk" - models may emit multiple reasoning blocks.
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAK1C,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,eAAe,GAChB,MAAM,oDAAoD,CAAC;AAG5D,YAAY,EAAE,YAAY,EAAE,MAAM,iDAAiD,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAEvF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC;AAExE,YAAY,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qDAAqD,CAAC;AAG7D,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EAChB,MAAM,oDAAoD,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;AAEvE;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,uBAAuB,CAAC;IAEzC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CACzC;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,gDAAgD;IAChD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6CAA6C;IAC7C,8BAA8B,CAAC,EAAE,MAAM,CAAC;CACzC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC;IACxE;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,qBAAqB,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE1D;;;GAGG;AACH,MAAM,MAAM,OAAO,GACf,WAAW,GACX,mBAAmB,GACnB,iBAAiB,GACjB,qBAAqB,GACrB,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IAEX,uCAAuC;IACvC,IAAI,EAAE,WAAW,CAAC;IAElB,oCAAoC;IACpC,OAAO,EAAE,OAAO,EAAE,CAAC;IAEnB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAK1C,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,eAAe,GAChB,MAAM,oDAAoD,CAAC;AAG5D,YAAY,EAAE,YAAY,EAAE,MAAM,iDAAiD,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAEvF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC;AAExE,YAAY,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,qDAAqD,CAAC;AAG7D,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EAChB,MAAM,oDAAoD,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;AAEvE;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,uBAAuB,CAAC;IAEzC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CACzC;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,gDAAgD;IAChD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6CAA6C;IAC7C,8BAA8B,CAAC,EAAE,MAAM,CAAC;CACzC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC;IACxE;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,qBAAqB,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE1D;;;GAGG;AACH,MAAM,MAAM,OAAO,GACf,WAAW,GACX,mBAAmB,GACnB,iBAAiB,GACjB,qBAAqB,GACrB,eAAe,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IAEX,uCAAuC;IACvC,IAAI,EAAE,WAAW,CAAC;IAElB,oCAAoC;IACpC,OAAO,EAAE,OAAO,EAAE,CAAC;IAEnB,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * Message and Content Types\n *\n * Re-exports message and content types from `@tambo-ai/typescript-sdk`.\n * Messages use Anthropic-style content blocks pattern where a message\n * contains an array of content blocks (text, tool calls, tool results, components).\n */\n\nimport type { ReactElement } from \"react\";\n\n// Re-export content block types from TypeScript SDK\n// Note: ToolUseContent and ComponentContent are NOT re-exported - use TamboToolUseContent\n// and TamboComponentContent instead, which include computed state properties.\nexport type {\n TextContent,\n ToolResultContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n// Re-export message types from TypeScript SDK\nexport type { InputMessage } from \"@tambo-ai/typescript-sdk/resources/threads/runs\";\nimport type { RunCreateParams } from \"@tambo-ai/typescript-sdk/resources/threads/runs\";\n\n/**\n * Message type for initial messages that seed a new thread.\n * Supports system and assistant roles in addition to user,\n * and restricts content to text and resource blocks (no tool results).\n */\nexport type InitialInputMessage = RunCreateParams.Thread.InitialMessage;\n\nexport type {\n MessageListResponse,\n MessageGetResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/messages\";\n\n// Import for Content union type\nimport type {\n TextContent,\n ToolUseContent,\n ToolResultContent,\n ComponentContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n/**\n * Streaming state for component content blocks.\n * Tracks the lifecycle of component prop/state streaming.\n */\nexport type ComponentStreamingState = \"started\" | \"streaming\" | \"done\";\n\n/**\n * Extended ComponentContent with streaming state and rendered element.\n * Used by the SDK to track component rendering lifecycle.\n */\nexport interface TamboComponentContent extends ComponentContent {\n /**\n * Current streaming state of this component's props.\n * - 'started': Component block created, awaiting props\n * - 'streaming': Props are being streamed\n * - 'done': Props streaming complete\n *\n * Optional for historical messages loaded from API (defaults to \"done\").\n */\n streamingState?: ComponentStreamingState;\n\n /**\n * The rendered React element for this component.\n * undefined if not yet rendered, null if the component couldn't be found in the registry.\n */\n renderedComponent?: ReactElement | null;\n}\n\n/**\n * Special display properties that can be included in tool input.\n * These are used to customize tool status messages shown in the UI.\n */\nexport interface TamboToolDisplayProps {\n /** Message shown while the tool is executing */\n _tambo_statusMessage?: string;\n /** Message shown after the tool completes */\n _tambo_completionStatusMessage?: string;\n}\n\n/**\n * Extended ToolUseContent with computed state properties.\n * Used by the SDK to provide pre-computed tool state to consumers.\n *\n * Note: The computed properties are populated by `useTambo()` hook.\n * When accessed via lower-level APIs, they may be undefined.\n */\nexport interface TamboToolUseContent extends Omit<ToolUseContent, \"input\"> {\n /**\n * Tool input parameters with internal `_tambo_*` properties removed.\n * Consumers see only the actual tool parameters.\n */\n input: Record<string, unknown>;\n\n /**\n * Whether this tool call has completed (has a matching tool_result).\n * Computed by `useTambo()` based on presence of matching tool_result.\n */\n hasCompleted?: boolean;\n\n /**\n * The status message to display, resolved based on tool execution state.\n * Automatically updates as tool progresses through execution lifecycle.\n * Computed by `useTambo()`.\n */\n statusMessage?: string;\n\n /**\n * Extracted Tambo display properties from the tool input.\n * Consumers can use these for custom rendering if needed.\n * Computed by `useTambo()`.\n */\n tamboDisplayProps?: TamboToolDisplayProps;\n}\n\n/**\n * Message role (from SDK)\n * Includes 'system' to accommodate messages loaded from API.\n */\nexport type MessageRole = \"user\" | \"assistant\" | \"system\";\n\n/**\n * Union type of all content block types.\n * Uses TamboComponentContent and TamboToolUseContent which include computed state.\n */\nexport type Content =\n | TextContent\n | TamboToolUseContent\n | ToolResultContent\n | TamboComponentContent\n | ResourceContent;\n\n/**\n * Message in a thread (simplified from SDK's MessageGetResponse)\n */\nexport interface TamboThreadMessage {\n /** Unique message identifier */\n id: string;\n\n /** Message role (user or assistant) */\n role: MessageRole;\n\n /** Content blocks in the message */\n content: Content[];\n\n /** When the message was created (optional for historical messages loaded from API) */\n createdAt?: string;\n\n /** Message metadata */\n metadata?: Record<string, unknown>;\n\n /**\n * Reasoning content from the model (transient - only during streaming).\n * Each element is a reasoning \"chunk\" - models may emit multiple reasoning blocks.\n * This data is not persisted to the database and will not be present in\n * messages loaded from the API.\n */\n reasoning?: string[];\n\n /**\n * Duration of the reasoning phase in milliseconds (for display purposes).\n * Populated when reasoning completes.\n */\n reasoningDurationMS?: number;\n}\n"]}
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/v1/types/message.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * Message and Content Types\n *\n * Re-exports message and content types from `@tambo-ai/typescript-sdk`.\n * Messages use Anthropic-style content blocks pattern where a message\n * contains an array of content blocks (text, tool calls, tool results, components).\n */\n\nimport type { ReactElement } from \"react\";\n\n// Re-export content block types from TypeScript SDK\n// Note: ToolUseContent and ComponentContent are NOT re-exported - use TamboToolUseContent\n// and TamboComponentContent instead, which include computed state properties.\nexport type {\n TextContent,\n ToolResultContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n// Re-export message types from TypeScript SDK\nexport type { InputMessage } from \"@tambo-ai/typescript-sdk/resources/threads/runs\";\nimport type { RunCreateParams } from \"@tambo-ai/typescript-sdk/resources/threads/runs\";\n\n/**\n * Message type for initial messages that seed a new thread.\n * Supports system and assistant roles in addition to user,\n * and restricts content to text and resource blocks (no tool results).\n */\nexport type InitialInputMessage = RunCreateParams.Thread.InitialMessage;\n\nexport type {\n MessageListResponse,\n MessageGetResponse,\n} from \"@tambo-ai/typescript-sdk/resources/threads/messages\";\n\n// Import for Content union type\nimport type {\n TextContent,\n ToolUseContent,\n ToolResultContent,\n ComponentContent,\n ResourceContent,\n} from \"@tambo-ai/typescript-sdk/resources/threads/threads\";\n\n/**\n * Streaming state for component content blocks.\n * Tracks the lifecycle of component prop/state streaming.\n */\nexport type ComponentStreamingState = \"started\" | \"streaming\" | \"done\";\n\n/**\n * Extended ComponentContent with streaming state and rendered element.\n * Used by the SDK to track component rendering lifecycle.\n */\nexport interface TamboComponentContent extends ComponentContent {\n /**\n * Current streaming state of this component's props.\n * - 'started': Component block created, awaiting props\n * - 'streaming': Props are being streamed\n * - 'done': Props streaming complete\n *\n * Optional for historical messages loaded from API (defaults to \"done\").\n */\n streamingState?: ComponentStreamingState;\n\n /**\n * The rendered React element for this component.\n * undefined if not yet rendered, null if the component couldn't be found in the registry.\n */\n renderedComponent?: ReactElement | null;\n}\n\n/**\n * Special display properties that can be included in tool input.\n * These are used to customize tool status messages shown in the UI.\n */\nexport interface TamboToolDisplayProps {\n /** Message shown while the tool is executing */\n _tambo_statusMessage?: string;\n /** Message shown after the tool completes */\n _tambo_completionStatusMessage?: string;\n}\n\n/**\n * Extended ToolUseContent with computed state properties.\n * Used by the SDK to provide pre-computed tool state to consumers.\n *\n * Note: The computed properties are populated by `useTambo()` hook.\n * When accessed via lower-level APIs, they may be undefined.\n */\nexport interface TamboToolUseContent extends Omit<ToolUseContent, \"input\"> {\n /**\n * Tool input parameters with internal `_tambo_*` properties removed.\n * Consumers see only the actual tool parameters.\n */\n input: Record<string, unknown>;\n\n /**\n * Whether this tool call has completed (has a matching tool_result).\n * Computed by `useTambo()` based on presence of matching tool_result.\n */\n hasCompleted?: boolean;\n\n /**\n * The status message to display, resolved based on tool execution state.\n * Automatically updates as tool progresses through execution lifecycle.\n * Computed by `useTambo()`.\n */\n statusMessage?: string;\n\n /**\n * Extracted Tambo display properties from the tool input.\n * Consumers can use these for custom rendering if needed.\n * Computed by `useTambo()`.\n */\n tamboDisplayProps?: TamboToolDisplayProps;\n}\n\n/**\n * Message role (from SDK)\n * Includes 'system' to accommodate messages loaded from API.\n */\nexport type MessageRole = \"user\" | \"assistant\" | \"system\";\n\n/**\n * Union type of all content block types.\n * Uses TamboComponentContent and TamboToolUseContent which include computed state.\n */\nexport type Content =\n | TextContent\n | TamboToolUseContent\n | ToolResultContent\n | TamboComponentContent\n | ResourceContent;\n\n/**\n * Message in a thread (simplified from SDK's MessageGetResponse)\n */\nexport interface TamboThreadMessage {\n /** Unique message identifier */\n id: string;\n\n /** Message role (user or assistant) */\n role: MessageRole;\n\n /** Content blocks in the message */\n content: Content[];\n\n /** When the message was created (optional for historical messages loaded from API) */\n createdAt?: string;\n\n /** Message metadata */\n metadata?: Record<string, unknown>;\n\n /**\n * The id of the parent message, if this message was created during\n * generation of another message (e.g., MCP sampling or elicitation).\n */\n parentMessageId?: string;\n\n /**\n * Reasoning content from the model (transient - only during streaming).\n * Each element is a reasoning \"chunk\" - models may emit multiple reasoning blocks.\n * This data is not persisted to the database and will not be present in\n * messages loaded from the API.\n */\n reasoning?: string[];\n\n /**\n * Duration of the reasoning phase in milliseconds (for display purposes).\n * Populated when reasoning completes.\n */\n reasoningDurationMS?: number;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"event-accumulator.d.ts","sourceRoot":"","sources":["../../../src/v1/utils/event-accumulator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-accumulator.d.ts","sourceRoot":"","sources":["../../../src/v1/utils/event-accumulator.ts"],"names":[],"mappings":"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"}
@@ -539,7 +539,23 @@ function handleTextMessageStart(threadState, event) {
539
539
  };
540
540
  }
541
541
  }
542
- // No ephemeral message to reuse - create a new message
542
+ // Check if a message with this ID already exists (e.g., created by
543
+ // handleMessageParent). If so, just update streaming state to track it.
544
+ const existingIndex = messages.findIndex((m) => m.id === event.messageId);
545
+ if (existingIndex !== -1) {
546
+ return {
547
+ ...threadState,
548
+ thread: {
549
+ ...threadState.thread,
550
+ updatedAt: new Date().toISOString(),
551
+ },
552
+ streaming: {
553
+ ...threadState.streaming,
554
+ messageId: event.messageId,
555
+ },
556
+ };
557
+ }
558
+ // No existing message to reuse - create a new message
543
559
  const newMessage = {
544
560
  id: event.messageId,
545
561
  role: isAssistant ? "assistant" : "user",
@@ -848,6 +864,8 @@ function handleCustomEvent(threadState, event) {
848
864
  return handleComponentEnd(threadState, customEvent);
849
865
  case "tambo.run.awaiting_input":
850
866
  return handleRunAwaitingInput(threadState, customEvent);
867
+ case "tambo.message.parent":
868
+ return handleMessageParent(threadState, customEvent);
851
869
  default: {
852
870
  // Exhaustiveness check: if a new event type is added to TamboCustomEvent
853
871
  // and not handled here, TypeScript will error
@@ -985,6 +1003,42 @@ function handleRunAwaitingInput(threadState, _event) {
985
1003
  },
986
1004
  };
987
1005
  }
1006
+ /**
1007
+ * Handle tambo.message.parent event.
1008
+ * Sets parentMessageId on the target message, creating a new empty assistant
1009
+ * message if one doesn't already exist with the given ID.
1010
+ *
1011
+ * This event fires BEFORE TEXT_MESSAGE_START, so when handleTextMessageStart
1012
+ * later finds/creates the message with the same ID, the parentMessageId will
1013
+ * already be set.
1014
+ * @param threadState - Current thread state
1015
+ * @param event - Message parent event
1016
+ * @returns Updated thread state
1017
+ */
1018
+ function handleMessageParent(threadState, event) {
1019
+ const { messageId, parentMessageId } = event.value;
1020
+ const messages = threadState.thread.messages;
1021
+ // Find existing message or create a new empty assistant message
1022
+ const messageIndex = messages.findIndex((m) => m.id === messageId);
1023
+ if (messageIndex !== -1) {
1024
+ // Message already exists - set parentMessageId on it
1025
+ const message = messages[messageIndex];
1026
+ const updatedMessage = {
1027
+ ...message,
1028
+ parentMessageId,
1029
+ };
1030
+ return updateThreadMessages(threadState, updateMessageAtIndex(messages, messageIndex, updatedMessage));
1031
+ }
1032
+ // Message doesn't exist yet - create a new empty assistant message
1033
+ const newMessage = {
1034
+ id: messageId,
1035
+ role: "assistant",
1036
+ content: [],
1037
+ createdAt: new Date().toISOString(),
1038
+ parentMessageId,
1039
+ };
1040
+ return updateThreadMessages(threadState, [...messages, newMessage]);
1041
+ }
988
1042
  // ============================================================================
989
1043
  // Reasoning Event Handlers (currently mapped from THINKING_TEXT_MESSAGE_* events)
990
1044
  // ============================================================================