agents 0.26.0 → 0.28.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.
- package/README.md +8 -9
- package/dist/abortable-C1SpfVoi.js +21 -0
- package/dist/abortable-C1SpfVoi.js.map +1 -0
- package/dist/{agent-routing-0DR0Tk2v.d.ts → agent-routing-QDcchcQP.d.ts} +16 -16
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-YrATZJu2.d.ts → agent-tools-DHL2XI7u.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/ai-ahruGw7e.d.ts +239 -0
- package/dist/ai-sdk-Bdsf6mSA.js +2444 -0
- package/dist/ai-sdk-Bdsf6mSA.js.map +1 -0
- package/dist/apply-chunks-1FheRb9W.js +99 -0
- package/dist/apply-chunks-1FheRb9W.js.map +1 -0
- package/dist/broadcast-state-CEyI4uAK.js +69 -0
- package/dist/broadcast-state-CEyI4uAK.js.map +1 -0
- package/dist/browser/ai.d.ts +8 -227
- package/dist/browser/ai.js +259 -1
- package/dist/browser/ai.js.map +1 -0
- package/dist/browser/index.d.ts +56 -46
- package/dist/browser/index.js +4 -361
- package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
- package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +6 -5
- package/dist/browser/tools/ai-sdk.js.map +1 -0
- package/dist/browser/tools/pi.d.ts +111 -0
- package/dist/browser/tools/pi.js +119 -0
- package/dist/browser/tools/pi.js.map +1 -0
- package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
- package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
- package/dist/browser/tools/tanstack-ai.js.map +1 -0
- package/dist/browser-CEdNlsaD.js +481 -0
- package/dist/browser-CEdNlsaD.js.map +1 -0
- package/dist/{browser-DE3d-RLk.d.ts → browser-D30VlpcA.d.ts} +63 -37
- package/dist/{browser-tool-CQ10e6Kj.js → browser-tool-4iomavs_.js} +198 -62
- package/dist/browser-tool-4iomavs_.js.map +1 -0
- package/dist/{browser-tool-DuNdlwZ9.d.ts → browser-tool-vtrPOV8e.d.ts} +25 -6
- package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
- package/dist/capability-DBAKc6UZ.js.map +1 -0
- package/dist/{capability-runner-DBAnGr6L.d.ts → capability-runner-BiVUtjqC.d.ts} +9 -7
- package/dist/channel-Bak_6zDP.d.ts +333 -0
- package/dist/chat/index.d.ts +11 -9
- package/dist/chat/index.js +5 -194
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +2 -4
- package/dist/chat/react.js +3 -1
- package/dist/chat/react.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/chat-sdk/index.js +1 -1
- package/dist/cli.js +144 -0
- package/dist/{client-je3koD9Z.d.ts → client-BGIQKJhX.d.ts} +2 -2
- package/dist/{client-fyQrLGkD.js → client-BnYbNT3z.js} +29 -5
- package/dist/client-BnYbNT3z.js.map +1 -0
- package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
- package/dist/client.d.ts +1 -1
- package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
- package/dist/connector-CtZylXdk.js.map +1 -0
- package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
- package/dist/conversations-FjHDRZyD.d.ts +192 -0
- package/dist/{current-agent-vAk_5JMt.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/daemon-core-Buubj-y1.js +481 -0
- package/dist/daemon-core-Buubj-y1.js.map +1 -0
- package/dist/daemon-core-CbohVPAu.d.ts +132 -0
- package/dist/{do-oauth-client-provider-Tmf1vgKz.d.ts → do-oauth-client-provider-DfsUcpc3.d.ts} +7 -1
- package/dist/{durable-object-lifecycle-HhgOMWq9.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
- package/dist/{channels/email.d.ts → experimental/channels/email/index.d.ts} +25 -12
- package/dist/{channels/email.js → experimental/channels/email/index.js} +13 -35
- package/dist/experimental/channels/email/index.js.map +1 -0
- package/dist/experimental/channels/index.d.ts +270 -0
- package/dist/experimental/channels/index.js +1186 -0
- package/dist/experimental/channels/index.js.map +1 -0
- package/dist/{channels/slack.d.ts → experimental/channels/slack/index.d.ts} +19 -9
- package/dist/experimental/channels/slack/index.js +267 -0
- package/dist/experimental/channels/slack/index.js.map +1 -0
- package/dist/{channels/telegram.d.ts → experimental/channels/telegram/index.d.ts} +19 -9
- package/dist/experimental/channels/telegram/index.js +198 -0
- package/dist/experimental/channels/telegram/index.js.map +1 -0
- package/dist/experimental/channels/web/ai-sdk.d.ts +55 -0
- package/dist/experimental/channels/web/ai-sdk.js +266 -0
- package/dist/experimental/channels/web/ai-sdk.js.map +1 -0
- package/dist/experimental/channels/web/client.d.ts +97 -0
- package/dist/experimental/channels/web/client.js +349 -0
- package/dist/experimental/channels/web/client.js.map +1 -0
- package/dist/experimental/channels/web/index.d.ts +189 -0
- package/dist/experimental/channels/web/index.js +332 -0
- package/dist/experimental/channels/web/index.js.map +1 -0
- package/dist/gateway-BFO6vRDn.d.ts +100 -0
- package/dist/handle-zAzh0UW2.d.ts +460 -0
- package/dist/harness/ai-sdk/index.d.ts +175 -0
- package/dist/harness/ai-sdk/index.js +605 -0
- package/dist/harness/ai-sdk/index.js.map +1 -0
- package/dist/harness/container/daemon/index.d.ts +76 -0
- package/dist/harness/container/daemon/index.js +3 -0
- package/dist/harness/container/index.d.ts +740 -0
- package/dist/harness/container/index.js +2152 -0
- package/dist/harness/container/index.js.map +1 -0
- package/dist/harness/container/runtime/index.d.ts +144 -0
- package/dist/harness/container/runtime/index.js +1082 -0
- package/dist/harness/container/runtime/index.js.map +1 -0
- package/dist/harness/opencode/index.d.ts +369 -0
- package/dist/harness/opencode/index.js +1072 -0
- package/dist/harness/opencode/index.js.map +1 -0
- package/dist/harness/pi/index.d.ts +3 -2
- package/dist/harness/pi/index.js +3 -3
- package/dist/harness/store/index.d.ts +24 -0
- package/dist/harness/store/index.js +2 -0
- package/dist/harness/think/index.d.ts +821 -0
- package/dist/harness/think/index.js +2721 -0
- package/dist/harness/think/index.js.map +1 -0
- package/dist/harness-B6B9S3rb.d.ts +203 -0
- package/dist/{images-iiTDSyRu.js → images-Ce9SCu3X.js} +2 -248
- package/dist/images-Ce9SCu3X.js.map +1 -0
- package/dist/{index-BreL0YrQ.d.ts → index-BEL3ZV-s.d.ts} +2 -6
- package/dist/index-CBt8oRJt.d.ts +198 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/ingress-EFbrS547.js +9 -0
- package/dist/ingress-EFbrS547.js.map +1 -0
- package/dist/input-schema-BQykTEp_.js +20 -0
- package/dist/input-schema-BQykTEp_.js.map +1 -0
- package/dist/input-schema-D2QAtHZH.js +23 -0
- package/dist/input-schema-D2QAtHZH.js.map +1 -0
- package/dist/internal-kmw70xwR.js +46 -0
- package/dist/internal-kmw70xwR.js.map +1 -0
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +3 -3
- package/dist/lifecycle/index.js +2 -2
- package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
- package/dist/lifecycle-DGorpAmA.js.map +1 -0
- package/dist/mcp/client/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/client/do-oauth-client-provider.js +9 -0
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/client/index.d.ts +1 -1
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/client/x402.d.ts +35 -4
- package/dist/mcp/client/x402.js +24 -3
- package/dist/mcp/client/x402.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/models/ai-sdk/index.d.ts +16 -14
- package/dist/models/ai-sdk/index.js +1 -2442
- package/dist/models/opencode/index.d.ts +65 -0
- package/dist/models/opencode/index.js +285 -0
- package/dist/models/opencode/index.js.map +1 -0
- package/dist/models/pi-ai/index.d.ts +9 -7
- package/dist/models/pi-ai/index.js +2 -1
- package/dist/models/pi-ai/index.js.map +1 -1
- package/dist/options-CiIsJHXR.d.ts +130 -0
- package/dist/protocol-BEgrJYC5.d.ts +331 -0
- package/dist/protocol-CukuI73M.d.ts +386 -0
- package/dist/protocol-cOklVBBD.js +227 -0
- package/dist/protocol-cOklVBBD.js.map +1 -0
- package/dist/{protocol-kHsr-f0X.js → protocol-eXeJxhgu.js} +2 -67
- package/dist/protocol-eXeJxhgu.js.map +1 -0
- package/dist/protocol-y2sSY584.js +148 -0
- package/dist/protocol-y2sSY584.js.map +1 -0
- package/dist/queue/index.d.ts +1 -1
- package/dist/queue/index.js +1 -1
- package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
- package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
- package/dist/react.d.ts +2 -2
- package/dist/routing/index.d.ts +2 -2
- package/dist/routing/index.js +1 -1
- package/dist/{scheduler-RdACNXDP.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
- package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
- package/dist/scheduler-FIHv2-kJ.js.map +1 -0
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/session-store-Do4xkDcf.js +606 -0
- package/dist/session-store-Do4xkDcf.js.map +1 -0
- package/dist/session-store-DoPY12xM.d.ts +383 -0
- package/dist/sessions/index.d.ts +11 -434
- package/dist/sessions/index.js +1 -2271
- package/dist/sessions-_vN5BEZX.js +2272 -0
- package/dist/sessions-_vN5BEZX.js.map +1 -0
- package/dist/settings-C45hDliX.js +253 -0
- package/dist/settings-C45hDliX.js.map +1 -0
- package/dist/{transport-PfFnt-Ld.d.ts → settings-NgGwF7Qt.d.ts} +14 -208
- package/dist/{src-BZeu-SCD.js → src-CQxJFv4l.js} +8 -8
- package/dist/src-CQxJFv4l.js.map +1 -0
- package/dist/stall-watchdog-BpRF2uwG.js +195 -0
- package/dist/stall-watchdog-BpRF2uwG.js.map +1 -0
- package/dist/state/index.d.ts +1 -1
- package/dist/state/index.js +1 -3
- package/dist/state/index.js.map +1 -1
- package/dist/store-BKM4Xm9M.d.ts +332 -0
- package/dist/store-CslVzfN7.js +458 -0
- package/dist/store-CslVzfN7.js.map +1 -0
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/{streams-DW-UCOUc.js → streams-lsHMJhRW.js} +17 -4
- package/dist/streams-lsHMJhRW.js.map +1 -0
- package/dist/{streams-Cmkj9QfW.d.ts → streams-vrCtbUIn.d.ts} +2 -2
- package/dist/sub-routing.d.ts +1 -1
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/{tasks-68DESxf0.js → tasks-BN_5AWqI.js} +3 -2
- package/dist/tasks-BN_5AWqI.js.map +1 -0
- package/dist/{tasks-9YxYtByh.d.ts → tasks-E89KdwkS.d.ts} +2 -2
- package/dist/tool-CTp72Jb_.d.ts +278 -0
- package/dist/tool-CxKsvxjm.js +1126 -0
- package/dist/tool-CxKsvxjm.js.map +1 -0
- package/dist/tool-DoVberpN.d.ts +301 -0
- package/dist/tool-cQRkwSZZ.js +410 -0
- package/dist/tool-cQRkwSZZ.js.map +1 -0
- package/dist/tool-helpers-O5BDVEAY.js +58 -0
- package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
- package/dist/transport-k2mFrtL8.d.ts +200 -0
- package/dist/turns-DCV3ycDl.js +317 -0
- package/dist/turns-DCV3ycDl.js.map +1 -0
- package/dist/voice/client.js +1 -1
- package/dist/voice/index.d.ts +2 -2
- package/dist/voice/index.js +1 -1
- package/dist/web/fetch/index.d.ts +89 -0
- package/dist/web/fetch/index.js +20 -0
- package/dist/web/fetch/index.js.map +1 -0
- package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
- package/dist/web/fetch/tools/ai-sdk.js +47 -0
- package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
- package/dist/web/fetch/tools/pi.d.ts +84 -0
- package/dist/web/fetch/tools/pi.js +88 -0
- package/dist/web/fetch/tools/pi.js.map +1 -0
- package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
- package/dist/web/fetch/tools/tanstack-ai.js +45 -0
- package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
- package/dist/web/search/index.d.ts +58 -0
- package/dist/web/search/index.js +2 -0
- package/dist/web/search/tools/ai-sdk.d.ts +77 -0
- package/dist/web/search/tools/ai-sdk.js +46 -0
- package/dist/web/search/tools/ai-sdk.js.map +1 -0
- package/dist/web/search/tools/pi.d.ts +82 -0
- package/dist/web/search/tools/pi.js +89 -0
- package/dist/web/search/tools/pi.js.map +1 -0
- package/dist/web/search/tools/tanstack-ai.d.ts +71 -0
- package/dist/web/search/tools/tanstack-ai.js +46 -0
- package/dist/web/search/tools/tanstack-ai.js.map +1 -0
- package/dist/websockets/index.d.ts +12 -296
- package/dist/websockets/index.js +1 -1
- package/dist/{websockets-Ci-LZFHH.js → websockets-C3zy8YR0.js} +20 -8
- package/dist/websockets-C3zy8YR0.js.map +1 -0
- package/dist/{wire-types-CrjKvDyi.d.ts → wire-types-Cv0iwjk5.d.ts} +3 -51
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/dist/workflows.js +1 -1
- package/docs/browse-the-web.md +29 -1
- package/docs/fetch-the-web.md +276 -0
- package/docs/harnesses/pi.md +25 -0
- package/docs/harnesses/think.md +215 -0
- package/docs/index.md +99 -75
- package/docs/lifecycle.md +42 -3
- package/docs/queue.md +2 -3
- package/docs/scheduling.md +2 -6
- package/docs/search-the-web.md +135 -0
- package/package.json +148 -44
- package/dist/ai-fm7xx1BK.js +0 -312
- package/dist/ai-fm7xx1BK.js.map +0 -1
- package/dist/browser/ai-sdk.js.map +0 -1
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/tanstack-ai.js.map +0 -1
- package/dist/browser-tool-CQ10e6Kj.js.map +0 -1
- package/dist/capability-B4WbF81e.js.map +0 -1
- package/dist/channel-Bnm4S7T2.d.ts +0 -491
- package/dist/channels/ai-sdk.d.ts +0 -46
- package/dist/channels/ai-sdk.js +0 -120
- package/dist/channels/ai-sdk.js.map +0 -1
- package/dist/channels/email.js.map +0 -1
- package/dist/channels/index.d.ts +0 -233
- package/dist/channels/index.js +0 -608
- package/dist/channels/index.js.map +0 -1
- package/dist/channels/slack.js +0 -614
- package/dist/channels/slack.js.map +0 -1
- package/dist/channels/tanstack-ai.d.ts +0 -39
- package/dist/channels/tanstack-ai.js +0 -17
- package/dist/channels/tanstack-ai.js.map +0 -1
- package/dist/channels/telegram.js +0 -427
- package/dist/channels/telegram.js.map +0 -1
- package/dist/channels/voice.d.ts +0 -45
- package/dist/channels/voice.js +0 -122
- package/dist/channels/voice.js.map +0 -1
- package/dist/client-fyQrLGkD.js.map +0 -1
- package/dist/connector-58XDGvc3.js.map +0 -1
- package/dist/images-iiTDSyRu.js.map +0 -1
- package/dist/index-BB0kqhIz.d.ts +0 -101
- package/dist/ingress-BfetZbMO.js +0 -83
- package/dist/ingress-BfetZbMO.js.map +0 -1
- package/dist/internal-CYlgHl1l.js +0 -59
- package/dist/internal-CYlgHl1l.js.map +0 -1
- package/dist/lifecycle-CFu6OV03.js.map +0 -1
- package/dist/models/ai-sdk/index.js.map +0 -1
- package/dist/protocol-kHsr-f0X.js.map +0 -1
- package/dist/scheduler-DZ3xQfeK.js.map +0 -1
- package/dist/sessions/index.js.map +0 -1
- package/dist/src-BZeu-SCD.js.map +0 -1
- package/dist/streams-DW-UCOUc.js.map +0 -1
- package/dist/surface-bZZJqBka.js +0 -17
- package/dist/surface-bZZJqBka.js.map +0 -1
- package/dist/tasks-68DESxf0.js.map +0 -1
- package/dist/tool-schema-CBjGPrsQ.js +0 -31
- package/dist/tool-schema-CBjGPrsQ.js.map +0 -1
- package/dist/websockets-Ci-LZFHH.js.map +0 -1
- package/docs/channels.md +0 -323
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
_ as TranscriptMessage,
|
|
3
|
+
c as InboundEvent,
|
|
4
|
+
m as ResponseChunk,
|
|
5
|
+
n as ConversationInfo,
|
|
6
|
+
p as Participant,
|
|
7
|
+
r as ConversationOperation,
|
|
8
|
+
y as TurnStatus
|
|
9
|
+
} from "../../../protocol-CukuI73M.js";
|
|
10
|
+
|
|
11
|
+
//#region src/experimental/channels/web/client.d.ts
|
|
12
|
+
type WebChannelClientState = {
|
|
13
|
+
connected: boolean /** The conversation this client follows, once connected. */;
|
|
14
|
+
conversationId?: string /** Conversation operations this client may send. */;
|
|
15
|
+
operations: ConversationOperation[];
|
|
16
|
+
you?: Participant /** The transcript, with the output of running turns applied. */;
|
|
17
|
+
messages: TranscriptMessage[] /** Turns that are queued, running or awaiting input. */;
|
|
18
|
+
turns: TurnStatus[] /** The agent's conversations, once listed or pushed. */;
|
|
19
|
+
conversations?: ConversationInfo[];
|
|
20
|
+
};
|
|
21
|
+
/** An inbound event; the client fills in `eventId` when it is left out. */
|
|
22
|
+
type ClientEvent = InboundEvent extends infer E
|
|
23
|
+
? E extends {
|
|
24
|
+
eventId: string;
|
|
25
|
+
}
|
|
26
|
+
? Omit<E, "eventId"> & {
|
|
27
|
+
eventId?: string;
|
|
28
|
+
}
|
|
29
|
+
: never
|
|
30
|
+
: never;
|
|
31
|
+
/** Turn statuses and response output, frame by frame. */
|
|
32
|
+
type WebChannelActivity =
|
|
33
|
+
| {
|
|
34
|
+
type: "turn";
|
|
35
|
+
turn: TurnStatus;
|
|
36
|
+
}
|
|
37
|
+
| {
|
|
38
|
+
type: "chunks";
|
|
39
|
+
responseId: string;
|
|
40
|
+
turnId: string;
|
|
41
|
+
chunks: ResponseChunk[];
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
type: "end";
|
|
45
|
+
responseId: string;
|
|
46
|
+
turnId: string;
|
|
47
|
+
state: "ended" | "interrupted" | "not-found";
|
|
48
|
+
};
|
|
49
|
+
type WebChannelClientOptions = {
|
|
50
|
+
/**
|
|
51
|
+
* The URL to reconnect to once the client follows another conversation.
|
|
52
|
+
* Default: the gateway's default, `/channels/<route>/<conversation>`.
|
|
53
|
+
*/
|
|
54
|
+
followUrl?(url: URL, conversationId: string): URL;
|
|
55
|
+
};
|
|
56
|
+
/** A browser client for the Web Channel, with reconnects. */
|
|
57
|
+
declare class WebChannelClient {
|
|
58
|
+
#private;
|
|
59
|
+
constructor(url: string | URL, options?: WebChannelClientOptions);
|
|
60
|
+
get state(): WebChannelClientState;
|
|
61
|
+
/** Calls the listener on every change. Returns the unsubscribe. */
|
|
62
|
+
subscribe(listener: (state: WebChannelClientState) => void): () => void;
|
|
63
|
+
/**
|
|
64
|
+
* Calls the listener with each turn status, response chunk and response
|
|
65
|
+
* ending as it arrives, including chunks that arrive after the turn has
|
|
66
|
+
* settled. Returns the unsubscribe.
|
|
67
|
+
*/
|
|
68
|
+
onActivity(listener: (activity: WebChannelActivity) => void): () => void;
|
|
69
|
+
/** The chunks received so far for a response this client is reading. */
|
|
70
|
+
chunksOf(responseId: string): readonly ResponseChunk[] | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Resolves once the agent accepts the event, and rejects if it refuses.
|
|
73
|
+
* While disconnected the event waits, and it is sent again after a
|
|
74
|
+
* reconnect until acknowledged; Channels drops repeats by `eventId`.
|
|
75
|
+
* Rejects once the client is closed.
|
|
76
|
+
*/
|
|
77
|
+
send(event: ClientEvent): Promise<void>;
|
|
78
|
+
/** The agent's conversations. Rejects while disconnected or closed. */
|
|
79
|
+
listConversations(): Promise<ConversationInfo[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Follow another conversation: reconnect to it, as after a create or
|
|
82
|
+
* fork. Events still waiting for an ack are rejected, since they were
|
|
83
|
+
* meant for the conversation left behind.
|
|
84
|
+
*/
|
|
85
|
+
follow(conversationId: string): void;
|
|
86
|
+
/** Closes the connection and rejects events still waiting for an ack. */
|
|
87
|
+
close(): void;
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
export {
|
|
91
|
+
ClientEvent,
|
|
92
|
+
WebChannelActivity,
|
|
93
|
+
WebChannelClient,
|
|
94
|
+
WebChannelClientOptions,
|
|
95
|
+
WebChannelClientState
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "../../../classPrivateFieldGet2-DZBYAB34.js";
|
|
2
|
+
import { t as _classPrivateMethodInitSpec } from "../../../classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
3
|
+
import { t as applyChunks } from "../../../apply-chunks-1FheRb9W.js";
|
|
4
|
+
//#region src/experimental/channels/web/client.ts
|
|
5
|
+
var _url = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
var _followUrl = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
var _conversationId = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
var _operations = /* @__PURE__ */ new WeakMap();
|
|
9
|
+
var _socket = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
var _closed = /* @__PURE__ */ new WeakMap();
|
|
11
|
+
var _connected = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
var _reconnect = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
var _you = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
var _transcript = /* @__PURE__ */ new WeakMap();
|
|
15
|
+
var _turns = /* @__PURE__ */ new WeakMap();
|
|
16
|
+
var _responses = /* @__PURE__ */ new WeakMap();
|
|
17
|
+
var _outbox = /* @__PURE__ */ new WeakMap();
|
|
18
|
+
var _conversations = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
var _lists = /* @__PURE__ */ new WeakMap();
|
|
20
|
+
var _listeners = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
var _activity = /* @__PURE__ */ new WeakMap();
|
|
22
|
+
var _state = /* @__PURE__ */ new WeakMap();
|
|
23
|
+
var _WebChannelClient_brand = /* @__PURE__ */ new WeakSet();
|
|
24
|
+
/** A browser client for the Web Channel, with reconnects. */
|
|
25
|
+
var WebChannelClient = class {
|
|
26
|
+
constructor(url, options = {}) {
|
|
27
|
+
_classPrivateMethodInitSpec(this, _WebChannelClient_brand);
|
|
28
|
+
_classPrivateFieldInitSpec(this, _url, void 0);
|
|
29
|
+
_classPrivateFieldInitSpec(this, _followUrl, void 0);
|
|
30
|
+
_classPrivateFieldInitSpec(this, _conversationId, void 0);
|
|
31
|
+
_classPrivateFieldInitSpec(this, _operations, []);
|
|
32
|
+
_classPrivateFieldInitSpec(this, _socket, void 0);
|
|
33
|
+
_classPrivateFieldInitSpec(this, _closed, false);
|
|
34
|
+
_classPrivateFieldInitSpec(this, _connected, false);
|
|
35
|
+
_classPrivateFieldInitSpec(this, _reconnect, void 0);
|
|
36
|
+
_classPrivateFieldInitSpec(this, _you, void 0);
|
|
37
|
+
_classPrivateFieldInitSpec(this, _transcript, []);
|
|
38
|
+
_classPrivateFieldInitSpec(this, _turns, /* @__PURE__ */ new Map());
|
|
39
|
+
_classPrivateFieldInitSpec(this, _responses, /* @__PURE__ */ new Map());
|
|
40
|
+
_classPrivateFieldInitSpec(this, _outbox, /* @__PURE__ */ new Map());
|
|
41
|
+
_classPrivateFieldInitSpec(this, _conversations, void 0);
|
|
42
|
+
_classPrivateFieldInitSpec(this, _lists, /* @__PURE__ */ new Map());
|
|
43
|
+
_classPrivateFieldInitSpec(this, _listeners, /* @__PURE__ */ new Set());
|
|
44
|
+
_classPrivateFieldInitSpec(this, _activity, /* @__PURE__ */ new Set());
|
|
45
|
+
_classPrivateFieldInitSpec(this, _state, {
|
|
46
|
+
connected: false,
|
|
47
|
+
operations: [],
|
|
48
|
+
messages: [],
|
|
49
|
+
turns: []
|
|
50
|
+
});
|
|
51
|
+
_classPrivateFieldSet2(_url, this, String(url));
|
|
52
|
+
_classPrivateFieldSet2(_followUrl, this, options.followUrl ?? defaultFollowUrl);
|
|
53
|
+
_assertClassBrand(_WebChannelClient_brand, this, _connect).call(this);
|
|
54
|
+
}
|
|
55
|
+
get state() {
|
|
56
|
+
return _classPrivateFieldGet2(_state, this);
|
|
57
|
+
}
|
|
58
|
+
/** Calls the listener on every change. Returns the unsubscribe. */
|
|
59
|
+
subscribe(listener) {
|
|
60
|
+
_classPrivateFieldGet2(_listeners, this).add(listener);
|
|
61
|
+
return () => _classPrivateFieldGet2(_listeners, this).delete(listener);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Calls the listener with each turn status, response chunk and response
|
|
65
|
+
* ending as it arrives, including chunks that arrive after the turn has
|
|
66
|
+
* settled. Returns the unsubscribe.
|
|
67
|
+
*/
|
|
68
|
+
onActivity(listener) {
|
|
69
|
+
_classPrivateFieldGet2(_activity, this).add(listener);
|
|
70
|
+
return () => _classPrivateFieldGet2(_activity, this).delete(listener);
|
|
71
|
+
}
|
|
72
|
+
/** The chunks received so far for a response this client is reading. */
|
|
73
|
+
chunksOf(responseId) {
|
|
74
|
+
return _classPrivateFieldGet2(_responses, this).get(responseId)?.chunks;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Resolves once the agent accepts the event, and rejects if it refuses.
|
|
78
|
+
* While disconnected the event waits, and it is sent again after a
|
|
79
|
+
* reconnect until acknowledged; Channels drops repeats by `eventId`.
|
|
80
|
+
* Rejects once the client is closed.
|
|
81
|
+
*/
|
|
82
|
+
send(event) {
|
|
83
|
+
if (_classPrivateFieldGet2(_closed, this)) return Promise.reject(/* @__PURE__ */ new Error("Closed"));
|
|
84
|
+
const eventId = event.eventId ?? crypto.randomUUID();
|
|
85
|
+
const complete = {
|
|
86
|
+
...event,
|
|
87
|
+
eventId
|
|
88
|
+
};
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
const accepted = () => {
|
|
91
|
+
if (complete.type === "message") _assertClassBrand(_WebChannelClient_brand, this, _upsert).call(this, [complete.message]);
|
|
92
|
+
resolve();
|
|
93
|
+
};
|
|
94
|
+
_classPrivateFieldGet2(_outbox, this).set(eventId, {
|
|
95
|
+
event: complete,
|
|
96
|
+
resolve: accepted,
|
|
97
|
+
reject
|
|
98
|
+
});
|
|
99
|
+
if (_classPrivateFieldGet2(_connected, this)) _assertClassBrand(_WebChannelClient_brand, this, _send).call(this, {
|
|
100
|
+
type: "channels:event",
|
|
101
|
+
event: complete
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/** The agent's conversations. Rejects while disconnected or closed. */
|
|
106
|
+
listConversations() {
|
|
107
|
+
if (_classPrivateFieldGet2(_closed, this)) return Promise.reject(/* @__PURE__ */ new Error("Closed"));
|
|
108
|
+
if (!_classPrivateFieldGet2(_connected, this)) return Promise.reject(/* @__PURE__ */ new Error("Not connected"));
|
|
109
|
+
const requestId = crypto.randomUUID();
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
_classPrivateFieldGet2(_lists, this).set(requestId, {
|
|
112
|
+
resolve,
|
|
113
|
+
reject
|
|
114
|
+
});
|
|
115
|
+
_assertClassBrand(_WebChannelClient_brand, this, _send).call(this, {
|
|
116
|
+
type: "channels:list-conversations",
|
|
117
|
+
requestId
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Follow another conversation: reconnect to it, as after a create or
|
|
123
|
+
* fork. Events still waiting for an ack are rejected, since they were
|
|
124
|
+
* meant for the conversation left behind.
|
|
125
|
+
*/
|
|
126
|
+
follow(conversationId) {
|
|
127
|
+
if (_classPrivateFieldGet2(_closed, this) || conversationId === _classPrivateFieldGet2(_conversationId, this)) return;
|
|
128
|
+
_assertClassBrand(_WebChannelClient_brand, this, _rejectPending).call(this, /* @__PURE__ */ new Error("Switched conversation"));
|
|
129
|
+
_classPrivateFieldSet2(_url, this, String(_classPrivateFieldGet2(_followUrl, this).call(this, new URL(_classPrivateFieldGet2(_url, this)), conversationId)));
|
|
130
|
+
const previous = _classPrivateFieldGet2(_socket, this);
|
|
131
|
+
_classPrivateFieldSet2(_connected, this, false);
|
|
132
|
+
_assertClassBrand(_WebChannelClient_brand, this, _cancelReconnect).call(this);
|
|
133
|
+
_assertClassBrand(_WebChannelClient_brand, this, _connect).call(this);
|
|
134
|
+
previous?.close();
|
|
135
|
+
_assertClassBrand(_WebChannelClient_brand, this, _update).call(this);
|
|
136
|
+
}
|
|
137
|
+
/** Closes the connection and rejects events still waiting for an ack. */
|
|
138
|
+
close() {
|
|
139
|
+
_classPrivateFieldSet2(_closed, this, true);
|
|
140
|
+
_assertClassBrand(_WebChannelClient_brand, this, _cancelReconnect).call(this);
|
|
141
|
+
_classPrivateFieldGet2(_socket, this)?.close();
|
|
142
|
+
_assertClassBrand(_WebChannelClient_brand, this, _rejectPending).call(this, /* @__PURE__ */ new Error("Closed"));
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
function _cancelReconnect() {
|
|
146
|
+
clearTimeout(_classPrivateFieldGet2(_reconnect, this));
|
|
147
|
+
_classPrivateFieldSet2(_reconnect, this, void 0);
|
|
148
|
+
}
|
|
149
|
+
function _rejectPending(error) {
|
|
150
|
+
for (const pending of _classPrivateFieldGet2(_outbox, this).values()) pending.reject(error);
|
|
151
|
+
_classPrivateFieldGet2(_outbox, this).clear();
|
|
152
|
+
for (const pending of _classPrivateFieldGet2(_lists, this).values()) pending.reject(error);
|
|
153
|
+
_classPrivateFieldGet2(_lists, this).clear();
|
|
154
|
+
}
|
|
155
|
+
function _connect() {
|
|
156
|
+
const socket = new WebSocket(_classPrivateFieldGet2(_url, this));
|
|
157
|
+
_classPrivateFieldSet2(_socket, this, socket);
|
|
158
|
+
socket.addEventListener("message", (event) => {
|
|
159
|
+
if (socket !== _classPrivateFieldGet2(_socket, this)) return;
|
|
160
|
+
if (typeof event.data !== "string") return;
|
|
161
|
+
const frame = JSON.parse(event.data);
|
|
162
|
+
if (typeof frame.type === "string" && frame.type.startsWith("channels:")) _assertClassBrand(_WebChannelClient_brand, this, _receive).call(this, frame);
|
|
163
|
+
});
|
|
164
|
+
socket.addEventListener("close", () => {
|
|
165
|
+
if (socket !== _classPrivateFieldGet2(_socket, this)) return;
|
|
166
|
+
_classPrivateFieldSet2(_connected, this, false);
|
|
167
|
+
for (const pending of _classPrivateFieldGet2(_lists, this).values()) pending.reject(/* @__PURE__ */ new Error("Disconnected"));
|
|
168
|
+
_classPrivateFieldGet2(_lists, this).clear();
|
|
169
|
+
_assertClassBrand(_WebChannelClient_brand, this, _update).call(this);
|
|
170
|
+
if (_classPrivateFieldGet2(_closed, this) || socket !== _classPrivateFieldGet2(_socket, this)) return;
|
|
171
|
+
_classPrivateFieldSet2(_reconnect, this, setTimeout(() => {
|
|
172
|
+
_classPrivateFieldSet2(_reconnect, this, void 0);
|
|
173
|
+
_assertClassBrand(_WebChannelClient_brand, this, _connect).call(this);
|
|
174
|
+
}, 1e3));
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function _send(frame) {
|
|
178
|
+
if (_classPrivateFieldGet2(_socket, this)?.readyState === WebSocket.OPEN) _classPrivateFieldGet2(_socket, this).send(JSON.stringify(frame));
|
|
179
|
+
}
|
|
180
|
+
function _receive(frame) {
|
|
181
|
+
if (frame.type !== "channels:snapshot" && frame.type !== "channels:ack" && frame.type !== "channels:conversations" && frame.conversationId !== _classPrivateFieldGet2(_conversationId, this)) return;
|
|
182
|
+
switch (frame.type) {
|
|
183
|
+
case "channels:snapshot":
|
|
184
|
+
if (frame.conversationId !== _classPrivateFieldGet2(_conversationId, this)) {
|
|
185
|
+
if (_classPrivateFieldGet2(_conversationId, this) !== void 0) {
|
|
186
|
+
_classPrivateFieldGet2(_responses, this).clear();
|
|
187
|
+
_classPrivateFieldSet2(_url, this, String(_classPrivateFieldGet2(_followUrl, this).call(this, new URL(_classPrivateFieldGet2(_url, this)), frame.conversationId)));
|
|
188
|
+
}
|
|
189
|
+
_classPrivateFieldSet2(_conversationId, this, frame.conversationId);
|
|
190
|
+
}
|
|
191
|
+
_classPrivateFieldSet2(_operations, this, frame.operations);
|
|
192
|
+
_classPrivateFieldSet2(_connected, this, true);
|
|
193
|
+
_classPrivateFieldSet2(_you, this, frame.you);
|
|
194
|
+
_classPrivateFieldSet2(_transcript, this, frame.messages);
|
|
195
|
+
_classPrivateFieldGet2(_turns, this).clear();
|
|
196
|
+
_assertClassBrand(_WebChannelClient_brand, this, _resume).call(this, frame.turns);
|
|
197
|
+
for (const turn of frame.turns) _assertClassBrand(_WebChannelClient_brand, this, _setTurn).call(this, turn);
|
|
198
|
+
for (const { event } of _classPrivateFieldGet2(_outbox, this).values()) _assertClassBrand(_WebChannelClient_brand, this, _send).call(this, {
|
|
199
|
+
type: "channels:event",
|
|
200
|
+
event
|
|
201
|
+
});
|
|
202
|
+
break;
|
|
203
|
+
case "channels:turn":
|
|
204
|
+
_assertClassBrand(_WebChannelClient_brand, this, _setTurn).call(this, frame.turn);
|
|
205
|
+
_assertClassBrand(_WebChannelClient_brand, this, _update).call(this);
|
|
206
|
+
_assertClassBrand(_WebChannelClient_brand, this, _emit).call(this, {
|
|
207
|
+
type: "turn",
|
|
208
|
+
turn: frame.turn
|
|
209
|
+
});
|
|
210
|
+
return;
|
|
211
|
+
case "channels:messages":
|
|
212
|
+
_assertClassBrand(_WebChannelClient_brand, this, _upsert).call(this, frame.messages);
|
|
213
|
+
return;
|
|
214
|
+
case "channels:chunks": {
|
|
215
|
+
const response = _classPrivateFieldGet2(_responses, this).get(frame.responseId);
|
|
216
|
+
const skip = (response?.chunks.length ?? 0) - frame.from;
|
|
217
|
+
if (!response || skip < 0) return;
|
|
218
|
+
const fresh = frame.chunks.slice(skip);
|
|
219
|
+
if (fresh.length === 0) return;
|
|
220
|
+
response.chunks.push(...fresh);
|
|
221
|
+
_assertClassBrand(_WebChannelClient_brand, this, _emit).call(this, {
|
|
222
|
+
type: "chunks",
|
|
223
|
+
responseId: frame.responseId,
|
|
224
|
+
turnId: response.turnId,
|
|
225
|
+
chunks: fresh
|
|
226
|
+
});
|
|
227
|
+
if (!response.shown) return;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case "channels:ack": {
|
|
231
|
+
const ack = _classPrivateFieldGet2(_outbox, this).get(frame.eventId);
|
|
232
|
+
_classPrivateFieldGet2(_outbox, this).delete(frame.eventId);
|
|
233
|
+
if (frame.error) ack?.reject(new Error(frame.error));
|
|
234
|
+
else ack?.resolve();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
case "channels:end": {
|
|
238
|
+
const response = _classPrivateFieldGet2(_responses, this).get(frame.responseId);
|
|
239
|
+
if (!response) return;
|
|
240
|
+
response.ended = true;
|
|
241
|
+
if (!response.shown || frame.state === "not-found") _classPrivateFieldGet2(_responses, this).delete(frame.responseId);
|
|
242
|
+
_assertClassBrand(_WebChannelClient_brand, this, _emit).call(this, {
|
|
243
|
+
type: "end",
|
|
244
|
+
responseId: frame.responseId,
|
|
245
|
+
turnId: response.turnId,
|
|
246
|
+
state: frame.state
|
|
247
|
+
});
|
|
248
|
+
if (frame.state === "not-found") break;
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
case "channels:caught-up": return;
|
|
252
|
+
case "channels:conversations": {
|
|
253
|
+
const request = frame.requestId === void 0 ? void 0 : _classPrivateFieldGet2(_lists, this).get(frame.requestId);
|
|
254
|
+
if (request) _classPrivateFieldGet2(_lists, this).delete(frame.requestId ?? "");
|
|
255
|
+
if (frame.error) {
|
|
256
|
+
request?.reject(new Error(frame.error));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (frame.conversations) {
|
|
260
|
+
_classPrivateFieldSet2(_conversations, this, frame.conversations);
|
|
261
|
+
request?.resolve(frame.conversations);
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
_assertClassBrand(_WebChannelClient_brand, this, _update).call(this);
|
|
267
|
+
}
|
|
268
|
+
function _upsert(messages) {
|
|
269
|
+
for (const message of messages) {
|
|
270
|
+
const index = _classPrivateFieldGet2(_transcript, this).findIndex((m) => m.id === message.id);
|
|
271
|
+
if (index === -1) _classPrivateFieldGet2(_transcript, this).push(message);
|
|
272
|
+
else _classPrivateFieldGet2(_transcript, this)[index] = message;
|
|
273
|
+
}
|
|
274
|
+
_assertClassBrand(_WebChannelClient_brand, this, _update).call(this);
|
|
275
|
+
}
|
|
276
|
+
function _emit(activity) {
|
|
277
|
+
for (const listener of _classPrivateFieldGet2(_activity, this)) listener(activity);
|
|
278
|
+
}
|
|
279
|
+
/** After a reconnect, keep reading still-running responses where we were. */
|
|
280
|
+
function _resume(turns) {
|
|
281
|
+
const running = new Set(turns.flatMap((turn) => turn.status === "running" ? [turn.responseId] : []));
|
|
282
|
+
for (const [responseId, response] of _classPrivateFieldGet2(_responses, this)) {
|
|
283
|
+
if (!running.has(responseId)) {
|
|
284
|
+
_classPrivateFieldGet2(_responses, this).delete(responseId);
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
_assertClassBrand(_WebChannelClient_brand, this, _send).call(this, {
|
|
288
|
+
type: "channels:subscribe",
|
|
289
|
+
responseId,
|
|
290
|
+
from: response.chunks.length
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function _setTurn(turn) {
|
|
295
|
+
const responseId = turn.status === "running" ? turn.responseId : void 0;
|
|
296
|
+
for (const [id, response] of _classPrivateFieldGet2(_responses, this)) if (response.turnId === turn.turnId && id !== responseId) {
|
|
297
|
+
response.shown = false;
|
|
298
|
+
if (response.ended) _classPrivateFieldGet2(_responses, this).delete(id);
|
|
299
|
+
}
|
|
300
|
+
if (turn.status !== "settled" || turn.outcome === "awaiting-input") _classPrivateFieldGet2(_turns, this).set(turn.turnId, turn);
|
|
301
|
+
else _classPrivateFieldGet2(_turns, this).delete(turn.turnId);
|
|
302
|
+
if (turn.status === "running" && !_classPrivateFieldGet2(_responses, this).has(turn.responseId)) {
|
|
303
|
+
_classPrivateFieldGet2(_responses, this).set(turn.responseId, {
|
|
304
|
+
turnId: turn.turnId,
|
|
305
|
+
...turn.extends !== void 0 && { extends: turn.extends },
|
|
306
|
+
chunks: [],
|
|
307
|
+
shown: true,
|
|
308
|
+
ended: false
|
|
309
|
+
});
|
|
310
|
+
_assertClassBrand(_WebChannelClient_brand, this, _send).call(this, {
|
|
311
|
+
type: "channels:subscribe",
|
|
312
|
+
responseId: turn.responseId
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function _update() {
|
|
317
|
+
const messages = [..._classPrivateFieldGet2(_transcript, this)];
|
|
318
|
+
for (const [responseId, live] of _classPrivateFieldGet2(_responses, this)) {
|
|
319
|
+
if (!live.shown) continue;
|
|
320
|
+
const index = messages.findIndex((m) => m.id === live.extends);
|
|
321
|
+
const message = applyChunks(index === -1 ? {
|
|
322
|
+
id: responseId,
|
|
323
|
+
role: "assistant",
|
|
324
|
+
parts: []
|
|
325
|
+
} : messages[index], live.chunks);
|
|
326
|
+
if (index === -1) messages.push(message);
|
|
327
|
+
else messages[index] = message;
|
|
328
|
+
}
|
|
329
|
+
_classPrivateFieldSet2(_state, this, {
|
|
330
|
+
connected: _classPrivateFieldGet2(_connected, this),
|
|
331
|
+
..._classPrivateFieldGet2(_conversationId, this) !== void 0 && { conversationId: _classPrivateFieldGet2(_conversationId, this) },
|
|
332
|
+
operations: _classPrivateFieldGet2(_operations, this),
|
|
333
|
+
..._classPrivateFieldGet2(_you, this) && { you: _classPrivateFieldGet2(_you, this) },
|
|
334
|
+
messages,
|
|
335
|
+
turns: [..._classPrivateFieldGet2(_turns, this).values()],
|
|
336
|
+
..._classPrivateFieldGet2(_conversations, this) && { conversations: _classPrivateFieldGet2(_conversations, this) }
|
|
337
|
+
});
|
|
338
|
+
for (const listener of _classPrivateFieldGet2(_listeners, this)) listener(_classPrivateFieldGet2(_state, this));
|
|
339
|
+
}
|
|
340
|
+
function defaultFollowUrl(url, conversationId) {
|
|
341
|
+
const next = new URL(url);
|
|
342
|
+
const match = /^\/channels\/([^/]+)(?:\/[^/]+)?$/.exec(url.pathname);
|
|
343
|
+
if (match) next.pathname = `/channels/${match[1]}/${encodeURIComponent(conversationId)}`;
|
|
344
|
+
return next;
|
|
345
|
+
}
|
|
346
|
+
//#endregion
|
|
347
|
+
export { WebChannelClient };
|
|
348
|
+
|
|
349
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../../../src/experimental/channels/web/client.ts"],"sourcesContent":["import { applyChunks } from \"../apply-chunks\";\nimport type {\n ConversationInfo,\n ConversationOperation,\n InboundEvent,\n Participant,\n ResponseChunk,\n TranscriptMessage,\n TurnStatus\n} from \"../protocol\";\nimport type { ClientFrame, ServerFrame } from \"./protocol\";\n\nexport type WebChannelClientState = {\n connected: boolean;\n /** The conversation this client follows, once connected. */\n conversationId?: string;\n /** Conversation operations this client may send. */\n operations: ConversationOperation[];\n you?: Participant;\n /** The transcript, with the output of running turns applied. */\n messages: TranscriptMessage[];\n /** Turns that are queued, running or awaiting input. */\n turns: TurnStatus[];\n /** The agent's conversations, once listed or pushed. */\n conversations?: ConversationInfo[];\n};\n\n/** An inbound event; the client fills in `eventId` when it is left out. */\nexport type ClientEvent = InboundEvent extends infer E\n ? E extends { eventId: string }\n ? Omit<E, \"eventId\"> & { eventId?: string }\n : never\n : never;\n\n/** Turn statuses and response output, frame by frame. */\nexport type WebChannelActivity =\n | { type: \"turn\"; turn: TurnStatus }\n | {\n type: \"chunks\";\n responseId: string;\n turnId: string;\n chunks: ResponseChunk[];\n }\n | {\n type: \"end\";\n responseId: string;\n turnId: string;\n state: \"ended\" | \"interrupted\" | \"not-found\";\n };\n\ntype Response = {\n turnId: string;\n extends?: string;\n chunks: ResponseChunk[];\n /** Applied to the transcript until the turn moves past it. */\n shown: boolean;\n ended: boolean;\n};\n\nexport type WebChannelClientOptions = {\n /**\n * The URL to reconnect to once the client follows another conversation.\n * Default: the gateway's default, `/channels/<route>/<conversation>`.\n */\n followUrl?(url: URL, conversationId: string): URL;\n};\n\n/** A browser client for the Web Channel, with reconnects. */\nexport class WebChannelClient {\n #url: string;\n readonly #followUrl: NonNullable<WebChannelClientOptions[\"followUrl\"]>;\n #conversationId: string | undefined;\n #operations: ConversationOperation[] = [];\n #socket: WebSocket | undefined;\n #closed = false;\n #connected = false;\n /** The reconnect scheduled after a socket closed, until it runs. */\n #reconnect: ReturnType<typeof setTimeout> | undefined;\n #you: Participant | undefined;\n #transcript: TranscriptMessage[] = [];\n readonly #turns = new Map<string, TurnStatus>();\n readonly #responses = new Map<string, Response>();\n /** Events not yet acknowledged, sent again after each reconnect. */\n readonly #outbox = new Map<\n string,\n { event: InboundEvent; resolve(): void; reject(error: Error): void }\n >();\n #conversations: ConversationInfo[] | undefined;\n /** List requests waiting for their answer, by request id. */\n readonly #lists = new Map<\n string,\n { resolve(list: ConversationInfo[]): void; reject(error: Error): void }\n >();\n readonly #listeners = new Set<(state: WebChannelClientState) => void>();\n readonly #activity = new Set<(activity: WebChannelActivity) => void>();\n #state: WebChannelClientState = {\n connected: false,\n operations: [],\n messages: [],\n turns: []\n };\n\n constructor(url: string | URL, options: WebChannelClientOptions = {}) {\n this.#url = String(url);\n this.#followUrl = options.followUrl ?? defaultFollowUrl;\n this.#connect();\n }\n\n get state(): WebChannelClientState {\n return this.#state;\n }\n\n /** Calls the listener on every change. Returns the unsubscribe. */\n subscribe(listener: (state: WebChannelClientState) => void): () => void {\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n }\n\n /**\n * Calls the listener with each turn status, response chunk and response\n * ending as it arrives, including chunks that arrive after the turn has\n * settled. Returns the unsubscribe.\n */\n onActivity(listener: (activity: WebChannelActivity) => void): () => void {\n this.#activity.add(listener);\n return () => this.#activity.delete(listener);\n }\n\n /** The chunks received so far for a response this client is reading. */\n chunksOf(responseId: string): readonly ResponseChunk[] | undefined {\n return this.#responses.get(responseId)?.chunks;\n }\n\n /**\n * Resolves once the agent accepts the event, and rejects if it refuses.\n * While disconnected the event waits, and it is sent again after a\n * reconnect until acknowledged; Channels drops repeats by `eventId`.\n * Rejects once the client is closed.\n */\n send(event: ClientEvent): Promise<void> {\n if (this.#closed) return Promise.reject(new Error(\"Closed\"));\n const eventId = event.eventId ?? crypto.randomUUID();\n // SAFETY: the same event, with its id filled in.\n const complete = { ...event, eventId } as InboundEvent;\n return new Promise((resolve, reject) => {\n const accepted = () => {\n // Other connections get the message from Channels; this one adds its\n // own once the agent has accepted it.\n if (complete.type === \"message\") this.#upsert([complete.message]);\n resolve();\n };\n this.#outbox.set(eventId, { event: complete, resolve: accepted, reject });\n if (this.#connected) {\n this.#send({ type: \"channels:event\", event: complete });\n }\n });\n }\n\n /** The agent's conversations. Rejects while disconnected or closed. */\n listConversations(): Promise<ConversationInfo[]> {\n if (this.#closed) return Promise.reject(new Error(\"Closed\"));\n if (!this.#connected) return Promise.reject(new Error(\"Not connected\"));\n const requestId = crypto.randomUUID();\n return new Promise((resolve, reject) => {\n this.#lists.set(requestId, { resolve, reject });\n this.#send({ type: \"channels:list-conversations\", requestId });\n });\n }\n\n /**\n * Follow another conversation: reconnect to it, as after a create or\n * fork. Events still waiting for an ack are rejected, since they were\n * meant for the conversation left behind.\n */\n follow(conversationId: string): void {\n if (this.#closed || conversationId === this.#conversationId) return;\n this.#rejectPending(new Error(\"Switched conversation\"));\n this.#url = String(this.#followUrl(new URL(this.#url), conversationId));\n const previous = this.#socket;\n this.#connected = false;\n this.#cancelReconnect();\n this.#connect();\n previous?.close();\n this.#update();\n }\n\n /** Closes the connection and rejects events still waiting for an ack. */\n close(): void {\n this.#closed = true;\n this.#cancelReconnect();\n this.#socket?.close();\n this.#rejectPending(new Error(\"Closed\"));\n }\n\n #cancelReconnect(): void {\n clearTimeout(this.#reconnect);\n this.#reconnect = undefined;\n }\n\n #rejectPending(error: Error): void {\n for (const pending of this.#outbox.values()) pending.reject(error);\n this.#outbox.clear();\n for (const pending of this.#lists.values()) pending.reject(error);\n this.#lists.clear();\n }\n\n #connect(): void {\n const socket = new WebSocket(this.#url);\n this.#socket = socket;\n socket.addEventListener(\"message\", (event) => {\n // A socket left behind by `follow`.\n if (socket !== this.#socket) return;\n if (typeof event.data !== \"string\") return;\n const frame = JSON.parse(event.data) as { type?: unknown };\n // Skip the agent's own frames on the shared connection.\n if (\n typeof frame.type === \"string\" &&\n frame.type.startsWith(\"channels:\")\n ) {\n this.#receive(frame as ServerFrame);\n }\n });\n socket.addEventListener(\"close\", () => {\n if (socket !== this.#socket) return;\n this.#connected = false;\n for (const pending of this.#lists.values()) {\n pending.reject(new Error(\"Disconnected\"));\n }\n this.#lists.clear();\n this.#update();\n // A subscriber may have closed the client, or followed another\n // conversation, while it was told about the drop.\n if (this.#closed || socket !== this.#socket) return;\n this.#reconnect = setTimeout(() => {\n this.#reconnect = undefined;\n this.#connect();\n }, 1000);\n });\n }\n\n #send(frame: ClientFrame): void {\n if (this.#socket?.readyState === WebSocket.OPEN) {\n this.#socket.send(JSON.stringify(frame));\n }\n }\n\n #receive(frame: ServerFrame): void {\n // Frames for a conversation this client no longer follows.\n if (\n frame.type !== \"channels:snapshot\" &&\n frame.type !== \"channels:ack\" &&\n frame.type !== \"channels:conversations\" &&\n frame.conversationId !== this.#conversationId\n ) {\n return;\n }\n switch (frame.type) {\n case \"channels:snapshot\":\n if (frame.conversationId !== this.#conversationId) {\n if (this.#conversationId !== undefined) {\n // Following another conversation: start over from its snapshot,\n // and reconnect to it after a disconnect.\n this.#responses.clear();\n this.#url = String(\n this.#followUrl(new URL(this.#url), frame.conversationId)\n );\n }\n this.#conversationId = frame.conversationId;\n }\n this.#operations = frame.operations;\n this.#connected = true;\n this.#you = frame.you;\n this.#transcript = frame.messages;\n this.#turns.clear();\n this.#resume(frame.turns);\n for (const turn of frame.turns) this.#setTurn(turn);\n for (const { event } of this.#outbox.values()) {\n this.#send({ type: \"channels:event\", event });\n }\n break;\n case \"channels:turn\":\n this.#setTurn(frame.turn);\n this.#update();\n this.#emit({ type: \"turn\", turn: frame.turn });\n return;\n case \"channels:messages\":\n this.#upsert(frame.messages);\n return;\n case \"channels:chunks\": {\n const response = this.#responses.get(frame.responseId);\n // Skip chunks already received, and frames past a gap.\n const skip = (response?.chunks.length ?? 0) - frame.from;\n if (!response || skip < 0) return;\n const fresh = frame.chunks.slice(skip);\n if (fresh.length === 0) return;\n response.chunks.push(...fresh);\n this.#emit({\n type: \"chunks\",\n responseId: frame.responseId,\n turnId: response.turnId,\n chunks: fresh\n });\n if (!response.shown) return;\n break;\n }\n case \"channels:ack\": {\n const ack = this.#outbox.get(frame.eventId);\n this.#outbox.delete(frame.eventId);\n if (frame.error) ack?.reject(new Error(frame.error));\n else ack?.resolve();\n return;\n }\n case \"channels:end\": {\n const response = this.#responses.get(frame.responseId);\n if (!response) return;\n response.ended = true;\n // A missing response has nothing to show.\n if (!response.shown || frame.state === \"not-found\") {\n this.#responses.delete(frame.responseId);\n }\n this.#emit({\n type: \"end\",\n responseId: frame.responseId,\n turnId: response.turnId,\n state: frame.state\n });\n if (frame.state === \"not-found\") break;\n return;\n }\n case \"channels:caught-up\":\n return;\n case \"channels:conversations\": {\n const request =\n frame.requestId === undefined\n ? undefined\n : this.#lists.get(frame.requestId);\n if (request) this.#lists.delete(frame.requestId ?? \"\");\n if (frame.error) {\n request?.reject(new Error(frame.error));\n return;\n }\n if (frame.conversations) {\n this.#conversations = frame.conversations;\n request?.resolve(frame.conversations);\n }\n break;\n }\n }\n this.#update();\n }\n\n #upsert(messages: TranscriptMessage[]): void {\n for (const message of messages) {\n const index = this.#transcript.findIndex((m) => m.id === message.id);\n if (index === -1) this.#transcript.push(message);\n else this.#transcript[index] = message;\n }\n this.#update();\n }\n\n #emit(activity: WebChannelActivity): void {\n for (const listener of this.#activity) listener(activity);\n }\n\n /** After a reconnect, keep reading still-running responses where we were. */\n #resume(turns: TurnStatus[]): void {\n const running = new Set(\n turns.flatMap((turn) =>\n turn.status === \"running\" ? [turn.responseId] : []\n )\n );\n for (const [responseId, response] of this.#responses) {\n if (!running.has(responseId)) {\n this.#responses.delete(responseId);\n continue;\n }\n this.#send({\n type: \"channels:subscribe\",\n responseId,\n from: response.chunks.length\n });\n }\n }\n\n #setTurn(turn: TurnStatus): void {\n const responseId = turn.status === \"running\" ? turn.responseId : undefined;\n // A turn's earlier response is replaced by its next one, or by the\n // saved messages once it settles. It is kept until its end arrives.\n for (const [id, response] of this.#responses) {\n if (response.turnId === turn.turnId && id !== responseId) {\n response.shown = false;\n if (response.ended) this.#responses.delete(id);\n }\n }\n const open = turn.status !== \"settled\" || turn.outcome === \"awaiting-input\";\n if (open) this.#turns.set(turn.turnId, turn);\n else this.#turns.delete(turn.turnId);\n if (turn.status === \"running\" && !this.#responses.has(turn.responseId)) {\n this.#responses.set(turn.responseId, {\n turnId: turn.turnId,\n ...(turn.extends !== undefined && { extends: turn.extends }),\n chunks: [],\n shown: true,\n ended: false\n });\n this.#send({ type: \"channels:subscribe\", responseId: turn.responseId });\n }\n }\n\n #update(): void {\n const messages = [...this.#transcript];\n for (const [responseId, live] of this.#responses) {\n if (!live.shown) continue;\n const index = messages.findIndex((m) => m.id === live.extends);\n const base: TranscriptMessage =\n index === -1\n ? { id: responseId, role: \"assistant\", parts: [] }\n : messages[index];\n const message = applyChunks(base, live.chunks);\n if (index === -1) messages.push(message);\n else messages[index] = message;\n }\n this.#state = {\n connected: this.#connected,\n ...(this.#conversationId !== undefined && {\n conversationId: this.#conversationId\n }),\n operations: this.#operations,\n ...(this.#you && { you: this.#you }),\n messages,\n turns: [...this.#turns.values()],\n ...(this.#conversations && { conversations: this.#conversations })\n };\n for (const listener of this.#listeners) listener(this.#state);\n }\n}\n\nfunction defaultFollowUrl(url: URL, conversationId: string): URL {\n const next = new URL(url);\n const match = /^\\/channels\\/([^/]+)(?:\\/[^/]+)?$/.exec(url.pathname);\n if (match) {\n next.pathname = `/channels/${match[1]}/${encodeURIComponent(conversationId)}`;\n }\n return next;\n}\n"],"mappings":"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"}
|