agents 0.20.0 → 0.21.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 +50 -12
- package/dist/{agent-tool-types-Btk9ETS-.d.ts → agent-tool-types-CzGGB-20.d.ts} +403 -115
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-UuScsJg3.d.ts → agent-tools-zR2d5uij.d.ts} +2 -2
- package/dist/agent-tools.d.ts +24 -8
- package/dist/agent-tools.js +14 -6
- package/dist/agent-tools.js.map +1 -1
- package/dist/browser/ai.d.ts +5 -3
- package/dist/browser/ai.js +86 -7
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/tanstack-ai.js +13 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/chat/index.d.ts +31 -2
- package/dist/chat/index.js +57 -2
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +5 -179
- package/dist/chat/react.js +18 -555
- package/dist/chat/react.js.map +1 -1
- package/dist/chat/transport.d.ts +10 -0
- package/dist/chat/transport.js +2 -0
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/cloudflare-BduZwmYK.js +204 -0
- package/dist/cloudflare-BduZwmYK.js.map +1 -0
- package/dist/{connector-v2M1zlZp.d.ts → connector-CkQD4MK3.d.ts} +20 -3
- package/dist/{connector-KEJnl6e5.js → connector-CptFKzRh.js} +158 -40
- package/dist/connector-CptFKzRh.js.map +1 -0
- package/dist/{handler-stateless-8hQN_kC3.js → handler-stateless-CIkKPETH.js} +20 -69
- package/dist/handler-stateless-CIkKPETH.js.map +1 -0
- package/dist/index.d.ts +21 -11
- package/dist/index.js +31 -21
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +20 -20
- package/dist/mcp/index.d.ts +35 -35
- package/dist/mcp/index.js +32 -98
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/observability/ai/index.d.ts +10 -131
- package/dist/observability/ai/index.js +209 -444
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/{wire-types-CU9rLoeS.js → protocol-Dqc2MQxo.js} +2 -46
- package/dist/protocol-Dqc2MQxo.js.map +1 -0
- package/dist/react.d.ts +1 -1
- package/dist/react.js +5 -8
- package/dist/react.js.map +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/sub-routing.d.ts +18 -6
- package/dist/sub-routing.js +92 -2
- package/dist/sub-routing.js.map +1 -1
- package/dist/wire-types-CnMt6_HR.js +47 -0
- package/dist/wire-types-CnMt6_HR.js.map +1 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflow-types.js.map +1 -1
- package/dist/workflows.d.ts +22 -22
- package/dist/ws-chat-transport-CIoOBbO7.js +561 -0
- package/dist/ws-chat-transport-CIoOBbO7.js.map +1 -0
- package/dist/ws-chat-transport-UNRIS2xl.d.ts +184 -0
- package/docs/adding-to-existing-project.md +4 -2
- package/docs/agent-class.md +1 -1
- package/docs/agent-tools.md +29 -0
- package/docs/browse-the-web.md +16 -1
- package/docs/chat-agents.md +3 -1
- package/docs/client-sdk.md +12 -8
- package/docs/configuration.md +7 -1
- package/docs/cross-domain-authentication.md +7 -35
- package/docs/email.md +2 -13
- package/docs/human-in-the-loop.md +15 -12
- package/docs/long-running-agents.md +11 -11
- package/docs/mcp-client.md +1 -1
- package/docs/mcp-servers.md +7 -1
- package/docs/mcp-transports.md +18 -12
- package/docs/migration-to-ai-sdk-v5.md +2 -2
- package/docs/migration-to-ai-sdk-v6.md +5 -1
- package/docs/observability.md +24 -67
- package/docs/routing.md +27 -0
- package/docs/sub-agents.md +47 -2
- package/docs/webhooks.md +109 -136
- package/docs/workflows.md +9 -1
- package/package.json +19 -10
- package/dist/cloudflare-BldFV0Pa.js +0 -117
- package/dist/cloudflare-BldFV0Pa.js.map +0 -1
- package/dist/connector-KEJnl6e5.js.map +0 -1
- package/dist/handler-stateless-8hQN_kC3.js.map +0 -1
- package/dist/wire-types-CU9rLoeS.js.map +0 -1
- package/dist/workflow-types-Baz_PO5v.d.ts +0 -280
package/dist/chat-sdk/index.d.ts
CHANGED
package/dist/client.d.ts
CHANGED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-DZBYAB34.js";
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
import * as cloudflareWorkers from "cloudflare:workers";
|
|
4
|
+
//#region src/observability/tracing/tracer.ts
|
|
5
|
+
/**
|
|
6
|
+
* Spans that asked to be invocation-bounded while a scope was active. Closed
|
|
7
|
+
* when that scope ends; see {@link withInvocationScope}.
|
|
8
|
+
*/
|
|
9
|
+
const invocationScope = new AsyncLocalStorage();
|
|
10
|
+
/**
|
|
11
|
+
* Runs `body` as one traced invocation.
|
|
12
|
+
*
|
|
13
|
+
* Work that escapes its native invocation cannot be traced from the context it
|
|
14
|
+
* started in: the still-open span is force-closed against the invocation that
|
|
15
|
+
* owned that context, which reports a negative duration or `span_not_ended`.
|
|
16
|
+
* Spans opened with {@link SpanLifetime.boundToInvocation} inside this scope
|
|
17
|
+
* are therefore closed before `body` settles — but not one moment earlier, so
|
|
18
|
+
* everything that completes during the invocation (the normal case: a chat
|
|
19
|
+
* turn is awaited by the handler that received it) still records its finish
|
|
20
|
+
* attributes. A span truncated this way is marked
|
|
21
|
+
* `cloudflare.agents.span.truncated` rather than passing as complete.
|
|
22
|
+
*/
|
|
23
|
+
function withInvocationScope(body, options) {
|
|
24
|
+
const current = invocationScope.getStore();
|
|
25
|
+
if (options?.detached !== true && current !== void 0 && !current.ended) return body();
|
|
26
|
+
const scope = {
|
|
27
|
+
ended: false,
|
|
28
|
+
open: /* @__PURE__ */ new Set()
|
|
29
|
+
};
|
|
30
|
+
const endInvocation = () => {
|
|
31
|
+
scope.ended = true;
|
|
32
|
+
for (const span of scope.open) try {
|
|
33
|
+
span.truncate();
|
|
34
|
+
} catch {}
|
|
35
|
+
scope.open.clear();
|
|
36
|
+
};
|
|
37
|
+
return invocationScope.run(scope, () => {
|
|
38
|
+
let result;
|
|
39
|
+
try {
|
|
40
|
+
result = body();
|
|
41
|
+
} catch (cause) {
|
|
42
|
+
endInvocation();
|
|
43
|
+
throw cause;
|
|
44
|
+
}
|
|
45
|
+
if (isPromiseLike(result)) return Promise.resolve(result).finally(endInvocation);
|
|
46
|
+
endInvocation();
|
|
47
|
+
return result;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** Creates a tracer from a runtime span capability. */
|
|
51
|
+
function createTracer(runtime) {
|
|
52
|
+
return new RuntimeTracer(runtime);
|
|
53
|
+
}
|
|
54
|
+
var RuntimeTracer = class {
|
|
55
|
+
constructor(runtime) {
|
|
56
|
+
this.runtime = runtime;
|
|
57
|
+
}
|
|
58
|
+
withSpan(name, attributes, run, lifetime) {
|
|
59
|
+
return this.activate(name, attributes, (span) => {
|
|
60
|
+
const outOfBand = lifetime?.boundToInvocation === true && bindToInvocation(span);
|
|
61
|
+
const result = run(span);
|
|
62
|
+
if (isPromiseLike(result)) {
|
|
63
|
+
if (outOfBand) span.truncate();
|
|
64
|
+
return Promise.resolve(result).catch((cause) => {
|
|
65
|
+
span.fail(cause);
|
|
66
|
+
throw cause;
|
|
67
|
+
}).finally(() => {
|
|
68
|
+
span.close();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (outOfBand) span.truncate();
|
|
72
|
+
span.close();
|
|
73
|
+
return result;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
openSpan(name, attributes, activate, lifetime) {
|
|
77
|
+
if (!lifetime?.boundToInvocation) return this.activate(name, attributes, activate);
|
|
78
|
+
return this.activate(name, attributes, (span) => {
|
|
79
|
+
const invocationEnded = bindToInvocation(span);
|
|
80
|
+
try {
|
|
81
|
+
return activate(span);
|
|
82
|
+
} finally {
|
|
83
|
+
if (invocationEnded) span.truncate();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Shared scaffold: opens an active span, seeds its attributes, and fails the
|
|
89
|
+
* span on a thrown defect before rethrowing. The `body` decides the span's
|
|
90
|
+
* finishing policy (managed vs. caller-owned).
|
|
91
|
+
*/
|
|
92
|
+
activate(name, attributes, body) {
|
|
93
|
+
return this.runtime.startActiveSpan(name, (writer) => {
|
|
94
|
+
setAttributes(writer, attributes);
|
|
95
|
+
const span = new ManagedSpan(writer);
|
|
96
|
+
try {
|
|
97
|
+
return body(span);
|
|
98
|
+
} catch (cause) {
|
|
99
|
+
span.fail(cause);
|
|
100
|
+
throw cause;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var _closed = /* @__PURE__ */ new WeakMap();
|
|
106
|
+
var ManagedSpan = class {
|
|
107
|
+
constructor(span) {
|
|
108
|
+
this.span = span;
|
|
109
|
+
_classPrivateFieldInitSpec(this, _closed, false);
|
|
110
|
+
}
|
|
111
|
+
get isTraced() {
|
|
112
|
+
return this.span.isTraced;
|
|
113
|
+
}
|
|
114
|
+
/** INTERNAL: see {@link writeSpanAttributes}. */
|
|
115
|
+
writeAttributes(attributes) {
|
|
116
|
+
if (_classPrivateFieldGet2(_closed, this)) return;
|
|
117
|
+
setAttributes(this.span, attributes);
|
|
118
|
+
}
|
|
119
|
+
finish(attributes = {}) {
|
|
120
|
+
if (_classPrivateFieldGet2(_closed, this)) return;
|
|
121
|
+
setAttributes(this.span, attributes);
|
|
122
|
+
this.close();
|
|
123
|
+
}
|
|
124
|
+
fail(cause) {
|
|
125
|
+
if (_classPrivateFieldGet2(_closed, this)) return;
|
|
126
|
+
if (isCancellation(cause)) setAttributes(this.span, { "cloudflare.agents.canceled": true });
|
|
127
|
+
else setAttributes(this.span, { "error.type": cause instanceof Error ? cause.name || "Error" : typeof cause });
|
|
128
|
+
this.close();
|
|
129
|
+
}
|
|
130
|
+
close() {
|
|
131
|
+
if (_classPrivateFieldGet2(_closed, this)) return;
|
|
132
|
+
_classPrivateFieldSet2(_closed, this, true);
|
|
133
|
+
this.span.end();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Closes a span whose work has not finished because its invocation is ending.
|
|
137
|
+
* The marker distinguishes "this span has no tokens because the turn escaped
|
|
138
|
+
* its invocation" from "this span completed and reported none".
|
|
139
|
+
*/
|
|
140
|
+
truncate() {
|
|
141
|
+
if (_classPrivateFieldGet2(_closed, this)) return;
|
|
142
|
+
setAttributes(this.span, { "cloudflare.agents.span.truncated": true });
|
|
143
|
+
this.close();
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Registers a span for closure at the end of the current invocation, and
|
|
148
|
+
* reports whether that invocation has already ended.
|
|
149
|
+
*
|
|
150
|
+
* Outside any scope the span keeps its natural lifetime: with no known
|
|
151
|
+
* invocation boundary there is nothing to bound it to, and closing early would
|
|
152
|
+
* discard finish attributes for no gain. Inside a scope that has already
|
|
153
|
+
* ended — work resumed later while still carrying this context — the span
|
|
154
|
+
* cannot outlive an invocation that is already gone, so the caller truncates
|
|
155
|
+
* it as soon as it has written what it knows.
|
|
156
|
+
*/
|
|
157
|
+
function bindToInvocation(span) {
|
|
158
|
+
const scope = invocationScope.getStore();
|
|
159
|
+
if (scope === void 0) return false;
|
|
160
|
+
if (scope.ended) return true;
|
|
161
|
+
scope.open.add(span);
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* INTERNAL: writes attributes onto an open managed span. Lets instrumentation
|
|
166
|
+
* defer expensive attribute computation until after the isTraced check (span
|
|
167
|
+
* names must exist at open time; attributes need not). Not part of the public
|
|
168
|
+
* barrel surface.
|
|
169
|
+
*/
|
|
170
|
+
function writeSpanAttributes(span, attributes) {
|
|
171
|
+
if (span instanceof ManagedSpan) span.writeAttributes(attributes);
|
|
172
|
+
}
|
|
173
|
+
function setAttributes(span, attributes) {
|
|
174
|
+
if (!span.isTraced) return;
|
|
175
|
+
try {
|
|
176
|
+
for (const [key, value] of Object.entries(attributes)) if (value !== void 0) span.setAttribute(key, value);
|
|
177
|
+
} catch {}
|
|
178
|
+
}
|
|
179
|
+
function isPromiseLike(value) {
|
|
180
|
+
return value !== null && value !== void 0 && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Recognizes caller/runtime cancellation (an `AbortError`, e.g. from an aborted
|
|
184
|
+
* `AbortSignal`) so it can be classified separately from genuine failures. A
|
|
185
|
+
* `DOMException` named `AbortError` is not always an `Error` instance, so this
|
|
186
|
+
* probes the `name` field structurally rather than via `instanceof`.
|
|
187
|
+
*/
|
|
188
|
+
function isCancellation(cause) {
|
|
189
|
+
return typeof cause === "object" && cause !== null && "name" in cause && cause.name === "AbortError";
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/observability/tracing/cloudflare.ts
|
|
193
|
+
const noopSpan = {
|
|
194
|
+
isTraced: false,
|
|
195
|
+
setAttribute() {},
|
|
196
|
+
end() {}
|
|
197
|
+
};
|
|
198
|
+
const tracer = createTracer(cloudflareWorkers.tracing ?? { startActiveSpan(_name, run) {
|
|
199
|
+
return run(noopSpan);
|
|
200
|
+
} });
|
|
201
|
+
//#endregion
|
|
202
|
+
export { withInvocationScope as n, writeSpanAttributes as r, tracer as t };
|
|
203
|
+
|
|
204
|
+
//# sourceMappingURL=cloudflare-BduZwmYK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudflare-BduZwmYK.js","names":[],"sources":["../src/observability/tracing/tracer.ts","../src/observability/tracing/cloudflare.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\n/** Attribute values accepted by custom spans. */\nexport type TraceAttributeValue = string | number | boolean | undefined;\n\n/** Initial or finish attributes attached to a span. */\nexport type TraceAttributes = Readonly<Record<string, TraceAttributeValue>>;\n\n/** A value that may complete synchronously or through a promise-like result. */\nexport type MaybePromise<T> = T | PromiseLike<T>;\n\n/** Minimal runtime span surface used by tracers. */\nexport type SpanWriter = {\n readonly isTraced: boolean;\n setAttribute(key: string, value: TraceAttributeValue): void;\n end(): void;\n};\n\n/** Runtime capability for starting an active span in the current async context. */\nexport type SpanRuntime = {\n startActiveSpan<T>(name: string, run: (span: SpanWriter) => T): T;\n};\n\n/** Optional automatic lifetime policy for invocation-bounded spans. */\nexport type SpanLifetime = {\n /**\n * Close the span no later than the end of the surrounding\n * {@link withInvocationScope}, so it cannot outlive the native invocation\n * that owns its tracing context. Ignored outside such a scope.\n */\n readonly boundToInvocation?: boolean;\n};\n\n/** AgentTracer seam used by integrations. */\nexport type AgentTracer = {\n /**\n * Runs `run` inside an active span whose lifetime the tracer owns: the span\n * finishes when `run` returns (or its promise resolves) and fails when `run`\n * throws or rejects. Callers do not call {@link AgentSpan.finish}/{@link AgentSpan.fail};\n * doing so early is safe but the tracer guarantees closure.\n *\n * @template T The value produced by the instrumented work.\n */\n withSpan<T>(\n name: string,\n attributes: TraceAttributes,\n run: (span: AgentSpan) => MaybePromise<T>,\n lifetime?: SpanLifetime\n ): T | Promise<T>;\n /**\n * Activates a span and returns whatever `activate` returns (typically the\n * {@link AgentSpan} handle itself). The caller owns the span lifetime and MUST call\n * {@link AgentSpan.finish} or {@link AgentSpan.fail}; an unfinished span leaks. Use this\n * for work that outlives the callback, such as streams and event-driven\n * telemetry. A throw from `activate` still fails the span before rethrowing.\n *\n * @template T The value returned to the caller, usually the span handle.\n */\n openSpan<T>(\n name: string,\n attributes: TraceAttributes,\n activate: (span: AgentSpan) => T,\n lifetime?: SpanLifetime\n ): T;\n};\n\n/** Active span handle passed to instrumented work. */\nexport type AgentSpan = {\n /**\n * Whether this invocation is actually being traced. Instrumentation can use\n * this to skip expensive capture work when nobody is listening.\n */\n readonly isTraced: boolean;\n /** Records the optional finish attributes and ends the span. Idempotent. */\n finish(attributes?: TraceAttributes): void;\n /**\n * Ends the span as not-successful. Genuine failures record `error.type`;\n * recognized cancellations (an `AbortError`) record `canceled` instead so aborts\n * are not counted as errors. The cause message is never recorded. Idempotent.\n */\n fail(cause: unknown): void;\n};\n\ntype InvocationScope = {\n /** Bounded spans still open. Emptied when the invocation ends. */\n readonly open: Set<ManagedSpan>;\n /** Whether the invocation this scope represents has already ended. */\n ended: boolean;\n};\n\nexport type InvocationScopeOptions = {\n /**\n * Open a scope even inside a live one, for work deliberately detached from\n * the handler that started it — `ctx.waitUntil` bodies, queue drains — which\n * runs on past that handler and must not be cut off with it.\n */\n readonly detached?: boolean;\n};\n\n/**\n * Spans that asked to be invocation-bounded while a scope was active. Closed\n * when that scope ends; see {@link withInvocationScope}.\n */\nconst invocationScope = new AsyncLocalStorage<InvocationScope>();\n\n/**\n * Runs `body` as one traced invocation.\n *\n * Work that escapes its native invocation cannot be traced from the context it\n * started in: the still-open span is force-closed against the invocation that\n * owned that context, which reports a negative duration or `span_not_ended`.\n * Spans opened with {@link SpanLifetime.boundToInvocation} inside this scope\n * are therefore closed before `body` settles — but not one moment earlier, so\n * everything that completes during the invocation (the normal case: a chat\n * turn is awaited by the handler that received it) still records its finish\n * attributes. A span truncated this way is marked\n * `cloudflare.agents.span.truncated` rather than passing as complete.\n */\nexport function withInvocationScope<T>(\n body: () => T,\n options?: InvocationScopeOptions\n): T {\n // Nested scopes would truncate spans at an inner boundary that is not an\n // invocation edge, so the outermost live scope owns the lifetime. A scope\n // that has already ended is not an enclosing invocation at all — it is a\n // leftover context on work that resumed later — so `body` starts a new one.\n const current = invocationScope.getStore();\n if (options?.detached !== true && current !== undefined && !current.ended) {\n return body();\n }\n\n const scope: InvocationScope = { ended: false, open: new Set() };\n const endInvocation = () => {\n scope.ended = true;\n for (const span of scope.open) {\n // Fail open: this runs on the return path of every agent handler, so a\n // span writer that throws must not take the handler's result with it,\n // nor stop the remaining spans from closing.\n try {\n span.truncate();\n } catch {\n // Nothing useful to do with a broken span writer.\n }\n }\n scope.open.clear();\n };\n\n return invocationScope.run(scope, () => {\n let result: T;\n try {\n result = body();\n } catch (cause: unknown) {\n endInvocation();\n throw cause;\n }\n\n if (isPromiseLike(result)) {\n // SAFETY: T is promise-like here, so the settled promise is still a T.\n return Promise.resolve(result).finally(endInvocation) as T;\n }\n\n endInvocation();\n return result;\n });\n}\n\n/** Creates a tracer from a runtime span capability. */\nexport function createTracer(runtime: SpanRuntime): AgentTracer {\n return new RuntimeTracer(runtime);\n}\n\nclass RuntimeTracer implements AgentTracer {\n constructor(private readonly runtime: SpanRuntime) {}\n\n withSpan<T>(\n name: string,\n attributes: TraceAttributes,\n run: (span: AgentSpan) => MaybePromise<T>,\n lifetime?: SpanLifetime\n ): T | Promise<T> {\n return this.activate(name, attributes, (span) => {\n // Ask before running: a span that opens and closes in one tick still\n // needs to know whether that tick happened after its invocation ended.\n const outOfBand =\n lifetime?.boundToInvocation === true && bindToInvocation(span);\n const result = run(span);\n if (isPromiseLike(result)) {\n if (outOfBand) {\n span.truncate();\n }\n return Promise.resolve(result)\n .catch((cause: unknown) => {\n span.fail(cause);\n throw cause;\n })\n .finally(() => {\n span.close();\n });\n }\n\n if (outOfBand) {\n span.truncate();\n }\n span.close();\n return result;\n });\n }\n\n openSpan<T>(\n name: string,\n attributes: TraceAttributes,\n activate: (span: AgentSpan) => T,\n lifetime?: SpanLifetime\n ): T {\n if (!lifetime?.boundToInvocation) {\n return this.activate(name, attributes, activate);\n }\n\n return this.activate(name, attributes, (span) => {\n const invocationEnded = bindToInvocation(span);\n try {\n return activate(span);\n } finally {\n // Truncate only once `activate` has had its turn: callers that open\n // with an empty attribute set and write the real one lazily (the AI\n // operation span does, to stay cheap for untraced calls) would\n // otherwise be closed before writing anything at all.\n if (invocationEnded) {\n span.truncate();\n }\n }\n });\n }\n\n /**\n * Shared scaffold: opens an active span, seeds its attributes, and fails the\n * span on a thrown defect before rethrowing. The `body` decides the span's\n * finishing policy (managed vs. caller-owned).\n */\n private activate<T>(\n name: string,\n attributes: TraceAttributes,\n body: (span: ManagedSpan) => T\n ): T {\n return this.runtime.startActiveSpan(name, (writer) => {\n setAttributes(writer, attributes);\n const span = new ManagedSpan(writer);\n\n try {\n return body(span);\n } catch (cause: unknown) {\n span.fail(cause);\n throw cause;\n }\n });\n }\n}\n\nclass ManagedSpan implements AgentSpan {\n #closed = false;\n\n constructor(private readonly span: SpanWriter) {}\n\n get isTraced(): boolean {\n return this.span.isTraced;\n }\n\n /** INTERNAL: see {@link writeSpanAttributes}. */\n writeAttributes(attributes: TraceAttributes): void {\n if (this.#closed) {\n return;\n }\n\n setAttributes(this.span, attributes);\n }\n\n finish(attributes: TraceAttributes = {}): void {\n if (this.#closed) {\n return;\n }\n\n setAttributes(this.span, attributes);\n this.close();\n }\n\n fail(cause: unknown): void {\n if (this.#closed) {\n return;\n }\n\n if (isCancellation(cause)) {\n // Cancellation is a control path, not a failure: OTel semconv leaves\n // status Unset and records no error.type for cancellations, so aborted\n // operations do not inflate error rates. The vendor marker is additive.\n setAttributes(this.span, { \"cloudflare.agents.canceled\": true });\n } else {\n // Workers' custom Span API does not currently expose setStatus(). Do not\n // invent an `otel.status_code` attribute: status is span state in OTel,\n // not an attribute. error.type remains the standard queryable marker.\n setAttributes(this.span, {\n \"error.type\":\n cause instanceof Error ? cause.name || \"Error\" : typeof cause\n });\n }\n\n this.close();\n }\n\n close(): void {\n if (this.#closed) {\n return;\n }\n\n this.#closed = true;\n this.span.end();\n }\n\n /**\n * Closes a span whose work has not finished because its invocation is ending.\n * The marker distinguishes \"this span has no tokens because the turn escaped\n * its invocation\" from \"this span completed and reported none\".\n */\n truncate(): void {\n if (this.#closed) {\n return;\n }\n\n setAttributes(this.span, { \"cloudflare.agents.span.truncated\": true });\n this.close();\n }\n}\n\n/**\n * Registers a span for closure at the end of the current invocation, and\n * reports whether that invocation has already ended.\n *\n * Outside any scope the span keeps its natural lifetime: with no known\n * invocation boundary there is nothing to bound it to, and closing early would\n * discard finish attributes for no gain. Inside a scope that has already\n * ended — work resumed later while still carrying this context — the span\n * cannot outlive an invocation that is already gone, so the caller truncates\n * it as soon as it has written what it knows.\n */\nfunction bindToInvocation(span: ManagedSpan): boolean {\n const scope = invocationScope.getStore();\n if (scope === undefined) {\n return false;\n }\n\n if (scope.ended) {\n return true;\n }\n\n scope.open.add(span);\n return false;\n}\n\n/**\n * INTERNAL: writes attributes onto an open managed span. Lets instrumentation\n * defer expensive attribute computation until after the isTraced check (span\n * names must exist at open time; attributes need not). Not part of the public\n * barrel surface.\n */\nexport function writeSpanAttributes(\n span: AgentSpan,\n attributes: TraceAttributes\n): void {\n if (span instanceof ManagedSpan) {\n span.writeAttributes(attributes);\n }\n}\n\nfunction setAttributes(span: SpanWriter, attributes: TraceAttributes): void {\n if (!span.isTraced) {\n return;\n }\n\n // Fail-safe: a throwing writer must not leak the span or replace the\n // application's original error with a telemetry one.\n try {\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== undefined) {\n span.setAttribute(key, value);\n }\n }\n } catch {\n // Drop the attributes; the span still closes.\n }\n}\n\nfunction isPromiseLike<T>(value: MaybePromise<T>): value is PromiseLike<T> {\n return (\n value !== null &&\n value !== undefined &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n \"then\" in value &&\n typeof value.then === \"function\"\n );\n}\n\n/**\n * Recognizes caller/runtime cancellation (an `AbortError`, e.g. from an aborted\n * `AbortSignal`) so it can be classified separately from genuine failures. A\n * `DOMException` named `AbortError` is not always an `Error` instance, so this\n * probes the `name` field structurally rather than via `instanceof`.\n */\nfunction isCancellation(cause: unknown): boolean {\n return (\n typeof cause === \"object\" &&\n cause !== null &&\n \"name\" in cause &&\n cause.name === \"AbortError\"\n );\n}\n","import * as cloudflareWorkers from \"cloudflare:workers\";\nimport { createTracer } from \"./tracer\";\nimport type { SpanRuntime, SpanWriter, AgentTracer } from \"./tracer\";\n\nconst noopSpan: SpanWriter = {\n isTraced: false,\n setAttribute() {},\n end() {}\n};\n\nconst noopRuntime: SpanRuntime = {\n startActiveSpan(_name, run) {\n return run(noopSpan);\n }\n};\n\n// Accessed via the namespace so runtimes that predate the `tracing` export\n// degrade to a no-op tracer instead of failing at module-link time — this\n// module loads with the main `agents` entry, not just for tracing users.\nconst runtime: SpanRuntime =\n (cloudflareWorkers as { tracing?: SpanRuntime }).tracing ?? noopRuntime;\n\nexport const tracer: AgentTracer = createTracer(runtime);\n"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CodemodeConnector,
|
|
3
|
+
ConnectorTool,
|
|
3
4
|
ConnectorTools,
|
|
4
5
|
ExecutionEndStatus,
|
|
5
6
|
PassEndStatus
|
|
@@ -95,6 +96,11 @@ interface ConnectBrowserOptions {
|
|
|
95
96
|
* {@link getBrowserRecording}.
|
|
96
97
|
*/
|
|
97
98
|
recording?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Select the browser engine. Defaults to Chromium. Use `"kitesurf"` for
|
|
101
|
+
* Cloudflare's connection-scoped, agent-first browser engine.
|
|
102
|
+
*/
|
|
103
|
+
browser?: "kitesurf";
|
|
98
104
|
}
|
|
99
105
|
/** An rrweb session recording for a closed Browser Run session. */
|
|
100
106
|
interface BrowserRecording {
|
|
@@ -228,7 +234,7 @@ type QuickActionExtractInput = QuickActionPage & {
|
|
|
228
234
|
/** Natural-language instruction for what to extract. */ prompt?: string /** A JSON Schema describing the desired output shape. */;
|
|
229
235
|
response_format?: {
|
|
230
236
|
type: "json_schema";
|
|
231
|
-
|
|
237
|
+
json_schema: unknown;
|
|
232
238
|
} /** Bring-your-own model(s), tried in order, for extraction. */;
|
|
233
239
|
custom_ai?: {
|
|
234
240
|
model: string;
|
|
@@ -432,6 +438,12 @@ interface BrowserConnectorSessionOptions {
|
|
|
432
438
|
* {@link BrowserConnector.liveView}/`sessionInfo()`.
|
|
433
439
|
*/
|
|
434
440
|
recording?: boolean;
|
|
441
|
+
/**
|
|
442
|
+
* Select the browser engine. Defaults to Chromium. Kitesurf is scoped to
|
|
443
|
+
* one CDP WebSocket, so it supports only one-shot execution without
|
|
444
|
+
* pause/resume, Live View, recording, or keep-alive.
|
|
445
|
+
*/
|
|
446
|
+
browser?: "kitesurf";
|
|
435
447
|
}
|
|
436
448
|
type BrowserConnectorOptions = (
|
|
437
449
|
| {
|
|
@@ -554,13 +566,14 @@ declare class BrowserConnector extends CodemodeConnector {
|
|
|
554
566
|
);
|
|
555
567
|
name(): string;
|
|
556
568
|
protected instructions(): string;
|
|
569
|
+
protected tool(name: string, tool: ConnectorTool): ConnectorTool;
|
|
557
570
|
protected tools(): ConnectorTools;
|
|
558
571
|
/**
|
|
559
572
|
* A pass is over (completed, errored, or paused awaiting approval) — drop
|
|
560
573
|
* the CDP socket. The Browser Run session itself stays alive; a resume
|
|
561
574
|
* reconnects from the durably stored session id.
|
|
562
575
|
*/
|
|
563
|
-
onPassEnd(executionId: string,
|
|
576
|
+
onPassEnd(executionId: string, status: PassEndStatus): Promise<void>;
|
|
564
577
|
/**
|
|
565
578
|
* The execution is terminal — delete its Browser Run session unless it was
|
|
566
579
|
* promoted to the shared slot via `cdp.startSession()`.
|
|
@@ -597,6 +610,10 @@ declare class BrowserConnector extends CodemodeConnector {
|
|
|
597
610
|
* deleted, so a later resume fails with a clear "session expired" error
|
|
598
611
|
* instead of silently continuing in a fresh browser; tombstones are
|
|
599
612
|
* deleted once they age past the threshold again.
|
|
613
|
+
*
|
|
614
|
+
* Kitesurf entries are reclaimed the same way, minus the Browser Run
|
|
615
|
+
* delete: their stored id is a synthetic per-execution marker, not a
|
|
616
|
+
* session, and the connection died with the execution.
|
|
600
617
|
*/
|
|
601
618
|
sweep(
|
|
602
619
|
options?: BrowserConnectorSweepOptions
|
|
@@ -656,4 +673,4 @@ export {
|
|
|
656
673
|
QuickActionCommonOptions as y,
|
|
657
674
|
BrowserSessionInfo as z
|
|
658
675
|
};
|
|
659
|
-
//# sourceMappingURL=connector-
|
|
676
|
+
//# sourceMappingURL=connector-CkQD4MK3.d.ts.map
|