agents 0.23.0 → 0.25.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/dist/{agent-routing-DE5zmCQ8.d.ts → agent-routing-0DR0Tk2v.d.ts} +270 -190
- package/dist/agent-routing.d.ts +1 -1
- package/dist/agent-routing.js.map +1 -1
- package/dist/agent-tool-types.d.ts +13 -7
- package/dist/agent-tool-types.js +23 -1
- package/dist/agent-tool-types.js.map +1 -1
- package/dist/{agent-tools-y7zLfw4Q.js → agent-tools-CdJC-8Dc.js} +72 -9
- package/dist/agent-tools-CdJC-8Dc.js.map +1 -0
- package/dist/{agent-tools-DtXMTDGM.d.ts → agent-tools-YrATZJu2.d.ts} +29 -15
- package/dist/agent-tools.d.ts +6 -4
- package/dist/agent-tools.js.map +1 -1
- package/dist/ai-fm7xx1BK.js +312 -0
- package/dist/ai-fm7xx1BK.js.map +1 -0
- package/dist/base64-redaction-C1Uu29t5.js +59 -0
- package/dist/base64-redaction-C1Uu29t5.js.map +1 -0
- package/dist/browser/ai-sdk.d.ts +90 -0
- package/dist/browser/ai-sdk.js +51 -0
- package/dist/browser/ai-sdk.js.map +1 -0
- package/dist/browser/ai.d.ts +4 -4
- package/dist/browser/ai.js +1 -347
- package/dist/browser/index.d.ts +81 -79
- package/dist/browser/index.js +361 -2
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/tanstack-ai.d.ts +96 -1
- package/dist/browser/tanstack-ai.js +62 -2
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/browser-DE3d-RLk.d.ts +275 -0
- package/dist/browser-tool-CQ10e6Kj.js +480 -0
- package/dist/browser-tool-CQ10e6Kj.js.map +1 -0
- package/dist/browser-tool-DuNdlwZ9.d.ts +73 -0
- package/dist/{capability-BjSKYpzg.js → capability-B4WbF81e.js} +2 -1
- package/dist/capability-B4WbF81e.js.map +1 -0
- package/dist/{capability-runner-Be_-PLR1.d.ts → capability-runner-DBAnGr6L.d.ts} +45 -15
- package/dist/chat/index.d.ts +341 -232
- package/dist/chat/index.js +602 -72
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +42 -2
- package/dist/chat/react.js +191 -35
- package/dist/chat/react.js.map +1 -1
- package/dist/chat/transport.d.ts +1 -1
- package/dist/chat/transport.js +1 -1
- package/dist/chat-sdk/index.d.ts +17 -3
- package/dist/chat-sdk/index.js +28 -2
- package/dist/chat-sdk/index.js.map +1 -1
- package/dist/client-4OlMIJx-.js +591 -0
- package/dist/client-4OlMIJx-.js.map +1 -0
- package/dist/{client-jagG8a9_.js → client-fyQrLGkD.js} +2 -2
- package/dist/{client-jagG8a9_.js.map → client-fyQrLGkD.js.map} +1 -1
- package/dist/client-je3koD9Z.d.ts +446 -0
- package/dist/client.d.ts +29 -283
- package/dist/client.js +2 -274
- package/dist/{connector-CptFKzRh.js → connector-58XDGvc3.js} +251 -120
- package/dist/connector-58XDGvc3.js.map +1 -0
- package/dist/{connector-CkQD4MK3.d.ts → connector-Cl-VqPmA.d.ts} +244 -146
- package/dist/context/index.d.ts +29 -0
- package/dist/context/index.js +64 -17
- package/dist/context/index.js.map +1 -1
- package/dist/current-agent-DhoDkSnH.js.map +1 -1
- package/dist/current-agent-vAk_5JMt.d.ts +93 -0
- package/dist/{current-agent-Da_C9a3b.d.ts → durable-object-lifecycle-HhgOMWq9.d.ts} +26 -127
- package/dist/harnesses/pi/index.d.ts +348 -0
- package/dist/harnesses/pi/index.js +754 -0
- package/dist/harnesses/pi/index.js.map +1 -0
- package/dist/images-iiTDSyRu.js +1631 -0
- package/dist/images-iiTDSyRu.js.map +1 -0
- package/dist/index-BreL0YrQ.d.ts +78 -0
- package/dist/index-kbSUIer3.d.ts +343 -0
- package/dist/index.d.ts +43 -41
- package/dist/index.js +2 -2
- package/dist/internal_context.d.ts +1 -1
- package/dist/lifecycle/index.d.ts +19 -17
- package/dist/lifecycle/index.js +2 -2
- package/dist/{lifecycle-CMRGjZdw.js → lifecycle-CFu6OV03.js} +73 -29
- package/dist/lifecycle-CFu6OV03.js.map +1 -0
- package/dist/mcp/client/index.d.ts +20 -20
- package/dist/mcp/client/index.js +1 -1
- package/dist/mcp/client/x402.js +21 -19
- package/dist/mcp/client/x402.js.map +1 -1
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +2 -2
- package/dist/{message-builder-BymO4N_D.js → message-builder-DAl9AhHH.js} +89 -4
- package/dist/message-builder-DAl9AhHH.js.map +1 -0
- package/dist/models/ai-sdk/index.d.ts +353 -0
- package/dist/models/ai-sdk/index.js +2443 -0
- package/dist/models/ai-sdk/index.js.map +1 -0
- package/dist/models/pi-ai/index.d.ts +313 -0
- package/dist/models/pi-ai/index.js +1795 -0
- package/dist/models/pi-ai/index.js.map +1 -0
- package/dist/observability/ai/index.js +20 -4
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/{protocol-B0nh6KNf.js → protocol-kHsr-f0X.js} +26 -12
- package/dist/{protocol-B0nh6KNf.js.map → protocol-kHsr-f0X.js.map} +1 -1
- package/dist/queue/index.d.ts +123 -0
- package/dist/queue/index.js +2 -0
- package/dist/queue-BB-zfIYF.js +406 -0
- package/dist/queue-BB-zfIYF.js.map +1 -0
- package/dist/react.d.ts +31 -13
- package/dist/react.js +190 -71
- package/dist/react.js.map +1 -1
- package/dist/{retries-D9Ds-1lz.d.ts → retries-CV6AkXmQ.d.ts} +23 -8
- package/dist/retries.d.ts +12 -8
- package/dist/retries.js +19 -1
- package/dist/retries.js.map +1 -1
- package/dist/routing/index.d.ts +2 -2
- package/dist/routing/index.js +1 -1
- package/dist/{scheduler-DD9NdYbF.js → scheduler-DZ3xQfeK.js} +4 -11
- package/dist/scheduler-DZ3xQfeK.js.map +1 -0
- package/dist/{scheduler-Dwh85ZGl.d.ts → scheduler-RdACNXDP.d.ts} +6 -6
- package/dist/schedules/index.d.ts +1 -1
- package/dist/schedules/index.js +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/sessions/index.d.ts +70 -3
- package/dist/sessions/index.js +276 -67
- package/dist/sessions/index.js.map +1 -1
- package/dist/skills/index.d.ts +29 -314
- package/dist/socket-address.d.ts +16 -0
- package/dist/socket-address.js +19 -0
- package/dist/socket-address.js.map +1 -0
- package/dist/{src-DlSHshb2.js → src-BZeu-SCD.js} +541 -500
- package/dist/src-BZeu-SCD.js.map +1 -0
- package/dist/state/index.d.ts +6 -0
- package/dist/state/index.js +137 -0
- package/dist/state/index.js.map +1 -0
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/{streams-D6tJ0NN9.d.ts → streams-Cmkj9QfW.d.ts} +4 -2
- package/dist/{streams-DZKgAj9b.js → streams-DW-UCOUc.js} +9 -2
- package/dist/streams-DW-UCOUc.js.map +1 -0
- package/dist/sub-routing.d.ts +12 -12
- package/dist/tasks/index.d.ts +1 -1
- package/dist/tasks/index.js +1 -1
- package/dist/{tasks-ylZgBjhj.js → tasks-68DESxf0.js} +3 -3
- package/dist/{tasks-ylZgBjhj.js.map → tasks-68DESxf0.js.map} +1 -1
- package/dist/{tasks-BRJ5zgya.d.ts → tasks-9YxYtByh.d.ts} +5 -5
- package/dist/transport-PfFnt-Ld.d.ts +525 -0
- package/dist/transport-protocol-BxyngQ_R.js +25 -0
- package/dist/transport-protocol-BxyngQ_R.js.map +1 -0
- package/dist/transport-protocol-ZTew5Wso.d.ts +27 -0
- package/dist/types-BA4anrjI.d.ts +70 -0
- package/dist/voice/index.d.ts +2 -2
- package/dist/websockets/index.d.ts +195 -69
- package/dist/websockets/index.js +3 -2
- package/dist/websockets-Ci-LZFHH.js +1030 -0
- package/dist/websockets-Ci-LZFHH.js.map +1 -0
- package/dist/wire-types-CnMt6_HR.js.map +1 -1
- package/dist/wire-types-CrjKvDyi.d.ts +300 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflows.d.ts +21 -21
- package/dist/workflows.js +1 -1
- package/dist/{ws-chat-transport-UNRIS2xl.d.ts → ws-chat-transport-BbT1A5Lc.d.ts} +51 -2
- package/dist/{ws-chat-transport-rWwta645.js → ws-chat-transport-cqMKq3IY.js} +143 -16
- package/dist/ws-chat-transport-cqMKq3IY.js.map +1 -0
- package/docs/agent-class.md +2 -2
- package/docs/agent-tools.md +29 -4
- package/docs/browse-the-web.md +87 -5
- package/docs/chat-agents.md +124 -16
- package/docs/client-sdk.md +30 -0
- package/docs/context.md +27 -0
- package/docs/durable-execution.md +2 -0
- package/docs/harnesses/pi.md +91 -0
- package/docs/human-in-the-loop.md +4 -0
- package/docs/index.md +4 -1
- package/docs/lifecycle.md +114 -23
- package/docs/models-pi-ai.md +325 -0
- package/docs/models.md +504 -0
- package/docs/queue.md +135 -241
- package/docs/resumable-streaming.md +2 -0
- package/docs/retries.md +1 -1
- package/docs/routing.md +13 -13
- package/docs/sessions.md +36 -1
- package/docs/state.md +1 -0
- package/docs/sub-agents.md +12 -3
- package/package.json +51 -3
- package/dist/agent-tools-y7zLfw4Q.js.map +0 -1
- package/dist/browser/ai.js.map +0 -1
- package/dist/capability-BjSKYpzg.js.map +0 -1
- package/dist/client-tools-aIBO0Fk7.d.ts +0 -53
- package/dist/client.js.map +0 -1
- package/dist/connector-CptFKzRh.js.map +0 -1
- package/dist/lifecycle-CMRGjZdw.js.map +0 -1
- package/dist/message-builder-BymO4N_D.js.map +0 -1
- package/dist/scheduler-DD9NdYbF.js.map +0 -1
- package/dist/src-DlSHshb2.js.map +0 -1
- package/dist/streams-DZKgAj9b.js.map +0 -1
- package/dist/websockets-DUfRHPRq.js +0 -502
- package/dist/websockets-DUfRHPRq.js.map +0 -1
- package/dist/ws-chat-transport-rWwta645.js.map +0 -1
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
import { camelCaseToKebabCase, isInternalJsStubProp } from "./utils.js";
|
|
2
|
+
import "./types.js";
|
|
3
|
+
import { i as capnWebTransportUrl, n as CAPNWEB_TRANSPORT_SEND } from "./transport-protocol-BxyngQ_R.js";
|
|
4
|
+
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _assertClassBrand, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
|
|
5
|
+
import { t as _classPrivateMethodInitSpec } from "./classPrivateMethodInitSpec-qMjJ6sHQ.js";
|
|
6
|
+
import { PartySocket } from "partysocket";
|
|
7
|
+
import { RpcTarget, newWebSocketRpcSession } from "capnweb";
|
|
8
|
+
//#region src/websockets/capnweb-socket.ts
|
|
9
|
+
/** Local root the host calls to deliver frames. */
|
|
10
|
+
var Inbox = class extends RpcTarget {
|
|
11
|
+
constructor(socket) {
|
|
12
|
+
super();
|
|
13
|
+
this.socket = socket;
|
|
14
|
+
}
|
|
15
|
+
message(value) {
|
|
16
|
+
this.socket.dispatchEvent(new MessageEvent("message", { data: value }));
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var _socket = /* @__PURE__ */ new WeakMap();
|
|
20
|
+
var _root = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
/**
|
|
22
|
+
* A WebSocket-shaped client for the Cap'n Web connection transport.
|
|
23
|
+
*
|
|
24
|
+
* It has the constructor, `readyState`, `send()`, `close()`, and events of
|
|
25
|
+
* a `WebSocket`, so PartySocket (and therefore `useAgent` and
|
|
26
|
+
* `AgentClient`) can drive it as a drop-in socket implementation and keep
|
|
27
|
+
* owning reconnection, buffering, and backoff. Frames sent here travel
|
|
28
|
+
* through the host's pipe method; frames from the host arrive as
|
|
29
|
+
* `message` events.
|
|
30
|
+
*
|
|
31
|
+
* @experimental The transport is experimental.
|
|
32
|
+
*/
|
|
33
|
+
var CapnWebSocket = class CapnWebSocket extends EventTarget {
|
|
34
|
+
constructor(url, protocols) {
|
|
35
|
+
super();
|
|
36
|
+
this.CONNECTING = 0;
|
|
37
|
+
this.OPEN = 1;
|
|
38
|
+
this.CLOSING = 2;
|
|
39
|
+
this.CLOSED = 3;
|
|
40
|
+
this.readyState = CapnWebSocket.CONNECTING;
|
|
41
|
+
this.binaryType = "arraybuffer";
|
|
42
|
+
this.bufferedAmount = 0;
|
|
43
|
+
this.extensions = "";
|
|
44
|
+
this.protocol = "";
|
|
45
|
+
this.onopen = null;
|
|
46
|
+
this.onmessage = null;
|
|
47
|
+
this.onclose = null;
|
|
48
|
+
this.onerror = null;
|
|
49
|
+
_classPrivateFieldInitSpec(this, _socket, void 0);
|
|
50
|
+
_classPrivateFieldInitSpec(this, _root, void 0);
|
|
51
|
+
this.url = capnWebTransportUrl(url);
|
|
52
|
+
_classPrivateFieldSet2(_socket, this, protocols ? new WebSocket(this.url, protocols) : new WebSocket(this.url));
|
|
53
|
+
_classPrivateFieldSet2(_root, this, newWebSocketRpcSession(_classPrivateFieldGet2(_socket, this), new Inbox(this)));
|
|
54
|
+
_classPrivateFieldGet2(_socket, this).addEventListener("open", () => {
|
|
55
|
+
this.readyState = CapnWebSocket.OPEN;
|
|
56
|
+
this.protocol = _classPrivateFieldGet2(_socket, this).protocol;
|
|
57
|
+
this.dispatchEvent(new Event("open"));
|
|
58
|
+
});
|
|
59
|
+
_classPrivateFieldGet2(_socket, this).addEventListener("close", (event) => {
|
|
60
|
+
this.readyState = CapnWebSocket.CLOSED;
|
|
61
|
+
this.dispatchEvent(new CloseEvent("close", {
|
|
62
|
+
code: event.code,
|
|
63
|
+
reason: event.reason,
|
|
64
|
+
wasClean: event.wasClean
|
|
65
|
+
}));
|
|
66
|
+
});
|
|
67
|
+
_classPrivateFieldGet2(_socket, this).addEventListener("error", () => {
|
|
68
|
+
this.dispatchEvent(new Event("error"));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
dispatchEvent(event) {
|
|
72
|
+
const handler = Reflect.get(this, `on${event.type}`);
|
|
73
|
+
if (typeof handler === "function") Reflect.apply(handler, this, [event]);
|
|
74
|
+
return super.dispatchEvent(event);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Invoke one of the host's native callables on the session root. The
|
|
78
|
+
* result keeps Cap'n Web semantics: an `RpcTarget` arrives as a live
|
|
79
|
+
* stub, a `ReadableStream` streams, and chained calls pipeline.
|
|
80
|
+
*/
|
|
81
|
+
invoke(method, args) {
|
|
82
|
+
if (this.readyState !== CapnWebSocket.OPEN) return Promise.reject(/* @__PURE__ */ new Error("Connection closed"));
|
|
83
|
+
const root = _classPrivateFieldGet2(_root, this);
|
|
84
|
+
return Promise.resolve(root[method](...args));
|
|
85
|
+
}
|
|
86
|
+
send(data) {
|
|
87
|
+
if (this.readyState !== CapnWebSocket.OPEN) throw new DOMException("WebSocket is not open", "InvalidStateError");
|
|
88
|
+
_classPrivateFieldGet2(_root, this)[CAPNWEB_TRANSPORT_SEND](data).catch(() => {
|
|
89
|
+
this.dispatchEvent(new Event("error"));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
close(code, reason) {
|
|
93
|
+
if (this.readyState >= CapnWebSocket.CLOSING) return;
|
|
94
|
+
this.readyState = CapnWebSocket.CLOSING;
|
|
95
|
+
try {
|
|
96
|
+
_classPrivateFieldGet2(_root, this)[Symbol.dispose]();
|
|
97
|
+
} catch {}
|
|
98
|
+
_classPrivateFieldGet2(_socket, this).close(code, reason);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
CapnWebSocket.CONNECTING = 0;
|
|
102
|
+
CapnWebSocket.OPEN = 1;
|
|
103
|
+
CapnWebSocket.CLOSING = 2;
|
|
104
|
+
CapnWebSocket.CLOSED = 3;
|
|
105
|
+
/**
|
|
106
|
+
* A `CapnWebSocket` subclass that reports each instance it constructs.
|
|
107
|
+
* PartySocket instantiates the class it is given; this is how a client
|
|
108
|
+
* gets hold of the live socket to call `invoke()` without reaching into
|
|
109
|
+
* PartySocket internals.
|
|
110
|
+
*/
|
|
111
|
+
function boundCapnWebSocket(onCreate) {
|
|
112
|
+
return class BoundCapnWebSocket extends CapnWebSocket {
|
|
113
|
+
constructor(url, protocols) {
|
|
114
|
+
super(url, protocols);
|
|
115
|
+
onCreate(this);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/client.ts
|
|
121
|
+
var AgentConnectionError = class extends Error {
|
|
122
|
+
constructor(event) {
|
|
123
|
+
const reason = event.reason || `WebSocket closed with code ${event.code}`;
|
|
124
|
+
super(`Agent connection closed: ${reason}`);
|
|
125
|
+
this.name = "AgentConnectionError";
|
|
126
|
+
this.code = event.code;
|
|
127
|
+
this.reason = event.reason;
|
|
128
|
+
this.wasClean = event.wasClean;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function isTerminalCloseEvent(event) {
|
|
132
|
+
return event.code === 1008 || event.code >= 4e3 && event.code <= 4999;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* PartySocket's `shouldReconnectOnClose`, plus a record of whether that
|
|
136
|
+
* decision ended reconnection so the close can surface a connection error.
|
|
137
|
+
*
|
|
138
|
+
* Reconnection ends on a terminal close code, when the caller's
|
|
139
|
+
* `shouldReconnectOnClose` declines, or when `maxRetries` is spent (a
|
|
140
|
+
* failed handshake never reaches the server's close codes, so it only
|
|
141
|
+
* stops this way). An explicit `close()` has already cleared
|
|
142
|
+
* `shouldReconnect` by the time PartySocket asks, and is not an error.
|
|
143
|
+
* PartySocket asks before it schedules the next attempt, so `retryCount`
|
|
144
|
+
* still counts the attempt that just closed.
|
|
145
|
+
* @internal
|
|
146
|
+
*/
|
|
147
|
+
function createCloseClassifier(options) {
|
|
148
|
+
let finalClose = false;
|
|
149
|
+
return {
|
|
150
|
+
shouldReconnectOnClose(event) {
|
|
151
|
+
const reconnect = (options.shouldReconnectOnClose()?.(event) ?? true) && !isTerminalCloseEvent(event);
|
|
152
|
+
const socket = options.socket();
|
|
153
|
+
if (socket?.shouldReconnect === false) finalClose = false;
|
|
154
|
+
else if (!reconnect) finalClose = true;
|
|
155
|
+
else {
|
|
156
|
+
const maxRetries = options.maxRetries() ?? Number.POSITIVE_INFINITY;
|
|
157
|
+
finalClose = (socket?.retryCount ?? 0) >= maxRetries;
|
|
158
|
+
}
|
|
159
|
+
return reconnect;
|
|
160
|
+
},
|
|
161
|
+
takeFinalClose() {
|
|
162
|
+
const final = finalClose;
|
|
163
|
+
finalClose = false;
|
|
164
|
+
return final;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Default timeout (in milliseconds) applied to non-streaming RPC calls
|
|
170
|
+
* that don't pass an explicit `timeout`. Acts as a backstop so calls
|
|
171
|
+
* whose response is lost (e.g. the connection drops mid-flight) reject
|
|
172
|
+
* instead of hanging forever. Override per client via
|
|
173
|
+
* `defaultCallTimeout`, or per call via `timeout` (0 disables).
|
|
174
|
+
*/
|
|
175
|
+
const DEFAULT_CALL_TIMEOUT_MS = 3e4;
|
|
176
|
+
/**
|
|
177
|
+
* Normalize `call()` options. The legacy shape is the stream callbacks
|
|
178
|
+
* themselves (`{ onChunk, onDone, onError }`); the current shape nests
|
|
179
|
+
* them under `stream` beside `timeout`.
|
|
180
|
+
*/
|
|
181
|
+
function splitCallOptions(options) {
|
|
182
|
+
return options !== void 0 && ("onChunk" in options || "onDone" in options || "onError" in options) ? {
|
|
183
|
+
stream: options,
|
|
184
|
+
timeout: void 0
|
|
185
|
+
} : {
|
|
186
|
+
stream: options?.stream,
|
|
187
|
+
timeout: options?.timeout
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* One native call on the Cap'n Web transport, with the timeout and
|
|
192
|
+
* stream-callback contract `call()` has on the JSON wire. The timeout
|
|
193
|
+
* covers the whole call, draining included: on expiry the stream reader is
|
|
194
|
+
* cancelled and the promise rejects once. A `ReadableStream` result is
|
|
195
|
+
* drained into the stream callbacks when they are given; any other value,
|
|
196
|
+
* live stubs included, passes straight through.
|
|
197
|
+
*/
|
|
198
|
+
async function nativeCall(socket, method, args, options, defaultTimeout) {
|
|
199
|
+
const { stream, timeout } = splitCallOptions(options);
|
|
200
|
+
const effectiveTimeout = timeout !== void 0 ? timeout : stream ? void 0 : defaultTimeout;
|
|
201
|
+
let reader;
|
|
202
|
+
let timer;
|
|
203
|
+
const work = (async () => {
|
|
204
|
+
const result = await socket.invoke(method, args);
|
|
205
|
+
if (stream && result instanceof ReadableStream) {
|
|
206
|
+
reader = result.getReader();
|
|
207
|
+
for (;;) {
|
|
208
|
+
const { done, value } = await reader.read();
|
|
209
|
+
if (done) break;
|
|
210
|
+
stream.onChunk?.(value);
|
|
211
|
+
}
|
|
212
|
+
stream.onDone?.(void 0);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
})();
|
|
217
|
+
const expiry = effectiveTimeout ? new Promise((_, reject) => {
|
|
218
|
+
timer = setTimeout(() => {
|
|
219
|
+
reader?.cancel().catch(() => {});
|
|
220
|
+
reject(/* @__PURE__ */ new Error(`RPC call to ${method} timed out after ${effectiveTimeout}ms`));
|
|
221
|
+
}, effectiveTimeout);
|
|
222
|
+
}) : void 0;
|
|
223
|
+
try {
|
|
224
|
+
return await (expiry ? Promise.race([work, expiry]) : work);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
work.catch(() => {});
|
|
227
|
+
stream?.onError?.(error instanceof Error ? error.message : String(error));
|
|
228
|
+
throw error;
|
|
229
|
+
} finally {
|
|
230
|
+
if (timer) clearTimeout(timer);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
var _pending = /* @__PURE__ */ new WeakMap();
|
|
234
|
+
/**
|
|
235
|
+
* Native calls issued while the Cap'n Web socket is still connecting or
|
|
236
|
+
* between reconnects. They must not fall back to JSON frames — that would
|
|
237
|
+
* change which methods are reachable and lose return-by-reference — so
|
|
238
|
+
* they wait here and run on the next open socket, or reject when the
|
|
239
|
+
* connection ends for good. Their timeout starts when they are issued.
|
|
240
|
+
*/
|
|
241
|
+
var NativeCallQueue = class {
|
|
242
|
+
constructor() {
|
|
243
|
+
_classPrivateFieldInitSpec(this, _pending, []);
|
|
244
|
+
}
|
|
245
|
+
enqueue(method, args, options, defaultTimeout) {
|
|
246
|
+
return new Promise((resolve, reject) => {
|
|
247
|
+
const { stream, timeout } = splitCallOptions(options);
|
|
248
|
+
const effectiveTimeout = timeout !== void 0 ? timeout : stream ? void 0 : defaultTimeout;
|
|
249
|
+
const startedAt = Date.now();
|
|
250
|
+
const entry = {
|
|
251
|
+
run: (socket) => {
|
|
252
|
+
const remaining = effectiveTimeout === void 0 ? void 0 : Math.max(1, effectiveTimeout - (Date.now() - startedAt));
|
|
253
|
+
nativeCall(socket, method, args, remaining === void 0 ? options : {
|
|
254
|
+
stream,
|
|
255
|
+
timeout: remaining
|
|
256
|
+
}, defaultTimeout).then(resolve, reject);
|
|
257
|
+
},
|
|
258
|
+
reject: (error) => {
|
|
259
|
+
stream?.onError?.(error.message);
|
|
260
|
+
reject(error);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
_classPrivateFieldGet2(_pending, this).push(entry);
|
|
264
|
+
if (effectiveTimeout) setTimeout(() => {
|
|
265
|
+
const index = _classPrivateFieldGet2(_pending, this).indexOf(entry);
|
|
266
|
+
if (index === -1) return;
|
|
267
|
+
_classPrivateFieldGet2(_pending, this).splice(index, 1);
|
|
268
|
+
entry.reject(/* @__PURE__ */ new Error(`RPC call to ${method} timed out after ${effectiveTimeout}ms`));
|
|
269
|
+
}, effectiveTimeout);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/** Run everything queued on a socket that just opened. */
|
|
273
|
+
flush(socket) {
|
|
274
|
+
const pending = _classPrivateFieldGet2(_pending, this);
|
|
275
|
+
_classPrivateFieldSet2(_pending, this, []);
|
|
276
|
+
for (const entry of pending) entry.run(socket);
|
|
277
|
+
}
|
|
278
|
+
/** Reject everything queued; the connection will not come back. */
|
|
279
|
+
rejectAll(reason) {
|
|
280
|
+
const pending = _classPrivateFieldGet2(_pending, this);
|
|
281
|
+
_classPrivateFieldSet2(_pending, this, []);
|
|
282
|
+
const error = new Error(reason);
|
|
283
|
+
for (const entry of pending) entry.reject(error);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Creates a proxy that wraps RPC method calls.
|
|
288
|
+
* Internal JS methods (toJSON, then, etc.) return undefined to avoid
|
|
289
|
+
* triggering RPC calls during serialization (e.g., console.log)
|
|
290
|
+
*/
|
|
291
|
+
function createStubProxy(call) {
|
|
292
|
+
return new Proxy({}, { get: (_target, method) => {
|
|
293
|
+
if (isInternalJsStubProp(method)) return;
|
|
294
|
+
return (...args) => call(method, args);
|
|
295
|
+
} });
|
|
296
|
+
}
|
|
297
|
+
var _connect = /* @__PURE__ */ new WeakMap();
|
|
298
|
+
var _AgentClient_brand = /* @__PURE__ */ new WeakSet();
|
|
299
|
+
var _capnWeb = /* @__PURE__ */ new WeakMap();
|
|
300
|
+
var _nativeQueue = /* @__PURE__ */ new WeakMap();
|
|
301
|
+
/**
|
|
302
|
+
* WebSocket client for connecting to an Agent
|
|
303
|
+
*/
|
|
304
|
+
var AgentClient = class extends PartySocket {
|
|
305
|
+
/**
|
|
306
|
+
* @deprecated Use agentFetch instead
|
|
307
|
+
*/
|
|
308
|
+
static fetch(_opts) {
|
|
309
|
+
throw new Error("AgentClient.fetch is not implemented, use agentFetch instead");
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Promise that resolves when identity has been received from the server.
|
|
313
|
+
* When the server also sends the stored state on connect, it resolves only
|
|
314
|
+
* after that state has been applied, so `state` is current once it settles.
|
|
315
|
+
* Servers without that signal resolve on identity alone.
|
|
316
|
+
* Useful for waiting before making calls that depend on knowing the instance.
|
|
317
|
+
* Resets on connection close so it can be awaited again after reconnect.
|
|
318
|
+
*/
|
|
319
|
+
get ready() {
|
|
320
|
+
return this._readyPromise;
|
|
321
|
+
}
|
|
322
|
+
_resetReady() {
|
|
323
|
+
this._readyPromise = new Promise((resolve) => {
|
|
324
|
+
this._resolveReady = resolve;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
constructor(options) {
|
|
328
|
+
const capnWeb = { current: null };
|
|
329
|
+
const socketClass = options.transport === "capnweb" ? { WebSocket: boundCapnWebSocket((socket) => {
|
|
330
|
+
capnWeb.current = socket;
|
|
331
|
+
}) } : {};
|
|
332
|
+
const agentNamespace = camelCaseToKebabCase(options.agent);
|
|
333
|
+
const self = { current: null };
|
|
334
|
+
const closeClassifier = createCloseClassifier({
|
|
335
|
+
socket: () => self.current,
|
|
336
|
+
shouldReconnectOnClose: () => options.shouldReconnectOnClose,
|
|
337
|
+
maxRetries: () => options.maxRetries
|
|
338
|
+
});
|
|
339
|
+
const classifyReconnect = closeClassifier.shouldReconnectOnClose;
|
|
340
|
+
const socketOptions = options.basePath ? {
|
|
341
|
+
basePath: options.basePath,
|
|
342
|
+
path: options.path,
|
|
343
|
+
...options,
|
|
344
|
+
...socketClass,
|
|
345
|
+
shouldReconnectOnClose: classifyReconnect
|
|
346
|
+
} : {
|
|
347
|
+
party: agentNamespace,
|
|
348
|
+
prefix: "agents",
|
|
349
|
+
room: options.name || "default",
|
|
350
|
+
path: options.path,
|
|
351
|
+
...options,
|
|
352
|
+
...socketClass,
|
|
353
|
+
shouldReconnectOnClose: classifyReconnect
|
|
354
|
+
};
|
|
355
|
+
super(socketOptions);
|
|
356
|
+
_classPrivateMethodInitSpec(this, _AgentClient_brand);
|
|
357
|
+
this.state = void 0;
|
|
358
|
+
this.identified = false;
|
|
359
|
+
this.connectionError = null;
|
|
360
|
+
this._pendingCalls = /* @__PURE__ */ new Map();
|
|
361
|
+
this._previousName = null;
|
|
362
|
+
this._previousAgent = null;
|
|
363
|
+
_classPrivateFieldInitSpec(this, _connect, {
|
|
364
|
+
stateSeen: false,
|
|
365
|
+
pendingIdentity: null
|
|
366
|
+
});
|
|
367
|
+
_classPrivateFieldInitSpec(this, _capnWeb, void 0);
|
|
368
|
+
_classPrivateFieldInitSpec(this, _nativeQueue, new NativeCallQueue());
|
|
369
|
+
self.current = this;
|
|
370
|
+
_classPrivateFieldSet2(_capnWeb, this, capnWeb);
|
|
371
|
+
this.agent = agentNamespace;
|
|
372
|
+
this.name = options.name || "default";
|
|
373
|
+
this.options = options;
|
|
374
|
+
this._resetReady();
|
|
375
|
+
this.addEventListener("message", (event) => {
|
|
376
|
+
if (typeof event.data === "string") {
|
|
377
|
+
let parsedMessage;
|
|
378
|
+
try {
|
|
379
|
+
parsedMessage = JSON.parse(event.data);
|
|
380
|
+
} catch (_error) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (parsedMessage.type === "cf_agent_identity") {
|
|
384
|
+
const identity = {
|
|
385
|
+
name: parsedMessage.name,
|
|
386
|
+
agent: parsedMessage.agent
|
|
387
|
+
};
|
|
388
|
+
if (parsedMessage.stateFollows === true && !_classPrivateFieldGet2(_connect, this).stateSeen) {
|
|
389
|
+
_classPrivateFieldGet2(_connect, this).pendingIdentity = identity;
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
_assertClassBrand(_AgentClient_brand, this, _applyIdentity).call(this, identity.name, identity.agent);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (parsedMessage.type === "cf_agent_state") {
|
|
396
|
+
this.state = parsedMessage.state;
|
|
397
|
+
try {
|
|
398
|
+
this.options.onStateUpdate?.(parsedMessage.state, "server");
|
|
399
|
+
} finally {
|
|
400
|
+
_classPrivateFieldGet2(_connect, this).stateSeen = true;
|
|
401
|
+
const pending = _classPrivateFieldGet2(_connect, this).pendingIdentity;
|
|
402
|
+
if (pending) {
|
|
403
|
+
_classPrivateFieldGet2(_connect, this).pendingIdentity = null;
|
|
404
|
+
_assertClassBrand(_AgentClient_brand, this, _applyIdentity).call(this, pending.name, pending.agent);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (parsedMessage.type === "cf_agent_state_error") {
|
|
410
|
+
this.options.onStateUpdateError?.(parsedMessage.error);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
if (parsedMessage.type === "rpc") {
|
|
414
|
+
const response = parsedMessage;
|
|
415
|
+
const pending = this._pendingCalls.get(response.id);
|
|
416
|
+
if (!pending) {
|
|
417
|
+
console.warn(`[AgentClient] Discarded an RPC response with no matching pending call (id "${response.id}"). The call likely timed out or was rejected when its connection closed before the response arrived.`);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (!response.success) {
|
|
421
|
+
pending.reject(new Error(response.error));
|
|
422
|
+
this._pendingCalls.delete(response.id);
|
|
423
|
+
pending.stream?.onError?.(response.error);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if ("done" in response) if (response.done) {
|
|
427
|
+
pending.resolve(response.result);
|
|
428
|
+
this._pendingCalls.delete(response.id);
|
|
429
|
+
pending.stream?.onDone?.(response.result);
|
|
430
|
+
} else pending.stream?.onChunk?.(response.result);
|
|
431
|
+
else {
|
|
432
|
+
pending.resolve(response.result);
|
|
433
|
+
this._pendingCalls.delete(response.id);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
this.addEventListener("open", () => {
|
|
439
|
+
this.connectionError = null;
|
|
440
|
+
for (const pending of this._pendingCalls.values()) pending.transmitted = true;
|
|
441
|
+
const native = _classPrivateFieldGet2(_capnWeb, this).current;
|
|
442
|
+
if (native) _classPrivateFieldGet2(_nativeQueue, this).flush(native);
|
|
443
|
+
});
|
|
444
|
+
this.addEventListener("close", (event) => {
|
|
445
|
+
const finalClose = closeClassifier.takeFinalClose();
|
|
446
|
+
this.identified = false;
|
|
447
|
+
this._resetReady();
|
|
448
|
+
_classPrivateFieldSet2(_connect, this, {
|
|
449
|
+
stateSeen: false,
|
|
450
|
+
pendingIdentity: null
|
|
451
|
+
});
|
|
452
|
+
if (this.shouldReconnect && !finalClose) this._rejectPendingCalls("Connection closed", { onlyTransmitted: true });
|
|
453
|
+
else {
|
|
454
|
+
this._rejectPendingCalls("Connection closed");
|
|
455
|
+
_classPrivateFieldGet2(_nativeQueue, this).rejectAll("Connection closed");
|
|
456
|
+
if (finalClose) {
|
|
457
|
+
const error = new AgentConnectionError(event);
|
|
458
|
+
this.connectionError = error;
|
|
459
|
+
this.options.onConnectionError?.(error);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
this.call = this._callImpl.bind(this);
|
|
464
|
+
this.stub = createStubProxy((method, args) => this._callImpl(method, args));
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Reject pending RPC calls with the given reason.
|
|
468
|
+
* With `onlyTransmitted`, calls still sitting in the send buffer are
|
|
469
|
+
* kept pending (they'll be flushed on reconnect).
|
|
470
|
+
*/
|
|
471
|
+
_rejectPendingCalls(reason, { onlyTransmitted = false } = {}) {
|
|
472
|
+
const error = new Error(reason);
|
|
473
|
+
for (const [id, pending] of this._pendingCalls) {
|
|
474
|
+
if (onlyTransmitted && !pending.transmitted) continue;
|
|
475
|
+
this._pendingCalls.delete(id);
|
|
476
|
+
pending.reject(error);
|
|
477
|
+
pending.stream?.onError?.(reason);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
setState(state) {
|
|
481
|
+
this.send(JSON.stringify({
|
|
482
|
+
state,
|
|
483
|
+
type: "cf_agent_state"
|
|
484
|
+
}));
|
|
485
|
+
this.state = state;
|
|
486
|
+
this.options.onStateUpdate?.(state, "client");
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Close the connection and immediately reject all pending RPC calls.
|
|
490
|
+
* This provides immediate feedback on intentional close rather than
|
|
491
|
+
* waiting for the WebSocket close handshake to complete.
|
|
492
|
+
*
|
|
493
|
+
* Note: Any calls made after `close()` will be rejected when the
|
|
494
|
+
* underlying WebSocket close event fires.
|
|
495
|
+
*/
|
|
496
|
+
close(code, reason) {
|
|
497
|
+
this._rejectPendingCalls("Connection closed");
|
|
498
|
+
super.close(code, reason);
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Call a method on the Agent.
|
|
502
|
+
* When AgentT is provided, method names are inferred from the agent's methods.
|
|
503
|
+
* Falls back to untyped string-based calls when AgentT is not provided.
|
|
504
|
+
*/
|
|
505
|
+
async _callImpl(method, args = [], options) {
|
|
506
|
+
if (this.options.transport === "capnweb") {
|
|
507
|
+
const timeout = this.options.defaultCallTimeout ?? 3e4;
|
|
508
|
+
const native = _classPrivateFieldGet2(_capnWeb, this).current;
|
|
509
|
+
if (native && this.readyState === this.OPEN) return nativeCall(native, method, args, options, timeout);
|
|
510
|
+
if (this.connectionError && this.readyState === this.CLOSED) throw new Error("Connection closed");
|
|
511
|
+
return _classPrivateFieldGet2(_nativeQueue, this).enqueue(method, args, options, timeout);
|
|
512
|
+
}
|
|
513
|
+
if (this.connectionError && this.readyState === this.CLOSED) throw new Error("Connection closed");
|
|
514
|
+
return new Promise((resolve, reject) => {
|
|
515
|
+
const id = crypto.randomUUID();
|
|
516
|
+
let timeoutId;
|
|
517
|
+
const { stream: streamOptions, timeout } = splitCallOptions(options);
|
|
518
|
+
const effectiveTimeout = timeout !== void 0 ? timeout : streamOptions ? void 0 : this.options.defaultCallTimeout ?? 3e4;
|
|
519
|
+
if (effectiveTimeout) timeoutId = setTimeout(() => {
|
|
520
|
+
const pending = this._pendingCalls.get(id);
|
|
521
|
+
this._pendingCalls.delete(id);
|
|
522
|
+
const errorMessage = `RPC call to ${method} timed out after ${effectiveTimeout}ms`;
|
|
523
|
+
pending?.stream?.onError?.(errorMessage);
|
|
524
|
+
reject(new Error(errorMessage));
|
|
525
|
+
}, effectiveTimeout);
|
|
526
|
+
this._pendingCalls.set(id, {
|
|
527
|
+
reject: (e) => {
|
|
528
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
529
|
+
reject(e);
|
|
530
|
+
},
|
|
531
|
+
resolve: (value) => {
|
|
532
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
533
|
+
resolve(value);
|
|
534
|
+
},
|
|
535
|
+
stream: streamOptions,
|
|
536
|
+
transmitted: this.readyState === this.OPEN
|
|
537
|
+
});
|
|
538
|
+
const request = {
|
|
539
|
+
args,
|
|
540
|
+
id,
|
|
541
|
+
method,
|
|
542
|
+
type: "rpc"
|
|
543
|
+
};
|
|
544
|
+
this.send(JSON.stringify(request));
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
function _applyIdentity(newName, newAgent) {
|
|
549
|
+
const oldName = this._previousName;
|
|
550
|
+
const oldAgent = this._previousAgent;
|
|
551
|
+
this.identified = true;
|
|
552
|
+
this._resolveReady();
|
|
553
|
+
if (oldName !== null && oldAgent !== null && (oldName !== newName || oldAgent !== newAgent)) if (this.options.onIdentityChange) this.options.onIdentityChange(oldName, newName, oldAgent, newAgent);
|
|
554
|
+
else {
|
|
555
|
+
const agentChanged = oldAgent !== newAgent;
|
|
556
|
+
const nameChanged = oldName !== newName;
|
|
557
|
+
let changeDescription = "";
|
|
558
|
+
if (agentChanged && nameChanged) changeDescription = `agent "${oldAgent}" → "${newAgent}", instance "${oldName}" → "${newName}"`;
|
|
559
|
+
else if (agentChanged) changeDescription = `agent "${oldAgent}" → "${newAgent}"`;
|
|
560
|
+
else changeDescription = `instance "${oldName}" → "${newName}"`;
|
|
561
|
+
console.warn(`[agents] Identity changed on reconnect: ${changeDescription}. This can happen with server-side routing (e.g., basePath with getAgentByName) where the instance is determined by auth/session. Provide onIdentityChange callback to handle this explicitly, or ignore if this is expected for your routing pattern.`);
|
|
562
|
+
}
|
|
563
|
+
this._previousName = newName;
|
|
564
|
+
this._previousAgent = newAgent;
|
|
565
|
+
this.name = newName;
|
|
566
|
+
this.agent = newAgent;
|
|
567
|
+
this.options.onIdentity?.(newName, newAgent);
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Make an HTTP request to an Agent
|
|
571
|
+
* @param opts Connection options
|
|
572
|
+
* @param init Request initialization options
|
|
573
|
+
* @returns Promise resolving to a Response
|
|
574
|
+
*/
|
|
575
|
+
function agentFetch(opts, init) {
|
|
576
|
+
const agentNamespace = camelCaseToKebabCase(opts.agent);
|
|
577
|
+
if (opts.basePath) return PartySocket.fetch({
|
|
578
|
+
basePath: opts.basePath,
|
|
579
|
+
...opts
|
|
580
|
+
}, init);
|
|
581
|
+
return PartySocket.fetch({
|
|
582
|
+
party: agentNamespace,
|
|
583
|
+
prefix: "agents",
|
|
584
|
+
room: opts.name || "default",
|
|
585
|
+
...opts
|
|
586
|
+
}, init);
|
|
587
|
+
}
|
|
588
|
+
//#endregion
|
|
589
|
+
export { agentFetch as a, isTerminalCloseEvent as c, boundCapnWebSocket as d, NativeCallQueue as i, nativeCall as l, AgentConnectionError as n, createCloseClassifier as o, DEFAULT_CALL_TIMEOUT_MS as r, createStubProxy as s, AgentClient as t, splitCallOptions as u };
|
|
590
|
+
|
|
591
|
+
//# sourceMappingURL=client-4OlMIJx-.js.map
|