@trigger.dev/sdk 4.5.1 → 4.5.2
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/commonjs/v3/ai.js +66 -22
- package/dist/commonjs/v3/ai.js.map +1 -1
- package/dist/commonjs/v3/chat-react.d.ts +1 -0
- package/dist/commonjs/v3/chat-react.js +4 -1
- package/dist/commonjs/v3/chat-react.js.map +1 -1
- package/dist/commonjs/v3/chat.d.ts +100 -0
- package/dist/commonjs/v3/chat.js +203 -19
- package/dist/commonjs/v3/chat.js.map +1 -1
- package/dist/commonjs/v3/index.d.ts +1 -1
- package/dist/commonjs/v3/index.js.map +1 -1
- package/dist/commonjs/v3/runs-bulk.test.d.ts +1 -0
- package/dist/commonjs/v3/runs-bulk.test.js +141 -0
- package/dist/commonjs/v3/runs-bulk.test.js.map +1 -0
- package/dist/commonjs/v3/runs.d.ts +19 -2
- package/dist/commonjs/v3/runs.js +87 -0
- package/dist/commonjs/v3/runs.js.map +1 -1
- package/dist/commonjs/v3/sessions.js +5 -2
- package/dist/commonjs/v3/sessions.js.map +1 -1
- package/dist/commonjs/v3/shared.d.ts +2 -2
- package/dist/commonjs/v3/shared.js +79 -4
- package/dist/commonjs/v3/shared.js.map +1 -1
- package/dist/commonjs/v3/shared.test.js +37 -0
- package/dist/commonjs/v3/shared.test.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/esm/v3/ai.js +66 -22
- package/dist/esm/v3/ai.js.map +1 -1
- package/dist/esm/v3/chat-react.d.ts +1 -0
- package/dist/esm/v3/chat-react.js +4 -1
- package/dist/esm/v3/chat-react.js.map +1 -1
- package/dist/esm/v3/chat.d.ts +100 -0
- package/dist/esm/v3/chat.js +204 -20
- package/dist/esm/v3/chat.js.map +1 -1
- package/dist/esm/v3/index.d.ts +1 -1
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/esm/v3/runs-bulk.test.d.ts +1 -0
- package/dist/esm/v3/runs-bulk.test.js +139 -0
- package/dist/esm/v3/runs-bulk.test.js.map +1 -0
- package/dist/esm/v3/runs.d.ts +18 -1
- package/dist/esm/v3/runs.js +87 -0
- package/dist/esm/v3/runs.js.map +1 -1
- package/dist/esm/v3/sessions.js +5 -2
- package/dist/esm/v3/sessions.js.map +1 -1
- package/dist/esm/v3/shared.d.ts +2 -2
- package/dist/esm/v3/shared.js +79 -5
- package/dist/esm/v3/shared.js.map +1 -1
- package/dist/esm/v3/shared.test.js +38 -1
- package/dist/esm/v3/shared.test.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/ai-chat/frontend.mdx +46 -0
- package/docs/ai-chat/pending-messages.mdx +3 -1
- package/docs/ai-chat/reference.mdx +20 -0
- package/docs/billing-limits.mdx +73 -0
- package/docs/how-to-reduce-your-spend.mdx +1 -14
- package/docs/limits.mdx +5 -0
- package/docs/self-hosting/docker.mdx +24 -1
- package/docs/self-hosting/env/webapp.mdx +6 -1
- package/docs/self-hosting/kubernetes.mdx +26 -0
- package/docs/self-hosting/overview.mdx +4 -1
- package/docs/self-hosting/security.mdx +50 -0
- package/docs/troubleshooting.mdx +4 -0
- package/package.json +2 -2
|
@@ -15,6 +15,7 @@ export type UseTriggerChatTransportOptions<TTask extends AnyTask = AnyTask> = Om
|
|
|
15
15
|
task: TaskIdentifier<TTask>;
|
|
16
16
|
};
|
|
17
17
|
export type { InferChatUIMessage };
|
|
18
|
+
export type { ChatTransportEvent, ChatTransportSendSource } from "./chat.js";
|
|
18
19
|
/**
|
|
19
20
|
* React hook that creates and memoizes a `TriggerChatTransport` instance.
|
|
20
21
|
*
|
|
@@ -60,10 +60,13 @@ export function useTriggerChatTransport(options) {
|
|
|
60
60
|
ref.current = new TriggerChatTransport(options);
|
|
61
61
|
}
|
|
62
62
|
// Keep callbacks up to date without recreating the transport.
|
|
63
|
-
const { onSessionChange, clientData } = options;
|
|
63
|
+
const { onSessionChange, clientData, onEvent } = options;
|
|
64
64
|
useEffect(() => {
|
|
65
65
|
ref.current?.setOnSessionChange(onSessionChange);
|
|
66
66
|
}, [onSessionChange]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
ref.current?.setOnEvent(onEvent);
|
|
69
|
+
}, [onEvent]);
|
|
67
70
|
// Keep `clientData` up to date so the transport's per-turn merge and
|
|
68
71
|
// `startSession` callback both see the latest value without
|
|
69
72
|
// reconstructing the transport.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-react.js","sourceRoot":"","sources":["../../../src/v3/chat-react.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAoC,MAAM,WAAW,CAAC;AAEnF,OAAO,EACL,6BAA6B,GAG9B,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"chat-react.js","sourceRoot":"","sources":["../../../src/v3/chat-react.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAoC,MAAM,WAAW,CAAC;AAEnF,OAAO,EACL,6BAA6B,GAG9B,MAAM,gBAAgB,CAAC;AAsBxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAA8C;IAE9C,MAAM,GAAG,GAAG,MAAM,CAA8B,IAAI,CAAC,CAAC;IACtD,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QACzB,GAAG,CAAC,OAAO,GAAG,IAAI,oBAAoB,CAAC,OAAsC,CAAC,CAAC;IACjF,CAAC;IAED,8DAA8D;IAC9D,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACzD,SAAS,CAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAEtB,SAAS,CAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,qEAAqE;IACrE,4DAA4D;IAC5D,gCAAgC;IAChC,SAAS,CAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,EAAE,aAAa,CAAC,UAAiD,CAAC,CAAC;IAChF,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,4EAA4E;IAC5E,+EAA+E;IAC/E,kEAAkE;IAClE,4EAA4E;IAE5E,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAC7B,SAA+B,EAC/B,MAAc,EACd,QAAa,EACb,WAAoC;IAEpC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAEjF,wBAAwB;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,QAAiB,EAAE,EAAE;YACjD,IAAI,EAAE,KAAK,MAAM;gBAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC,CAAC;QACF,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACxC,aAAa,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAExB,0DAA0D;IAC1D,wEAAwE;IACxE,8DAA8D;IAC9D,wEAAwE;IACxE,MAAM,OAAO,GAAG,MAAM,CAAgD,IAAI,CAAC,CAAC;IAC5E,MAAM,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3C,iBAAiB,CAAC,OAAO,GAAG,QAAQ,CAAC;IAErC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACjE,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI;YAAE,OAAO,CAAC,oBAAoB;QAE1D,MAAM,QAAQ,GACZ,OAAO,mBAAmB,KAAK,UAAU;YACvC,CAAC,CAAC,mBAAmB;YACrB,CAAC,CAAC,CAAC,EAAc,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAE7C,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE;YAC9B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;YACvB,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,CAAC,OAAoB,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAElC,2DAA2D;IAC3D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxE,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,OAAO,kBAAkB,KAAK,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,YAAY,CAAC;gBAC5F,MAAM,CAAC,OAAO,CAAC,OAAc,CAAC,CAAC;gBAC/B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;YACzB,CAAC;YACD,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,CAAC,OAAoB,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAEpC,sDAAsD;IACtD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,IAAe,EAAE,EAAE;YAC/C,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;gBAClB,WAAW,CAAC,IAAW,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC;QACF,SAAS,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAErC,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC;AA0DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA8C;IAE9C,MAAM,EACJ,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,EACR,WAAW,EAAE,YAAY,EACzB,WAAW,EACX,QAAQ,GACT,GAAG,OAAO,CAAC;IAIZ,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAoB,EAAE,CAAC,CAAC;IACtE,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAC3C,cAAc,CAAC,OAAO,GAAG,WAAW,CAAC;IACrC,MAAM,cAAc,GAAG,MAAM,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAErC,gEAAgE;IAChE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,KAAK,WAAW;YAAE,OAAO;QACnC,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;gBAAE,SAAS;YACvC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;gBACnC,IAAK,IAAY,CAAC,IAAI,KAAK,6BAA6B,EAAE,CAAC;oBACzD,MAAM,UAAU,GAAI,IAAY,CAAC,IAAI,EAAE,UAAU,CAAC;oBAClD,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC9B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;4BAC5B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gCACpC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gCAC/B,aAAa,GAAG,IAAI,CAAC;4BACvB,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,yEAAyE;QACzE,IAAI,aAAa,EAAE,CAAC;YAClB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAClF,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEvB,yBAAyB;IACzB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,KAAK,WAAW,IAAI,MAAM,KAAK,OAAO,CAAC;QAClF,aAAa,CAAC,OAAO,GAAG,MAAM,CAAC;QAC/B,IAAI,CAAC,aAAa;YAAE,OAAO;QAE3B,oDAAoD;QACpD,mEAAmE;QACnE,8DAA8D;QAC9D,mEAAmE;QACnE,mEAAmE;QACnE,uEAAuE;QACvE,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5E,WAAW;QACX,cAAc,CAAC,EAAE,CAAC,CAAC;QACnB,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/B,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAE/B,yBAAyB;QACzB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAS,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7E,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE3D,kEAAkE;IAClE,MAAM,KAAK,GAAG,WAAW,CACvB,CAAC,IAAY,EAAE,EAAE;QACf,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG;gBACV,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;gBACvB,IAAI,EAAE,MAAe;gBACrB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;gBACxC,KAAK,EAAE,UAAmB;aACR,CAAC;YACrB,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;YACpD,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,qCAAqC;YACrC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,EACD,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CACnD,CAAC;IAEF,2DAA2D;IAC3D,MAAM,KAAK,GAAG,WAAW,CACvB,CAAC,IAAY,EAAE,EAAE;QACf,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG;gBACV,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;gBACvB,IAAI,EAAE,MAAe;gBACrB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;gBACxC,KAAK,EAAE,QAAiB;aACN,CAAC;YACrB,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,EACD,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,CAChC,CAAC;IAEF,2EAA2E;IAC3E,MAAM,cAAc,GAAG,MAAM,CAAc,IAAI,GAAG,EAAE,CAAC,CAAC;IACtD,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,EAAU,EAAE,EAAE;QACb,wDAAwD;QACxD,IAAI,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,sEAAsE;QACtE,sEAAsE;QACtE,mCAAmC;QACnC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO;QAC3C,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAEpD,cAAc,CAAC,CAAC,IAAI,EAAE,EAAE,CACtB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,UAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC1E,CAAC;IACJ,CAAC,EACD,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAC9B,CAAC;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,IAAa,EAAW,EAAE,CACzB,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACZ,IAAY,CAAC,IAAI,KAAK,6BAA6B,EACtD,EAAE,CACH,CAAC;IAEF,MAAM,qBAAqB,GAAG,WAAW,CACvC,CAAC,IAAa,EAAY,EAAE;QAC1B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QACvC,MAAM,GAAG,GAAI,IAAY,CAAC,IAAI,EAAE,UAAU,CAAC;QAC3C,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAC;IAEF,MAAM,mBAAmB,GAAG,WAAW,CACrC,CAAC,IAAa,EAAqB,EAAE;QACnC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QACvC,MAAM,IAAI,GAAI,IAAY,CAAC,IAAI,EAAE,QAAQ,CAAC;QAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAC;IAEF,MAAM,OAAO,GAAqB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAS,EAAE,IAAI,IAAI,EAAE;QACvC,IAAI,EAAE,CAAC,CAAC,KAAK;QACb,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3C,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,OAAO;QACP,KAAK;QACL,KAAK;QACL,iBAAiB;QACjB,gBAAgB;QAChB,qBAAqB;QACrB,mBAAmB;KACpB,CAAC;AACJ,CAAC"}
|
package/dist/esm/v3/chat.d.ts
CHANGED
|
@@ -52,6 +52,81 @@ export type ChatBaseURLResolver = (ctx: ChatTransportEndpointContext) => string;
|
|
|
52
52
|
* what `globalThis.fetch(url, init)` would have returned.
|
|
53
53
|
*/
|
|
54
54
|
export type ChatFetchOverride = (url: string, init: RequestInit, ctx: ChatTransportEndpointContext) => Promise<Response>;
|
|
55
|
+
/**
|
|
56
|
+
* Which transport path produced a send-lifecycle event: `useChat` sends,
|
|
57
|
+
* steering (`sendPendingMessage`), actions, stops, or the first-turn
|
|
58
|
+
* `headStart` POST.
|
|
59
|
+
*/
|
|
60
|
+
export type ChatTransportSendSource = "submit-message" | "regenerate-message" | "steer" | "action" | "stop" | "head-start";
|
|
61
|
+
/**
|
|
62
|
+
* Lifecycle events emitted through the transport's `onEvent` callback.
|
|
63
|
+
*
|
|
64
|
+
* Send events are terminal: `message-sent` fires when the append is
|
|
65
|
+
* durably acknowledged (2xx from the session input stream, after any
|
|
66
|
+
* internal token-refresh retries), `message-send-failed` when the send
|
|
67
|
+
* definitively failed. Response events follow the output stream:
|
|
68
|
+
* `stream-connected` when the SSE subscription opens, `first-chunk` on
|
|
69
|
+
* the first response chunk of a turn, `turn-completed` when the agent's
|
|
70
|
+
* turn-complete control record arrives, and `stream-error` when the
|
|
71
|
+
* stream fails unrecoverably.
|
|
72
|
+
*/
|
|
73
|
+
export type ChatTransportEvent = {
|
|
74
|
+
type: "message-sent";
|
|
75
|
+
chatId: string;
|
|
76
|
+
timestamp: number;
|
|
77
|
+
messageId?: string;
|
|
78
|
+
source: ChatTransportSendSource;
|
|
79
|
+
durationMs: number;
|
|
80
|
+
/** The append's idempotency key — also stored on the server-side record. */
|
|
81
|
+
partId?: string;
|
|
82
|
+
/** Serialized request body size in bytes. */
|
|
83
|
+
bodyBytes?: number;
|
|
84
|
+
} | {
|
|
85
|
+
type: "message-send-failed";
|
|
86
|
+
chatId: string;
|
|
87
|
+
timestamp: number;
|
|
88
|
+
messageId?: string;
|
|
89
|
+
source: ChatTransportSendSource;
|
|
90
|
+
error: Error;
|
|
91
|
+
status?: number;
|
|
92
|
+
durationMs: number;
|
|
93
|
+
partId?: string;
|
|
94
|
+
bodyBytes?: number;
|
|
95
|
+
} | {
|
|
96
|
+
type: "stream-connected";
|
|
97
|
+
chatId: string;
|
|
98
|
+
timestamp: number;
|
|
99
|
+
resumed: boolean;
|
|
100
|
+
/** The resume cursor the subscription connected from, if any. */
|
|
101
|
+
lastEventId?: string;
|
|
102
|
+
/** The last turn-producing send on this chat (client-side attribution). */
|
|
103
|
+
messageId?: string;
|
|
104
|
+
} | {
|
|
105
|
+
type: "stream-error";
|
|
106
|
+
chatId: string;
|
|
107
|
+
timestamp: number;
|
|
108
|
+
error: Error;
|
|
109
|
+
status?: number;
|
|
110
|
+
} | {
|
|
111
|
+
type: "first-chunk";
|
|
112
|
+
chatId: string;
|
|
113
|
+
timestamp: number;
|
|
114
|
+
chunkType?: string;
|
|
115
|
+
lastEventId?: string;
|
|
116
|
+
messageId?: string;
|
|
117
|
+
/** Milliseconds since the last turn-producing send on this chat (time to first token). */
|
|
118
|
+
sinceSendMs?: number;
|
|
119
|
+
} | {
|
|
120
|
+
type: "turn-completed";
|
|
121
|
+
chatId: string;
|
|
122
|
+
timestamp: number;
|
|
123
|
+
lastEventId?: string;
|
|
124
|
+
/** The agent's committed input-stream cursor from the turn-complete record. */
|
|
125
|
+
sessionInEventId?: string;
|
|
126
|
+
messageId?: string;
|
|
127
|
+
/** Milliseconds since the last turn-producing send on this chat (full turn latency). */
|
|
128
|
+
sinceSendMs?: number;
|
|
129
|
+
};
|
|
55
130
|
/**
|
|
56
131
|
* Arguments for the `accessToken` callback. The transport invokes this
|
|
57
132
|
* whenever it needs a fresh session-scoped PAT — initial use, and
|
|
@@ -204,6 +279,22 @@ export type TriggerChatTransportOptions<TClientData = unknown> = {
|
|
|
204
279
|
* ```
|
|
205
280
|
*/
|
|
206
281
|
fetch?: ChatFetchOverride;
|
|
282
|
+
/**
|
|
283
|
+
* Observability callback for transport lifecycle events (sends,
|
|
284
|
+
* stream connects, first chunk, turn completion). See
|
|
285
|
+
* {@link ChatTransportEvent} for the event catalog and semantics.
|
|
286
|
+
* Exceptions thrown by the callback are swallowed.
|
|
287
|
+
*
|
|
288
|
+
* @example Record send metrics:
|
|
289
|
+
* ```ts
|
|
290
|
+
* onEvent: (event) => {
|
|
291
|
+
* if (event.type === "message-sent") {
|
|
292
|
+
* metrics.timing("chat.send", event.durationMs);
|
|
293
|
+
* }
|
|
294
|
+
* },
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
onEvent?: (event: ChatTransportEvent) => void;
|
|
207
298
|
/** Additional headers included in every API request. */
|
|
208
299
|
headers?: Record<string, string>;
|
|
209
300
|
/**
|
|
@@ -305,9 +396,11 @@ export declare class TriggerChatTransport implements ChatTransport<UIMessage> {
|
|
|
305
396
|
private readonly headStart;
|
|
306
397
|
private coordinator;
|
|
307
398
|
private _onSessionChange;
|
|
399
|
+
private _onEvent;
|
|
308
400
|
private sessions;
|
|
309
401
|
private activeStreams;
|
|
310
402
|
private pendingStarts;
|
|
403
|
+
private lastTurnSends;
|
|
311
404
|
constructor(options: TriggerChatTransportOptions);
|
|
312
405
|
/**
|
|
313
406
|
* Eagerly create a Session and trigger its first run. Useful as a
|
|
@@ -382,6 +475,13 @@ export declare class TriggerChatTransport implements ChatTransport<UIMessage> {
|
|
|
382
475
|
getSession: (chatId: string) => ChatSessionPersistedState | undefined;
|
|
383
476
|
setSession(chatId: string, session: ChatSessionPersistedState): void;
|
|
384
477
|
setOnSessionChange(callback: ((chatId: string, session: ChatSessionPersistedState | null) => void) | undefined): void;
|
|
478
|
+
/** Update the `onEvent` callback without recreating the transport. */
|
|
479
|
+
setOnEvent(callback: ((event: ChatTransportEvent) => void) | undefined): void;
|
|
480
|
+
private emitEvent;
|
|
481
|
+
/** Run a send op, emitting the terminal message-sent / message-send-failed event. */
|
|
482
|
+
private sendWithEvents;
|
|
483
|
+
/** Attribution fields for response-side events. */
|
|
484
|
+
private turnAttribution;
|
|
385
485
|
/**
|
|
386
486
|
* Update the transport's `clientData`. Used by `useTriggerChatTransport`
|
|
387
487
|
* to keep the latest value reachable from inside `startSession` and
|
package/dist/esm/v3/chat.js
CHANGED
|
@@ -22,7 +22,10 @@
|
|
|
22
22
|
* }
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
import { controlSubtype, headerValue, PUBLIC_ACCESS_TOKEN_HEADER, SSEStreamSubscription, TRIGGER_CONTROL_SUBTYPE, } from "@trigger.dev/core/v3";
|
|
25
|
+
import { controlSubtype, headerValue, PUBLIC_ACCESS_TOKEN_HEADER, SESSION_IN_EVENT_ID_HEADER, SSEStreamSubscription, TRIGGER_CONTROL_SUBTYPE, } from "@trigger.dev/core/v3";
|
|
26
|
+
function byteLength(body) {
|
|
27
|
+
return new TextEncoder().encode(body).byteLength;
|
|
28
|
+
}
|
|
26
29
|
import { ChatTabCoordinator } from "./chat-tab-coordinator.js";
|
|
27
30
|
import { slimSubmitMessageForWire } from "./ai-shared.js";
|
|
28
31
|
const DEFAULT_BASE_URL = "https://api.trigger.dev";
|
|
@@ -140,9 +143,13 @@ export class TriggerChatTransport {
|
|
|
140
143
|
headStart;
|
|
141
144
|
coordinator = null;
|
|
142
145
|
_onSessionChange;
|
|
146
|
+
_onEvent;
|
|
143
147
|
sessions = new Map();
|
|
144
148
|
activeStreams = new Map();
|
|
145
149
|
pendingStarts = new Map();
|
|
150
|
+
// Last turn-producing send per chat — attribution source for the
|
|
151
|
+
// response-side events' `messageId` / `sinceSendMs`.
|
|
152
|
+
lastTurnSends = new Map();
|
|
146
153
|
constructor(options) {
|
|
147
154
|
this.taskId = options.task;
|
|
148
155
|
this.resolveAccessToken = options.accessToken;
|
|
@@ -158,6 +165,7 @@ export class TriggerChatTransport {
|
|
|
158
165
|
this.streamTimeoutSeconds = options.streamTimeoutSeconds ?? DEFAULT_STREAM_TIMEOUT_SECONDS;
|
|
159
166
|
this.defaultMetadata = options.clientData;
|
|
160
167
|
this._onSessionChange = options.onSessionChange;
|
|
168
|
+
this._onEvent = options.onEvent;
|
|
161
169
|
this.watchMode = options.watch ?? false;
|
|
162
170
|
this.headStart = options.headStart;
|
|
163
171
|
if (options.multiTab && !this.watchMode) {
|
|
@@ -282,10 +290,15 @@ export class TriggerChatTransport {
|
|
|
282
290
|
// Generated outside the closure so auth-retries reuse the same part id
|
|
283
291
|
// and the server-side dedupe sees one logical append.
|
|
284
292
|
const partId = crypto.randomUUID();
|
|
293
|
+
const serializedBody = this.serializeInputChunk({ kind: "message", payload: wirePayload });
|
|
285
294
|
const sendChatMessage = async (token) => {
|
|
286
|
-
await this.appendInputChunk(chatId, token,
|
|
295
|
+
await this.appendInputChunk(chatId, token, serializedBody, partId);
|
|
287
296
|
};
|
|
288
|
-
await this.
|
|
297
|
+
await this.sendWithEvents(chatId, trigger, {
|
|
298
|
+
messageId: messageId ?? messages.at(-1)?.id,
|
|
299
|
+
partId,
|
|
300
|
+
bodyBytes: byteLength(serializedBody),
|
|
301
|
+
}, () => this.callWithAuthRetry(chatId, state, sendChatMessage));
|
|
289
302
|
// Cancel any in-flight stream for this chat — the new turn supersedes it.
|
|
290
303
|
const activeStream = this.activeStreams.get(chatId);
|
|
291
304
|
if (activeStream) {
|
|
@@ -320,18 +333,27 @@ export class TriggerChatTransport {
|
|
|
320
333
|
messageId: args.messageId,
|
|
321
334
|
metadata: args.metadata,
|
|
322
335
|
};
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
336
|
+
let response;
|
|
337
|
+
const serializedBody = JSON.stringify(wirePayload);
|
|
338
|
+
await this.sendWithEvents(args.chatId, "head-start", {
|
|
339
|
+
messageId: args.messageId ?? args.messages.at(-1)?.id,
|
|
340
|
+
bodyBytes: byteLength(serializedBody),
|
|
341
|
+
}, async () => {
|
|
342
|
+
response = await fetch(this.headStart, {
|
|
343
|
+
method: "POST",
|
|
344
|
+
headers: {
|
|
345
|
+
"Content-Type": "application/json",
|
|
346
|
+
...this.extraHeaders,
|
|
347
|
+
},
|
|
348
|
+
body: serializedBody,
|
|
349
|
+
signal: args.abortSignal,
|
|
350
|
+
});
|
|
351
|
+
if (!response.ok) {
|
|
352
|
+
const err = new Error(`chat.handover endpoint returned ${response.status} ${response.statusText}`);
|
|
353
|
+
err.status = response.status;
|
|
354
|
+
throw err;
|
|
355
|
+
}
|
|
331
356
|
});
|
|
332
|
-
if (!response.ok) {
|
|
333
|
-
throw new Error(`chat.handover endpoint returned ${response.status} ${response.statusText}`);
|
|
334
|
-
}
|
|
335
357
|
if (!response.body) {
|
|
336
358
|
throw new Error("chat.handover endpoint returned no response body");
|
|
337
359
|
}
|
|
@@ -385,7 +407,17 @@ export class TriggerChatTransport {
|
|
|
385
407
|
notifyChange(chatId, state);
|
|
386
408
|
}
|
|
387
409
|
};
|
|
388
|
-
|
|
410
|
+
const emit = (event) => this.emitEvent(event);
|
|
411
|
+
const attribution = () => this.turnAttribution(chatId);
|
|
412
|
+
let sawFirstChunk = false;
|
|
413
|
+
emit({
|
|
414
|
+
type: "stream-connected",
|
|
415
|
+
chatId,
|
|
416
|
+
timestamp: Date.now(),
|
|
417
|
+
resumed: false,
|
|
418
|
+
messageId: this.lastTurnSends.get(chatId)?.messageId,
|
|
419
|
+
});
|
|
420
|
+
const piped = response.body
|
|
389
421
|
.pipeThrough(new TextDecoderStream())
|
|
390
422
|
.pipeThrough(parseUIMessageSseTransform())
|
|
391
423
|
.pipeThrough(new TransformStream({
|
|
@@ -394,6 +426,13 @@ export class TriggerChatTransport {
|
|
|
394
426
|
const type = chunk.type;
|
|
395
427
|
if (type === TRIGGER_TURN_COMPLETE) {
|
|
396
428
|
clearStreaming();
|
|
429
|
+
emit({
|
|
430
|
+
type: "turn-completed",
|
|
431
|
+
chatId,
|
|
432
|
+
timestamp: Date.now(),
|
|
433
|
+
lastEventId: sessions.get(chatId)?.lastEventId,
|
|
434
|
+
...attribution(),
|
|
435
|
+
});
|
|
397
436
|
return; // drop — not a real UIMessageChunk
|
|
398
437
|
}
|
|
399
438
|
if (type === TRIGGER_SESSION_STATE) {
|
|
@@ -404,12 +443,61 @@ export class TriggerChatTransport {
|
|
|
404
443
|
return; // drop
|
|
405
444
|
}
|
|
406
445
|
}
|
|
446
|
+
if (!sawFirstChunk) {
|
|
447
|
+
sawFirstChunk = true;
|
|
448
|
+
emit({
|
|
449
|
+
type: "first-chunk",
|
|
450
|
+
chatId,
|
|
451
|
+
timestamp: Date.now(),
|
|
452
|
+
chunkType: chunk?.type,
|
|
453
|
+
...attribution(),
|
|
454
|
+
});
|
|
455
|
+
}
|
|
407
456
|
controller.enqueue(chunk);
|
|
408
457
|
},
|
|
409
458
|
flush() {
|
|
410
459
|
clearStreaming();
|
|
411
460
|
},
|
|
412
461
|
}));
|
|
462
|
+
// Pump wrapper: a TransformStream can't observe upstream errors, so
|
|
463
|
+
// read here to emit stream-error (aborts close cleanly, matching the
|
|
464
|
+
// session subscribe path).
|
|
465
|
+
const pipedReader = piped.getReader();
|
|
466
|
+
return new ReadableStream({
|
|
467
|
+
async pull(controller) {
|
|
468
|
+
try {
|
|
469
|
+
const next = await pipedReader.read();
|
|
470
|
+
if (next.done) {
|
|
471
|
+
controller.close();
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
controller.enqueue(next.value);
|
|
475
|
+
}
|
|
476
|
+
catch (error) {
|
|
477
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
478
|
+
try {
|
|
479
|
+
controller.close();
|
|
480
|
+
}
|
|
481
|
+
catch {
|
|
482
|
+
/* already closed */
|
|
483
|
+
}
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const errorStatus = error.status;
|
|
487
|
+
emit({
|
|
488
|
+
type: "stream-error",
|
|
489
|
+
chatId,
|
|
490
|
+
timestamp: Date.now(),
|
|
491
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
492
|
+
status: typeof errorStatus === "number" ? errorStatus : undefined,
|
|
493
|
+
});
|
|
494
|
+
controller.error(error);
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
cancel(reason) {
|
|
498
|
+
return pipedReader.cancel(reason);
|
|
499
|
+
},
|
|
500
|
+
});
|
|
413
501
|
}
|
|
414
502
|
/**
|
|
415
503
|
* Send a steering message during an active stream without disrupting
|
|
@@ -430,11 +518,12 @@ export class TriggerChatTransport {
|
|
|
430
518
|
metadata: mergedMetadata,
|
|
431
519
|
};
|
|
432
520
|
const partId = crypto.randomUUID();
|
|
521
|
+
const serializedBody = this.serializeInputChunk({ kind: "message", payload: wirePayload });
|
|
433
522
|
const send = async (token) => {
|
|
434
|
-
await this.appendInputChunk(chatId, token,
|
|
523
|
+
await this.appendInputChunk(chatId, token, serializedBody, partId);
|
|
435
524
|
};
|
|
436
525
|
try {
|
|
437
|
-
await this.callWithAuthRetry(chatId, state, send);
|
|
526
|
+
await this.sendWithEvents(chatId, "steer", { messageId: message.id, partId, bodyBytes: byteLength(serializedBody) }, () => this.callWithAuthRetry(chatId, state, send));
|
|
438
527
|
return true;
|
|
439
528
|
}
|
|
440
529
|
catch {
|
|
@@ -460,6 +549,7 @@ export class TriggerChatTransport {
|
|
|
460
549
|
? AbortSignal.any([options.abortSignal, abortController.signal])
|
|
461
550
|
: abortController.signal;
|
|
462
551
|
return this.subscribeToSessionStream(state, abortSignal, options.chatId, {
|
|
552
|
+
resumed: true,
|
|
463
553
|
sendStopOnAbort: !!options.abortSignal,
|
|
464
554
|
// Reconnect-on-reload opts into the server's settled-peek shortcut
|
|
465
555
|
// so the SSE doesn't hang for 60s when no turn is in flight. Active
|
|
@@ -478,11 +568,12 @@ export class TriggerChatTransport {
|
|
|
478
568
|
if (!state)
|
|
479
569
|
return false;
|
|
480
570
|
const partId = crypto.randomUUID();
|
|
571
|
+
const serializedBody = this.serializeInputChunk({ kind: "stop" });
|
|
481
572
|
const send = async (token) => {
|
|
482
|
-
await this.appendInputChunk(chatId, token,
|
|
573
|
+
await this.appendInputChunk(chatId, token, serializedBody, partId);
|
|
483
574
|
};
|
|
484
575
|
try {
|
|
485
|
-
await this.callWithAuthRetry(chatId, state, send);
|
|
576
|
+
await this.sendWithEvents(chatId, "stop", { partId, bodyBytes: byteLength(serializedBody) }, () => this.callWithAuthRetry(chatId, state, send));
|
|
486
577
|
}
|
|
487
578
|
catch {
|
|
488
579
|
return false;
|
|
@@ -528,7 +619,7 @@ export class TriggerChatTransport {
|
|
|
528
619
|
const send = async (token) => {
|
|
529
620
|
await this.appendInputChunk(chatId, token, body, partId);
|
|
530
621
|
};
|
|
531
|
-
await this.callWithAuthRetry(chatId, state, send);
|
|
622
|
+
await this.sendWithEvents(chatId, "action", { partId, bodyBytes: byteLength(body) }, () => this.callWithAuthRetry(chatId, state, send));
|
|
532
623
|
// Supersede any in-flight reader before subscribing — same as
|
|
533
624
|
// `sendMessages`. Two concurrent readers both write `state.lastEventId`
|
|
534
625
|
// and the slower one can regress the cursor, replaying records on the
|
|
@@ -564,6 +655,61 @@ export class TriggerChatTransport {
|
|
|
564
655
|
setOnSessionChange(callback) {
|
|
565
656
|
this._onSessionChange = callback;
|
|
566
657
|
}
|
|
658
|
+
/** Update the `onEvent` callback without recreating the transport. */
|
|
659
|
+
setOnEvent(callback) {
|
|
660
|
+
this._onEvent = callback;
|
|
661
|
+
}
|
|
662
|
+
emitEvent(event) {
|
|
663
|
+
const cb = this._onEvent;
|
|
664
|
+
if (!cb)
|
|
665
|
+
return;
|
|
666
|
+
try {
|
|
667
|
+
cb(event);
|
|
668
|
+
}
|
|
669
|
+
catch {
|
|
670
|
+
// observability must never break the chat
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
/** Run a send op, emitting the terminal message-sent / message-send-failed event. */
|
|
674
|
+
async sendWithEvents(chatId, source, extras, op) {
|
|
675
|
+
const startedAt = Date.now();
|
|
676
|
+
try {
|
|
677
|
+
await op();
|
|
678
|
+
const turnProducing = source === "submit-message" || source === "regenerate-message" || source === "head-start";
|
|
679
|
+
if (turnProducing) {
|
|
680
|
+
this.lastTurnSends.set(chatId, { messageId: extras.messageId, at: Date.now() });
|
|
681
|
+
}
|
|
682
|
+
this.emitEvent({
|
|
683
|
+
type: "message-sent",
|
|
684
|
+
chatId,
|
|
685
|
+
timestamp: Date.now(),
|
|
686
|
+
source,
|
|
687
|
+
durationMs: Date.now() - startedAt,
|
|
688
|
+
...extras,
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
catch (error) {
|
|
692
|
+
const status = error.status;
|
|
693
|
+
this.emitEvent({
|
|
694
|
+
type: "message-send-failed",
|
|
695
|
+
chatId,
|
|
696
|
+
timestamp: Date.now(),
|
|
697
|
+
source,
|
|
698
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
699
|
+
status: typeof status === "number" ? status : undefined,
|
|
700
|
+
durationMs: Date.now() - startedAt,
|
|
701
|
+
...extras,
|
|
702
|
+
});
|
|
703
|
+
throw error;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
/** Attribution fields for response-side events. */
|
|
707
|
+
turnAttribution(chatId) {
|
|
708
|
+
const lastSend = this.lastTurnSends.get(chatId);
|
|
709
|
+
if (!lastSend)
|
|
710
|
+
return {};
|
|
711
|
+
return { messageId: lastSend.messageId, sinceSendMs: Date.now() - lastSend.at };
|
|
712
|
+
}
|
|
567
713
|
/**
|
|
568
714
|
* Update the transport's `clientData`. Used by `useTriggerChatTransport`
|
|
569
715
|
* to keep the latest value reachable from inside `startSession` and
|
|
@@ -930,6 +1076,15 @@ export class TriggerChatTransport {
|
|
|
930
1076
|
throw e;
|
|
931
1077
|
}
|
|
932
1078
|
}
|
|
1079
|
+
this.emitEvent({
|
|
1080
|
+
type: "stream-connected",
|
|
1081
|
+
chatId,
|
|
1082
|
+
timestamp: Date.now(),
|
|
1083
|
+
resumed: options?.resumed ?? false,
|
|
1084
|
+
lastEventId: state.lastEventId,
|
|
1085
|
+
messageId: this.lastTurnSends.get(chatId)?.messageId,
|
|
1086
|
+
});
|
|
1087
|
+
let sawFirstChunk = false;
|
|
933
1088
|
while (true) {
|
|
934
1089
|
let value;
|
|
935
1090
|
if (primed !== undefined) {
|
|
@@ -1001,12 +1156,22 @@ export class TriggerChatTransport {
|
|
|
1001
1156
|
if (refreshedToken) {
|
|
1002
1157
|
state.publicAccessToken = refreshedToken;
|
|
1003
1158
|
}
|
|
1159
|
+
this.emitEvent({
|
|
1160
|
+
type: "turn-completed",
|
|
1161
|
+
chatId,
|
|
1162
|
+
timestamp: Date.now(),
|
|
1163
|
+
lastEventId: state.lastEventId,
|
|
1164
|
+
sessionInEventId: headerValue(value.headers, SESSION_IN_EVENT_ID_HEADER),
|
|
1165
|
+
...this.turnAttribution(chatId),
|
|
1166
|
+
});
|
|
1004
1167
|
state.isStreaming = false;
|
|
1005
1168
|
this.notifySessionChange(chatId, state);
|
|
1006
1169
|
this.coordinator?.release(chatId);
|
|
1007
1170
|
this.coordinator?.broadcastSession(chatId, {
|
|
1008
1171
|
lastEventId: state.lastEventId,
|
|
1009
1172
|
});
|
|
1173
|
+
// Re-arm per-turn events for watch mode's next turn.
|
|
1174
|
+
sawFirstChunk = false;
|
|
1010
1175
|
if (this.watchMode)
|
|
1011
1176
|
continue;
|
|
1012
1177
|
internalAbort.abort();
|
|
@@ -1023,6 +1188,17 @@ export class TriggerChatTransport {
|
|
|
1023
1188
|
// JSON unwrap). Drop empty/malformed payloads defensively.
|
|
1024
1189
|
if (value.chunk == null)
|
|
1025
1190
|
continue;
|
|
1191
|
+
if (!sawFirstChunk) {
|
|
1192
|
+
sawFirstChunk = true;
|
|
1193
|
+
this.emitEvent({
|
|
1194
|
+
type: "first-chunk",
|
|
1195
|
+
chatId,
|
|
1196
|
+
timestamp: Date.now(),
|
|
1197
|
+
chunkType: value.chunk.type,
|
|
1198
|
+
lastEventId: value.id || undefined,
|
|
1199
|
+
...this.turnAttribution(chatId),
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1026
1202
|
controller.enqueue(value.chunk);
|
|
1027
1203
|
}
|
|
1028
1204
|
}
|
|
@@ -1036,6 +1212,14 @@ export class TriggerChatTransport {
|
|
|
1036
1212
|
}
|
|
1037
1213
|
return;
|
|
1038
1214
|
}
|
|
1215
|
+
const errorStatus = error.status;
|
|
1216
|
+
this.emitEvent({
|
|
1217
|
+
type: "stream-error",
|
|
1218
|
+
chatId,
|
|
1219
|
+
timestamp: Date.now(),
|
|
1220
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
1221
|
+
status: typeof errorStatus === "number" ? errorStatus : undefined,
|
|
1222
|
+
});
|
|
1039
1223
|
controller.error(error);
|
|
1040
1224
|
}
|
|
1041
1225
|
finally {
|