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
package/dist/react.js
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
import { camelCaseToKebabCase } from "./utils.js";
|
|
2
2
|
import "./types.js";
|
|
3
|
-
import {
|
|
3
|
+
import { r as CAPNWEB_TRANSPORT_VALUE, t as CAPNWEB_TRANSPORT_QUERY } from "./transport-protocol-BxyngQ_R.js";
|
|
4
|
+
import { d as boundCapnWebSocket, i as NativeCallQueue, l as nativeCall, n as AgentConnectionError, o as createCloseClassifier, s as createStubProxy, u as splitCallOptions } from "./client-4OlMIJx-.js";
|
|
4
5
|
import { buildSubAgentPathUnchecked } from "./sub-routing.js";
|
|
5
|
-
import {
|
|
6
|
+
import { SOCKET_ADDRESS_PENDING } from "./socket-address.js";
|
|
7
|
+
import { i as createAgentToolEventState, n as agentToolEventDedupeKey, r as applyAgentToolEvent } from "./agent-tools-CdJC-8Dc.js";
|
|
6
8
|
import { usePartySocket } from "partysocket/react";
|
|
7
9
|
import { use, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
8
10
|
//#region src/react.tsx
|
|
9
11
|
const queryCache = /* @__PURE__ */ new Map();
|
|
12
|
+
function socketDestinationKey(options) {
|
|
13
|
+
return JSON.stringify([
|
|
14
|
+
options.host ?? null,
|
|
15
|
+
options.basePath ?? null,
|
|
16
|
+
options.party ?? null,
|
|
17
|
+
options.prefix ?? null,
|
|
18
|
+
options.room ?? null,
|
|
19
|
+
options.path ?? null,
|
|
20
|
+
options.protocol ?? null,
|
|
21
|
+
options.protocols ?? null
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
function createReadyEntry() {
|
|
25
|
+
let resolvePromise;
|
|
26
|
+
const entry = {
|
|
27
|
+
promise: new Promise((r) => {
|
|
28
|
+
resolvePromise = r;
|
|
29
|
+
}),
|
|
30
|
+
resolved: false,
|
|
31
|
+
resolve: () => {
|
|
32
|
+
entry.resolved = true;
|
|
33
|
+
resolvePromise();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
return entry;
|
|
37
|
+
}
|
|
38
|
+
/** The host `usePartySocket` connects to when none is given. */
|
|
39
|
+
function defaultSocketHost() {
|
|
40
|
+
return typeof window !== "undefined" ? window.location.host : "dummy-domain.com";
|
|
41
|
+
}
|
|
10
42
|
function createCacheKey(agentNamespace, name, subChainOrDeps, deps) {
|
|
11
43
|
if (deps === void 0) return JSON.stringify([
|
|
12
44
|
agentNamespace,
|
|
@@ -64,7 +96,14 @@ const _testUtils = {
|
|
|
64
96
|
};
|
|
65
97
|
function useAgent(options) {
|
|
66
98
|
const agentNamespace = camelCaseToKebabCase(options.agent);
|
|
67
|
-
const { query, queryDeps, cacheTtl, sub: subOption, path: userPath, defaultCallTimeout, onConnectionError, shouldReconnectOnClose, ...restOptions } = options;
|
|
99
|
+
const { query, queryDeps, cacheTtl, sub: subOption, path: userPath, defaultCallTimeout, onConnectionError, shouldReconnectOnClose, transport = "cf-websocket", ...restOptions } = options;
|
|
100
|
+
const capnWebRef = useRef(null);
|
|
101
|
+
const transportRef = useRef(transport);
|
|
102
|
+
transportRef.current = transport;
|
|
103
|
+
const nativeQueueRef = useRef(new NativeCallQueue());
|
|
104
|
+
const socketClass = useMemo(() => transport === "capnweb" ? { WebSocket: boundCapnWebSocket((socket) => {
|
|
105
|
+
capnWebRef.current = socket;
|
|
106
|
+
}) } : {}, [transport]);
|
|
68
107
|
const subChain = useMemo(() => (subOption ?? []).map((s) => ({
|
|
69
108
|
agent: s.agent,
|
|
70
109
|
name: s.name
|
|
@@ -101,9 +140,12 @@ function useAgent(options) {
|
|
|
101
140
|
socket.send(pending.request);
|
|
102
141
|
pending.sentOn = socket;
|
|
103
142
|
}
|
|
143
|
+
const native = transportRef.current === "capnweb" ? capnWebRef.current : null;
|
|
144
|
+
if (native) nativeQueueRef.current.flush(native);
|
|
104
145
|
};
|
|
105
146
|
/** Reject (and remove) every still-queued (never transmitted) call. */
|
|
106
147
|
const rejectQueuedCalls = (reason) => {
|
|
148
|
+
nativeQueueRef.current.rejectAll(reason);
|
|
107
149
|
const error = new Error(reason);
|
|
108
150
|
for (const [id, pending] of pendingCallsRef.current) if (pending.sentOn === null) {
|
|
109
151
|
if (pending.timeoutId) clearTimeout(pending.timeoutId);
|
|
@@ -174,42 +216,57 @@ function useAgent(options) {
|
|
|
174
216
|
const connectionErrorAddressKeyRef = useRef(null);
|
|
175
217
|
const shouldReconnectOnCloseRef = useRef(shouldReconnectOnClose);
|
|
176
218
|
shouldReconnectOnCloseRef.current = shouldReconnectOnClose;
|
|
177
|
-
const
|
|
178
|
-
|
|
219
|
+
const maxRetriesRef = useRef(restOptions.maxRetries);
|
|
220
|
+
maxRetriesRef.current = restOptions.maxRetries;
|
|
221
|
+
const [closeClassifier] = useState(() => createCloseClassifier({
|
|
222
|
+
socket: () => socketRef.current,
|
|
223
|
+
shouldReconnectOnClose: () => shouldReconnectOnCloseRef.current,
|
|
224
|
+
maxRetries: () => maxRetriesRef.current
|
|
225
|
+
}));
|
|
226
|
+
const classifyReconnect = closeClassifier.shouldReconnectOnClose;
|
|
227
|
+
const [identity, setIdentity] = useState(() => ({
|
|
179
228
|
name: leafName,
|
|
180
229
|
agent: camelCaseToKebabCase(leafAgent),
|
|
181
|
-
identified: false
|
|
182
|
-
|
|
230
|
+
identified: false,
|
|
231
|
+
destination: null
|
|
232
|
+
}));
|
|
183
233
|
const previousIdentityRef = useRef({
|
|
184
234
|
name: null,
|
|
185
235
|
agent: null
|
|
186
236
|
});
|
|
187
|
-
const readyRef = useRef(
|
|
188
|
-
const
|
|
189
|
-
let
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
237
|
+
const readyRef = useRef(/* @__PURE__ */ new Map());
|
|
238
|
+
const readyFor = (destination) => {
|
|
239
|
+
let entry = readyRef.current.get(destination);
|
|
240
|
+
if (!entry) {
|
|
241
|
+
entry = createReadyEntry();
|
|
242
|
+
readyRef.current.set(destination, entry);
|
|
243
|
+
}
|
|
244
|
+
return entry;
|
|
245
|
+
};
|
|
246
|
+
const resetReady = (destination) => {
|
|
247
|
+
if (readyRef.current.get(destination)?.resolved !== false) readyRef.current.set(destination, createReadyEntry());
|
|
196
248
|
};
|
|
197
|
-
if (!readyRef.current) resetReady();
|
|
198
249
|
const mutableAgentRef = useRef(null);
|
|
199
250
|
const combinedPath = useMemo(() => buildSubPath(subChain, userPath), [subChain, userPath]);
|
|
251
|
+
const socketQuery = transport === "capnweb" ? {
|
|
252
|
+
...resolvedQuery,
|
|
253
|
+
[CAPNWEB_TRANSPORT_QUERY]: CAPNWEB_TRANSPORT_VALUE
|
|
254
|
+
} : resolvedQuery;
|
|
200
255
|
const socketOptions = options.basePath ? {
|
|
201
256
|
basePath: options.basePath,
|
|
202
257
|
path: combinedPath || void 0,
|
|
203
|
-
query:
|
|
258
|
+
query: socketQuery,
|
|
204
259
|
...restOptions,
|
|
260
|
+
...socketClass,
|
|
205
261
|
shouldReconnectOnClose: classifyReconnect
|
|
206
262
|
} : {
|
|
207
263
|
party: agentNamespace,
|
|
208
264
|
prefix: "agents",
|
|
209
265
|
room: options.name || "default",
|
|
210
266
|
path: combinedPath || void 0,
|
|
211
|
-
query:
|
|
267
|
+
query: socketQuery,
|
|
212
268
|
...restOptions,
|
|
269
|
+
...socketClass,
|
|
213
270
|
shouldReconnectOnClose: classifyReconnect
|
|
214
271
|
};
|
|
215
272
|
const socketEnabled = !awaitingQueryRefresh && (restOptions.enabled ?? true);
|
|
@@ -218,10 +275,65 @@ function useAgent(options) {
|
|
|
218
275
|
options.basePath ?? null,
|
|
219
276
|
agentNamespace,
|
|
220
277
|
options.name || "default",
|
|
221
|
-
combinedPath || null
|
|
278
|
+
combinedPath || null,
|
|
279
|
+
transport
|
|
222
280
|
]);
|
|
281
|
+
const destination = socketDestinationKey({
|
|
282
|
+
...socketOptions,
|
|
283
|
+
host: socketOptions.host || defaultSocketHost()
|
|
284
|
+
});
|
|
285
|
+
const seedDestinationRef = useRef(destination);
|
|
223
286
|
const visibleConnectionError = connectionErrorAddressKeyRef.current === addressKey ? connectionError : null;
|
|
224
287
|
connectionErrorRef.current = visibleConnectionError;
|
|
288
|
+
const connectProgressRef = useRef(/* @__PURE__ */ new WeakMap());
|
|
289
|
+
const connectProgress = (socket) => {
|
|
290
|
+
if (!socket) return {
|
|
291
|
+
stateSeen: false,
|
|
292
|
+
pendingIdentity: null
|
|
293
|
+
};
|
|
294
|
+
let progress = connectProgressRef.current.get(socket);
|
|
295
|
+
if (!progress) {
|
|
296
|
+
progress = {
|
|
297
|
+
stateSeen: false,
|
|
298
|
+
pendingIdentity: null
|
|
299
|
+
};
|
|
300
|
+
connectProgressRef.current.set(socket, progress);
|
|
301
|
+
}
|
|
302
|
+
return progress;
|
|
303
|
+
};
|
|
304
|
+
const applyIdentity = (newName, newAgent, identifiedSocket) => {
|
|
305
|
+
const oldName = previousIdentityRef.current.name;
|
|
306
|
+
const oldAgent = previousIdentityRef.current.agent;
|
|
307
|
+
const currentAgent = mutableAgentRef.current;
|
|
308
|
+
if (currentAgent) {
|
|
309
|
+
currentAgent.name = newName;
|
|
310
|
+
currentAgent.agent = newAgent;
|
|
311
|
+
currentAgent.identified = true;
|
|
312
|
+
}
|
|
313
|
+
const identifiedDestination = identifiedSocket ? socketDestinationKey(identifiedSocket.partySocketOptions) : null;
|
|
314
|
+
setIdentity({
|
|
315
|
+
name: newName,
|
|
316
|
+
agent: newAgent,
|
|
317
|
+
identified: true,
|
|
318
|
+
destination: identifiedDestination
|
|
319
|
+
});
|
|
320
|
+
if (identifiedDestination !== null) readyFor(identifiedDestination).resolve();
|
|
321
|
+
if (oldName !== null && oldAgent !== null && (oldName !== newName || oldAgent !== newAgent)) if (options.onIdentityChange) options.onIdentityChange(oldName, newName, oldAgent, newAgent);
|
|
322
|
+
else {
|
|
323
|
+
const agentChanged = oldAgent !== newAgent;
|
|
324
|
+
const nameChanged = oldName !== newName;
|
|
325
|
+
let changeDescription = "";
|
|
326
|
+
if (agentChanged && nameChanged) changeDescription = `agent "${oldAgent}" → "${newAgent}", instance "${oldName}" → "${newName}"`;
|
|
327
|
+
else if (agentChanged) changeDescription = `agent "${oldAgent}" → "${newAgent}"`;
|
|
328
|
+
else changeDescription = `instance "${oldName}" → "${newName}"`;
|
|
329
|
+
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.`);
|
|
330
|
+
}
|
|
331
|
+
previousIdentityRef.current = {
|
|
332
|
+
name: newName,
|
|
333
|
+
agent: newAgent
|
|
334
|
+
};
|
|
335
|
+
options.onIdentity?.(newName, newAgent);
|
|
336
|
+
};
|
|
225
337
|
const agent = usePartySocket({
|
|
226
338
|
...socketOptions,
|
|
227
339
|
enabled: socketEnabled,
|
|
@@ -240,42 +352,32 @@ function useAgent(options) {
|
|
|
240
352
|
return options.onMessage?.(message);
|
|
241
353
|
}
|
|
242
354
|
if (parsedMessage.type === "cf_agent_identity") {
|
|
243
|
-
const
|
|
244
|
-
const oldAgent = previousIdentityRef.current.agent;
|
|
355
|
+
const identifiedSocket = message.target ?? socketRef.current;
|
|
245
356
|
const newName = parsedMessage.name;
|
|
246
357
|
const newAgent = parsedMessage.agent;
|
|
247
|
-
const
|
|
248
|
-
if (
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
currentAgent.identified = true;
|
|
252
|
-
}
|
|
253
|
-
setIdentity({
|
|
254
|
-
name: newName,
|
|
255
|
-
agent: newAgent,
|
|
256
|
-
identified: true
|
|
257
|
-
});
|
|
258
|
-
readyRef.current?.resolve();
|
|
259
|
-
if (oldName !== null && oldAgent !== null && (oldName !== newName || oldAgent !== newAgent)) if (options.onIdentityChange) options.onIdentityChange(oldName, newName, oldAgent, newAgent);
|
|
260
|
-
else {
|
|
261
|
-
const agentChanged = oldAgent !== newAgent;
|
|
262
|
-
const nameChanged = oldName !== newName;
|
|
263
|
-
let changeDescription = "";
|
|
264
|
-
if (agentChanged && nameChanged) changeDescription = `agent "${oldAgent}" → "${newAgent}", instance "${oldName}" → "${newName}"`;
|
|
265
|
-
else if (agentChanged) changeDescription = `agent "${oldAgent}" → "${newAgent}"`;
|
|
266
|
-
else changeDescription = `instance "${oldName}" → "${newName}"`;
|
|
267
|
-
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.`);
|
|
358
|
+
const progress = connectProgress(identifiedSocket);
|
|
359
|
+
if (parsedMessage.stateFollows === true && !progress.stateSeen) {
|
|
360
|
+
progress.pendingIdentity = [newName, newAgent];
|
|
361
|
+
return;
|
|
268
362
|
}
|
|
269
|
-
|
|
270
|
-
name: newName,
|
|
271
|
-
agent: newAgent
|
|
272
|
-
};
|
|
273
|
-
options.onIdentity?.(newName, newAgent);
|
|
363
|
+
applyIdentity(newName, newAgent, identifiedSocket);
|
|
274
364
|
return;
|
|
275
365
|
}
|
|
276
366
|
if (parsedMessage.type === "cf_agent_state") {
|
|
277
367
|
setAgentState(parsedMessage.state);
|
|
278
|
-
|
|
368
|
+
if (mutableAgentRef.current) mutableAgentRef.current.state = parsedMessage.state;
|
|
369
|
+
const stateSocket = message.target ?? socketRef.current;
|
|
370
|
+
try {
|
|
371
|
+
options.onStateUpdate?.(parsedMessage.state, "server");
|
|
372
|
+
} finally {
|
|
373
|
+
const progress = connectProgress(stateSocket);
|
|
374
|
+
progress.stateSeen = true;
|
|
375
|
+
const pending = progress.pendingIdentity;
|
|
376
|
+
if (pending) {
|
|
377
|
+
progress.pendingIdentity = null;
|
|
378
|
+
applyIdentity(pending[0], pending[1], stateSocket);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
279
381
|
return;
|
|
280
382
|
}
|
|
281
383
|
if (parsedMessage.type === "cf_agent_state_error") {
|
|
@@ -319,24 +421,26 @@ function useAgent(options) {
|
|
|
319
421
|
onClose: (event) => {
|
|
320
422
|
const closedSocket = event.target ?? socketRef.current;
|
|
321
423
|
const isCurrentSocket = closedSocket === socketRef.current;
|
|
322
|
-
const
|
|
424
|
+
const finalClose = closeClassifier.takeFinalClose();
|
|
425
|
+
if (closedSocket) connectProgressRef.current.delete(closedSocket);
|
|
426
|
+
const reconnecting = !!closedSocket?.shouldReconnect && !finalClose;
|
|
323
427
|
if (closedSocket) {
|
|
324
428
|
rejectCallsSentOn(closedSocket, "Connection closed");
|
|
325
|
-
if (isCurrentSocket && !
|
|
429
|
+
if (isCurrentSocket && !reconnecting) rejectQueuedCalls("Connection closed");
|
|
326
430
|
}
|
|
327
431
|
if (isCurrentSocket) {
|
|
328
|
-
resetReady();
|
|
432
|
+
if (closedSocket) resetReady(socketDestinationKey(closedSocket.partySocketOptions));
|
|
329
433
|
if (mutableAgentRef.current) mutableAgentRef.current.identified = false;
|
|
330
434
|
setIdentity((prev) => ({
|
|
331
435
|
...prev,
|
|
332
436
|
identified: false
|
|
333
437
|
}));
|
|
334
|
-
if (
|
|
438
|
+
if (reconnecting) {
|
|
335
439
|
if (isAsyncQuery) setAwaitingQueryRefresh(true);
|
|
336
440
|
deleteCacheEntry(cacheKeyRef.current);
|
|
337
441
|
setCacheInvalidatedAt(Date.now());
|
|
338
442
|
}
|
|
339
|
-
if (
|
|
443
|
+
if (finalClose) {
|
|
340
444
|
const error = new AgentConnectionError(event);
|
|
341
445
|
connectionErrorAddressKeyRef.current = addressKey;
|
|
342
446
|
setConnectionError(error);
|
|
@@ -347,29 +451,49 @@ function useAgent(options) {
|
|
|
347
451
|
}
|
|
348
452
|
});
|
|
349
453
|
socketRef.current = agent;
|
|
454
|
+
const socketAddressPending = socketDestinationKey(agent.partySocketOptions) !== destination;
|
|
350
455
|
const prevSocketRef = useRef(null);
|
|
351
456
|
const prevAddressKeyRef = useRef(addressKey);
|
|
457
|
+
const prevDestinationRef = useRef(destination);
|
|
352
458
|
useEffect(() => {
|
|
353
459
|
const prev = prevSocketRef.current;
|
|
354
460
|
prevSocketRef.current = agent;
|
|
355
461
|
const prevAddress = prevAddressKeyRef.current;
|
|
356
462
|
prevAddressKeyRef.current = addressKey;
|
|
463
|
+
const prevDestination = prevDestinationRef.current;
|
|
464
|
+
prevDestinationRef.current = destination;
|
|
465
|
+
if (prevDestination !== destination) previousIdentityRef.current = {
|
|
466
|
+
name: null,
|
|
467
|
+
agent: null
|
|
468
|
+
};
|
|
357
469
|
if (prevAddress !== addressKey) {
|
|
358
470
|
connectionErrorAddressKeyRef.current = null;
|
|
359
471
|
setConnectionError(null);
|
|
360
472
|
rejectQueuedCalls("Call discarded: the agent address changed before the request could be sent");
|
|
361
473
|
}
|
|
474
|
+
for (const [key, entry] of readyRef.current) if (key !== destination && entry.resolved) readyRef.current.delete(key);
|
|
362
475
|
if (prev && prev !== agent) {
|
|
363
476
|
rejectCallsSentOn(prev, "Connection closed");
|
|
364
|
-
resetReady();
|
|
477
|
+
resetReady(socketDestinationKey(agent.partySocketOptions));
|
|
365
478
|
if (mutableAgentRef.current) mutableAgentRef.current.identified = false;
|
|
366
479
|
setIdentity((current) => current.identified ? {
|
|
367
480
|
...current,
|
|
368
481
|
identified: false
|
|
369
482
|
} : current);
|
|
370
483
|
}
|
|
371
|
-
}, [
|
|
484
|
+
}, [
|
|
485
|
+
agent,
|
|
486
|
+
addressKey,
|
|
487
|
+
destination
|
|
488
|
+
]);
|
|
372
489
|
const call = useCallback((method, args = [], options) => {
|
|
490
|
+
if (transportRef.current === "capnweb") {
|
|
491
|
+
const native = capnWebRef.current;
|
|
492
|
+
const socket = socketRef.current;
|
|
493
|
+
if (native && socket?.readyState === WebSocket.OPEN) return nativeCall(native, method, args, options, defaultCallTimeoutRef.current);
|
|
494
|
+
if (socket && connectionErrorRef.current && socket.readyState === socket.CLOSED) return Promise.reject(/* @__PURE__ */ new Error("Connection closed"));
|
|
495
|
+
return nativeQueueRef.current.enqueue(method, args, options, defaultCallTimeoutRef.current);
|
|
496
|
+
}
|
|
373
497
|
return new Promise((resolve, reject) => {
|
|
374
498
|
const socket = socketRef.current;
|
|
375
499
|
if (socket && connectionErrorRef.current && socket.readyState === socket.CLOSED) {
|
|
@@ -378,9 +502,7 @@ function useAgent(options) {
|
|
|
378
502
|
}
|
|
379
503
|
const id = crypto.randomUUID();
|
|
380
504
|
let timeoutId;
|
|
381
|
-
const
|
|
382
|
-
const streamOptions = isLegacyFormat ? options : options?.stream;
|
|
383
|
-
const timeout = isLegacyFormat ? void 0 : options?.timeout;
|
|
505
|
+
const { stream: streamOptions, timeout } = splitCallOptions(options);
|
|
384
506
|
const effectiveTimeout = timeout !== void 0 ? timeout : streamOptions ? void 0 : defaultCallTimeoutRef.current;
|
|
385
507
|
if (effectiveTimeout) timeoutId = setTimeout(() => {
|
|
386
508
|
const pending = pendingCallsRef.current.get(id);
|
|
@@ -415,32 +537,29 @@ function useAgent(options) {
|
|
|
415
537
|
state: newState,
|
|
416
538
|
type: "cf_agent_state"
|
|
417
539
|
}));
|
|
540
|
+
if (mutableAgentRef.current) mutableAgentRef.current.state = newState;
|
|
418
541
|
setAgentState(newState);
|
|
419
542
|
options.onStateUpdate?.(newState, "client");
|
|
420
543
|
};
|
|
421
544
|
agent.call = call;
|
|
422
|
-
|
|
423
|
-
agent.
|
|
545
|
+
const identityIsCurrent = !!options.basePath || (identity.destination ?? seedDestinationRef.current) === destination;
|
|
546
|
+
agent.agent = identityIsCurrent ? identity.agent : camelCaseToKebabCase(leafAgent);
|
|
547
|
+
agent.name = identityIsCurrent ? identity.name : leafName;
|
|
424
548
|
agent.path = fullPath;
|
|
425
|
-
agent.identified = identity.identified;
|
|
426
|
-
agent.ready =
|
|
549
|
+
agent.identified = identityIsCurrent && identity.identified;
|
|
550
|
+
agent.ready = readyFor(destination).promise;
|
|
427
551
|
agent.state = agentState;
|
|
428
552
|
agent.connectionError = visibleConnectionError;
|
|
429
553
|
mutableAgentRef.current = agent;
|
|
430
554
|
agent.stub = useMemo(() => createStubProxy(call), [call]);
|
|
555
|
+
agent[SOCKET_ADDRESS_PENDING] = socketAddressPending;
|
|
431
556
|
agent.getHttpUrl = () => {
|
|
557
|
+
if (socketAddressPending) return "";
|
|
432
558
|
return (agent._url || agent._pkurl || "").replace("ws://", "http://").replace("wss://", "https://");
|
|
433
559
|
};
|
|
434
560
|
if (identity.agent !== identity.agent.toLowerCase()) console.warn("Agent name: " + identity.agent + " should probably be in lowercase. Received: " + identity.agent);
|
|
435
561
|
return agent;
|
|
436
562
|
}
|
|
437
|
-
function agentToolDedupeKey(message) {
|
|
438
|
-
return [
|
|
439
|
-
message.parentToolCallId ?? "",
|
|
440
|
-
message.event.runId,
|
|
441
|
-
String(message.sequence)
|
|
442
|
-
].join("\0");
|
|
443
|
-
}
|
|
444
563
|
function useAgentToolEvents(options) {
|
|
445
564
|
const { agent } = options;
|
|
446
565
|
const [state, setState] = useState(() => createAgentToolEventState());
|
|
@@ -455,7 +574,7 @@ function useAgentToolEvents(options) {
|
|
|
455
574
|
return;
|
|
456
575
|
}
|
|
457
576
|
if (message.type !== "agent-tool-event") return;
|
|
458
|
-
const key =
|
|
577
|
+
const key = agentToolEventDedupeKey(message);
|
|
459
578
|
if (seenRef.current.has(key)) return;
|
|
460
579
|
seenRef.current.add(key);
|
|
461
580
|
setState((prev) => applyAgentToolEvent(prev, message));
|