agents 0.31.0 → 0.32.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.
Files changed (105) hide show
  1. package/dist/{agent-routing-wS1TimZ_.d.ts → agent-routing-vVMA7m8Y.d.ts} +6 -6
  2. package/dist/agent-routing.d.ts +1 -1
  3. package/dist/agent-tool-types.d.ts +1 -1
  4. package/dist/{agent-tools-Bamxxb6Y.d.ts → agent-tools-gGXXkf1z.d.ts} +2 -2
  5. package/dist/agent-tools.d.ts +1 -1
  6. package/dist/agent-tools.js +0 -1
  7. package/dist/agent-tools.js.map +1 -1
  8. package/dist/browser/ai.js +1 -1
  9. package/dist/browser/tools/ai-sdk.d.ts +66 -1
  10. package/dist/browser/tools/ai-sdk.js +2 -2
  11. package/dist/browser/tools/pi.js +2 -2
  12. package/dist/browser/tools/tanstack-ai.d.ts +2 -2
  13. package/dist/browser/tools/tanstack-ai.js +2 -2
  14. package/dist/browser/tools/tanstack-ai.js.map +1 -1
  15. package/dist/{browser-tool-lGnvEBLJ.js → browser-tool-DRan7Lk6.js} +2 -2
  16. package/dist/{browser-tool-lGnvEBLJ.js.map → browser-tool-DRan7Lk6.js.map} +1 -1
  17. package/dist/catalog-BpOejOsE.js +239 -0
  18. package/dist/catalog-BpOejOsE.js.map +1 -0
  19. package/dist/catalog-BpiVV1OF.d.ts +173 -0
  20. package/dist/chat/index.d.ts +2 -2
  21. package/dist/chat-sdk/index.d.ts +1 -1
  22. package/dist/chat-sdk/index.js +1 -1
  23. package/dist/{client-wn4-yqGz.d.ts → client-eSfgYvd3.d.ts} +2 -2
  24. package/dist/client.d.ts +1 -1
  25. package/dist/{cloudflare-Dzvc7V2N.js → cloudflare-CUUm_9q9.js} +26 -4
  26. package/dist/cloudflare-CUUm_9q9.js.map +1 -0
  27. package/dist/{do-oauth-client-provider-DfsUcpc3.d.ts → do-oauth-client-provider-DtNqv7oj.d.ts} +26 -2
  28. package/dist/{index-YSKgfgg9.d.ts → emitter-BJZtCVjQ.d.ts} +6 -140
  29. package/dist/emitter-DPOVcCln.js +15 -0
  30. package/dist/emitter-DPOVcCln.js.map +1 -0
  31. package/dist/experimental/channels/web/index.js +1 -1
  32. package/dist/harness/container/index.js +0 -1
  33. package/dist/harness/container/index.js.map +1 -1
  34. package/dist/harness/container/runtime/index.js +2 -2
  35. package/dist/harness/opencode/index.js +0 -1
  36. package/dist/harness/opencode/index.js.map +1 -1
  37. package/dist/harness/pi/index.d.ts +11 -4
  38. package/dist/harness/pi/index.js +43 -141
  39. package/dist/harness/pi/index.js.map +1 -1
  40. package/dist/index.d.ts +2 -3
  41. package/dist/index.js +2 -2
  42. package/dist/markdown-BZ-VLtA1.js +86 -0
  43. package/dist/markdown-BZ-VLtA1.js.map +1 -0
  44. package/dist/mcp/client/do-oauth-client-provider.d.ts +4 -2
  45. package/dist/mcp/client/do-oauth-client-provider.js +15 -1
  46. package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
  47. package/dist/mcp/client/index.d.ts +1 -1
  48. package/dist/mcp/index.d.ts +1 -1
  49. package/dist/mcp/index.js +1 -1
  50. package/dist/models/pi-ai/index.js +129 -2
  51. package/dist/models/pi-ai/index.js.map +1 -1
  52. package/dist/observability/ai/index.js +1 -2
  53. package/dist/observability/ai/index.js.map +1 -1
  54. package/dist/observability/index.d.ts +170 -9
  55. package/dist/observability/index.js +386 -11
  56. package/dist/observability/index.js.map +1 -1
  57. package/dist/react.d.ts +2 -2
  58. package/dist/resource-B59OV2a2.js +325 -0
  59. package/dist/resource-B59OV2a2.js.map +1 -0
  60. package/dist/routing/index.d.ts +1 -1
  61. package/dist/script-CFDLTk5b.d.ts +91 -0
  62. package/dist/script-workspace-BpdAYq1R.d.ts +41 -0
  63. package/dist/serializable.d.ts +1 -1
  64. package/dist/skill-DRBcIBjC.d.ts +221 -0
  65. package/dist/skills/index.d.ts +275 -36
  66. package/dist/skills/index.js +265 -1534
  67. package/dist/skills/index.js.map +1 -1
  68. package/dist/skills/runner.d.ts +37 -0
  69. package/dist/skills/runner.js +912 -0
  70. package/dist/skills/runner.js.map +1 -0
  71. package/dist/skills/tools/ai-sdk.d.ts +36 -0
  72. package/dist/skills/tools/ai-sdk.js +94 -0
  73. package/dist/skills/tools/ai-sdk.js.map +1 -0
  74. package/dist/source-9RQzlEhM.d.ts +112 -0
  75. package/dist/{src-BGolXG_H.js → src-DoGNJ4Ud.js} +4 -5
  76. package/dist/src-DoGNJ4Ud.js.map +1 -0
  77. package/dist/sub-routing.d.ts +1 -1
  78. package/dist/tool-CxKsvxjm.js.map +1 -1
  79. package/dist/tool-DkT_DJBm.js.map +1 -1
  80. package/dist/{tool-helpers-BodWi4gd.js → tool-helpers-BI7ifO2S.js} +1 -2
  81. package/dist/{tool-helpers-BodWi4gd.js.map → tool-helpers-BI7ifO2S.js.map} +1 -1
  82. package/dist/vite.d.ts +2 -2
  83. package/dist/vite.js +10 -258
  84. package/dist/vite.js.map +1 -1
  85. package/dist/voice/index.d.ts +1 -1
  86. package/dist/websockets/index.js +1 -1
  87. package/dist/{websockets-CyoeosdO.js → websockets-C6SJtWCJ.js} +1 -2
  88. package/dist/{websockets-CyoeosdO.js.map → websockets-C6SJtWCJ.js.map} +1 -1
  89. package/dist/workflow-types.d.ts +1 -1
  90. package/dist/workflows.d.ts +1 -1
  91. package/dist/workflows.js +0 -1
  92. package/dist/workflows.js.map +1 -1
  93. package/docs/harnesses/pi.md +9 -3
  94. package/docs/mcp-client.md +23 -1
  95. package/docs/mcp-servers.md +2 -2
  96. package/docs/observability.md +5 -3
  97. package/package.json +24 -15
  98. package/dist/ai-sdk-hW3vntnk.d.ts +0 -72
  99. package/dist/cloudflare-Dzvc7V2N.js.map +0 -1
  100. package/dist/index-iv9FTXX9.d.ts +0 -311
  101. package/dist/skills/compile.d.ts +0 -40
  102. package/dist/skills/compile.js +0 -65
  103. package/dist/skills/compile.js.map +0 -1
  104. package/dist/src-BGolXG_H.js.map +0 -1
  105. package/skills-module.d.ts +0 -22
@@ -0,0 +1,239 @@
1
+ import { c as isModelInvocable, d as err, f as ok, o as parseSkillResourcePath, t as InvalidSkillResourcePathError } from "./resource-B59OV2a2.js";
2
+ //#region src/skills/source.ts
3
+ /** A source's backing store failed. */
4
+ var SkillSourceError = class extends Error {
5
+ /**
6
+ * @param sourceId - The source that failed.
7
+ * @param operation - What the source was doing.
8
+ * @param cause - The underlying store error.
9
+ */
10
+ constructor(sourceId, operation, cause) {
11
+ super(`Skill source "${sourceId}" failed to ${operation === "list" ? "list skills" : "read a resource"}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
12
+ this.sourceId = sourceId;
13
+ this.operation = operation;
14
+ this._tag = "SkillSourceError";
15
+ this.name = "SkillSourceError";
16
+ }
17
+ };
18
+ /** A skill has no file at the requested path. */
19
+ var SkillResourceNotFoundError = class extends Error {
20
+ /**
21
+ * @param skill - The skill that was searched.
22
+ * @param path - The missing path.
23
+ */
24
+ constructor(skill, path) {
25
+ super(`Resource not found: ${skill}/${path}`);
26
+ this.skill = skill;
27
+ this.path = path;
28
+ this._tag = "SkillResourceNotFoundError";
29
+ this.name = "SkillResourceNotFoundError";
30
+ }
31
+ };
32
+ //#endregion
33
+ //#region src/skills/catalog.ts
34
+ /** The catalog has no skill with the requested name. */
35
+ var UnknownSkillError = class extends Error {
36
+ /** @param skill - The requested name. */
37
+ constructor(skill) {
38
+ super(`Skill not found: ${skill}`);
39
+ this.skill = skill;
40
+ this._tag = "UnknownSkillError";
41
+ this.name = "UnknownSkillError";
42
+ }
43
+ };
44
+ /**
45
+ * Successful listings behind each catalog, by source object. Lets a later
46
+ * load fall back to the last good listing of a failing source without
47
+ * putting listings on the public catalog shape.
48
+ */
49
+ const catalogListings = /* @__PURE__ */ new WeakMap();
50
+ /**
51
+ * Load every source and merge them into a catalog.
52
+ *
53
+ * Sources apply in order: the first source to list a name wins. A failing
54
+ * source or an invalid skill becomes a diagnostic instead of an error, so
55
+ * one bad source never hides the others. Skills that set
56
+ * `disable-model-invocation: true` are left out.
57
+ *
58
+ * @param sources - Skill sources in priority order.
59
+ * @param options - Pass `previous` to keep a failing source's last skills.
60
+ * @returns The merged catalog.
61
+ */
62
+ async function loadSkillCatalog(sources, options = {}) {
63
+ const previousListings = options.previous ? catalogListings.get(options.previous) : void 0;
64
+ const listings = await Promise.all(sources.map(async (source) => ({
65
+ source,
66
+ listed: await source.list().catch((cause) => err(new SkillSourceError(source.id, "list", cause)))
67
+ })));
68
+ const diagnostics = [];
69
+ const entries = /* @__PURE__ */ new Map();
70
+ const sourceBySkill = /* @__PURE__ */ new Map();
71
+ const goodListings = /* @__PURE__ */ new Map();
72
+ for (const { source, listed } of listings) {
73
+ let listing;
74
+ if (listed.ok) listing = listed.value;
75
+ else {
76
+ const fallback = previousListings?.get(source);
77
+ diagnostics.push({
78
+ _tag: "SourceFailed",
79
+ sourceId: source.id,
80
+ error: listed.error,
81
+ keptPrevious: fallback !== void 0
82
+ });
83
+ if (!fallback) continue;
84
+ listing = fallback;
85
+ }
86
+ goodListings.set(source, listing);
87
+ for (const invalid of listing.invalid) diagnostics.push({
88
+ _tag: "InvalidSkill",
89
+ sourceId: source.id,
90
+ location: invalid.location,
91
+ error: invalid.error
92
+ });
93
+ for (const { skill, resources, location, warnings } of listing.skills) {
94
+ const existing = entries.get(skill.name);
95
+ if (existing) {
96
+ diagnostics.push({
97
+ _tag: "DuplicateSkill",
98
+ name: skill.name,
99
+ sourceId: source.id,
100
+ keptSourceId: existing.sourceId
101
+ });
102
+ continue;
103
+ }
104
+ entries.set(skill.name, {
105
+ skill,
106
+ sourceId: source.id,
107
+ resources,
108
+ ...location === void 0 ? {} : { location }
109
+ });
110
+ sourceBySkill.set(skill.name, source);
111
+ for (const warning of warnings ?? []) diagnostics.push({
112
+ _tag: "SkillWarning",
113
+ sourceId: source.id,
114
+ name: skill.name,
115
+ error: warning
116
+ });
117
+ }
118
+ }
119
+ const skills = [...entries.values()].filter((entry) => isModelInvocable(entry.skill));
120
+ const visible = new Map(skills.map((entry) => [entry.skill.name, entry]));
121
+ const prompt = renderCatalogPrompt(skills);
122
+ const catalog = {
123
+ fingerprint: fingerprintOf(prompt ?? ""),
124
+ skills,
125
+ diagnostics,
126
+ prompt: () => prompt,
127
+ find: (name) => visible.get(name),
128
+ activate(name) {
129
+ const entry = visible.get(name);
130
+ return entry ? ok(renderSkillActivation(entry)) : err(new UnknownSkillError(name));
131
+ },
132
+ async readResource(request) {
133
+ const target = resolveResourceTarget(visible, request);
134
+ if (!target.ok) return target;
135
+ const { entry, path } = target.value;
136
+ const source = sourceBySkill.get(entry.skill.name);
137
+ if (!source) return err(new UnknownSkillError(entry.skill.name));
138
+ const read = await source.readResource(entry.skill.name, path).catch((cause) => err(new SkillSourceError(source.id, "read-resource", cause)));
139
+ if (!read.ok) return read;
140
+ return ok({
141
+ entry,
142
+ resource: read.value
143
+ });
144
+ }
145
+ };
146
+ catalogListings.set(catalog, goodListings);
147
+ return catalog;
148
+ }
149
+ /**
150
+ * Describe a diagnostic in one line, for logs.
151
+ *
152
+ * @param diagnostic - A diagnostic from {@link SkillCatalog.diagnostics}.
153
+ */
154
+ function formatSkillDiagnostic(diagnostic) {
155
+ switch (diagnostic._tag) {
156
+ case "InvalidSkill": return `Skipped invalid skill ${diagnostic.location} from source "${diagnostic.sourceId}": ${diagnostic.error.message}`;
157
+ case "SkillWarning": return `Skill "${diagnostic.name}" from source "${diagnostic.sourceId}" breaks the Agent Skills spec but was loaded: ${diagnostic.error.message}`;
158
+ case "SourceFailed": return `${diagnostic.error.message}. ${diagnostic.keptPrevious ? "Its last listed skills were kept." : "Its skills were skipped."}`;
159
+ case "DuplicateSkill": return `Duplicate skill "${diagnostic.name}" from source "${diagnostic.sourceId}" ignored; already provided by "${diagnostic.keptSourceId}".`;
160
+ }
161
+ }
162
+ /**
163
+ * Render a resource read for the model.
164
+ *
165
+ * @param read - A resource returned by {@link SkillCatalog.readResource}.
166
+ */
167
+ function renderSkillResource(read) {
168
+ const { entry, resource } = read;
169
+ return [
170
+ `<skill_resource${attributes([
171
+ ["name", entry.skill.name],
172
+ ["path", resource.path],
173
+ ["kind", resource.kind],
174
+ ["encoding", resource.encoding],
175
+ ["mimeType", resource.mimeType]
176
+ ])}>`,
177
+ resource.content,
178
+ "</skill_resource>"
179
+ ].join("\n");
180
+ }
181
+ function renderCatalogPrompt(skills) {
182
+ if (skills.length === 0) return null;
183
+ return [
184
+ "Available skills. When a task matches a skill, use activate_skill with its name before proceeding.",
185
+ "",
186
+ ...skills.map(({ skill }) => `- ${skill.name}: ${skill.description.replace(/\s+/g, " ")}`)
187
+ ].join("\n");
188
+ }
189
+ function renderSkillActivation(entry) {
190
+ const lines = [`<skill_content${attributes([["name", entry.skill.name], ["location", entry.location]])}>`, entry.skill.body.trim()];
191
+ if (entry.resources.length > 0) {
192
+ lines.push("", "<skill_resources>");
193
+ for (const resource of entry.resources) lines.push(` <file${attributes([
194
+ ["kind", resource.kind],
195
+ ["encoding", resource.encoding],
196
+ ["size", resource.size === void 0 ? void 0 : String(resource.size)]
197
+ ])}>${resource.path}</file>`);
198
+ lines.push("</skill_resources>");
199
+ }
200
+ lines.push("</skill_content>");
201
+ return lines.join("\n");
202
+ }
203
+ function resolveResourceTarget(skills, request) {
204
+ let name = request.name;
205
+ let relative = request.path;
206
+ if (name === void 0) {
207
+ const slash = relative.indexOf("/");
208
+ if (slash <= 0) return err(new InvalidSkillResourcePathError(relative));
209
+ name = relative.slice(0, slash);
210
+ relative = relative.slice(slash + 1);
211
+ }
212
+ const entry = skills.get(name);
213
+ if (!entry) return err(new UnknownSkillError(name));
214
+ const path = parseSkillResourcePath(relative);
215
+ if (!path.ok) return path;
216
+ if (!entry.resources.some((resource) => resource.path === path.value)) return err(new SkillResourceNotFoundError(entry.skill.name, path.value));
217
+ return ok({
218
+ entry,
219
+ path: path.value
220
+ });
221
+ }
222
+ function attributes(pairs) {
223
+ return pairs.filter((pair) => pair[1] !== void 0).map(([key, value]) => ` ${key}="${value.replace(/"/g, "&quot;")}"`).join("");
224
+ }
225
+ /** Two FNV-1a passes with different seeds: cheap and stable across isolates. */
226
+ function fingerprintOf(text) {
227
+ let a = 2166136261;
228
+ let b = 16777619;
229
+ for (let index = 0; index < text.length; index++) {
230
+ const code = text.charCodeAt(index);
231
+ a = Math.imul(a ^ code, 16777619);
232
+ b = Math.imul(b ^ code, 2166136261);
233
+ }
234
+ return `${(a >>> 0).toString(16).padStart(8, "0")}${(b >>> 0).toString(16).padStart(8, "0")}`;
235
+ }
236
+ //#endregion
237
+ export { SkillResourceNotFoundError as a, renderSkillResource as i, formatSkillDiagnostic as n, SkillSourceError as o, loadSkillCatalog as r, UnknownSkillError as t };
238
+
239
+ //# sourceMappingURL=catalog-BpOejOsE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-BpOejOsE.js","names":[],"sources":["../src/skills/source.ts","../src/skills/catalog.ts"],"sourcesContent":["import type { SkillResult } from \"./result\";\nimport type {\n SkillResource,\n SkillResourceInfo,\n SkillResourcePath\n} from \"./resource\";\nimport type { Skill, SkillName, SkillParseError } from \"./skill\";\n\n/**\n * Where skills are loaded from: a Computer Workspace, an R2 bucket, an\n * in-memory manifest, or a custom store.\n *\n * A source lists every skill it holds on each call, so changes show up the\n * next time a catalog is loaded. Expected failures are returned, not thrown.\n */\nexport interface SkillSource {\n /** Stable identifier used in diagnostics and duplicate-name warnings. */\n readonly id: string;\n /**\n * List the skills this source holds.\n *\n * @returns Valid skills and the skills that failed to parse, or\n * `SkillSourceError` when the store could not be read.\n */\n list(): Promise<SkillResult<SkillListing, SkillSourceError>>;\n /**\n * Read one file bundled with a skill.\n *\n * @param skill - The skill that owns the file.\n * @param path - Path relative to the skill directory.\n */\n readResource(\n skill: SkillName,\n path: SkillResourcePath\n ): Promise<\n SkillResult<SkillResource, SkillResourceNotFoundError | SkillSourceError>\n >;\n}\n\n/** Everything a source found in one {@link SkillSource.list} call. */\nexport interface SkillListing {\n /** Skills that parsed, in a stable order. */\n readonly skills: readonly ListedSkill[];\n /** Skills that did not follow the spec and were left out. */\n readonly invalid: readonly InvalidSkill[];\n}\n\n/** A valid skill and the files bundled with it. */\nexport interface ListedSkill {\n /** The parsed `SKILL.md`. */\n readonly skill: Skill;\n /** Files in the skill directory other than `SKILL.md`. */\n readonly resources: readonly SkillResourceInfo[];\n /**\n * Absolute directory of the skill in the agent's filesystem, when the\n * source stores skills there. Agents with a shell can run scripts from it.\n */\n readonly location?: string;\n /**\n * Spec rules the skill breaks but was loaded anyway, for example a name\n * that does not match its directory, as the spec's guide for agents\n * recommends.\n */\n readonly warnings?: readonly SkillParseError[];\n}\n\n/** A skill that failed to parse. */\nexport interface InvalidSkill {\n /** Where the broken skill lives, such as `my-skill/SKILL.md`. */\n readonly location: string;\n /** Which spec rule it broke. */\n readonly error: SkillParseError;\n}\n\n/** A source's backing store failed. */\nexport class SkillSourceError extends Error {\n /** Stable tag for narrowing. */\n readonly _tag = \"SkillSourceError\" as const;\n\n /**\n * @param sourceId - The source that failed.\n * @param operation - What the source was doing.\n * @param cause - The underlying store error.\n */\n constructor(\n readonly sourceId: string,\n readonly operation: \"list\" | \"read-resource\",\n cause: unknown\n ) {\n super(\n `Skill source \"${sourceId}\" failed to ${operation === \"list\" ? \"list skills\" : \"read a resource\"}: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause }\n );\n this.name = \"SkillSourceError\";\n }\n}\n\n/** A skill has no file at the requested path. */\nexport class SkillResourceNotFoundError extends Error {\n /** Stable tag for narrowing. */\n readonly _tag = \"SkillResourceNotFoundError\" as const;\n\n /**\n * @param skill - The skill that was searched.\n * @param path - The missing path.\n */\n constructor(\n readonly skill: SkillName,\n readonly path: string\n ) {\n super(`Resource not found: ${skill}/${path}`);\n this.name = \"SkillResourceNotFoundError\";\n }\n}\n","import { err, ok, type SkillResult } from \"./result\";\nimport {\n InvalidSkillResourcePathError,\n parseSkillResourcePath,\n type SkillResource,\n type SkillResourceInfo\n} from \"./resource\";\nimport { isModelInvocable, type Skill, type SkillParseError } from \"./skill\";\nimport {\n SkillResourceNotFoundError,\n SkillSourceError,\n type SkillListing,\n type SkillSource\n} from \"./source\";\n\n/**\n * The skills an agent can use right now, merged from its sources.\n *\n * Load one with {@link loadSkillCatalog}; load it again to pick up changes.\n * Framework adapters (Think's AI SDK tools, the pi `skills()` extension)\n * wrap a catalog so every framework shows the model the same catalog text,\n * activation output, and resource output.\n */\nexport interface SkillCatalog {\n /** Changes whenever {@link prompt} would change. */\n readonly fingerprint: string;\n /** Skills the model may activate, in source priority order. */\n readonly skills: readonly SkillCatalogEntry[];\n /** Problems found while loading: invalid skills, failed sources, duplicates. */\n readonly diagnostics: readonly SkillDiagnostic[];\n /**\n * System-prompt text listing each skill's name and description.\n *\n * @returns The catalog prompt, or `null` when there are no skills.\n */\n prompt(): string | null;\n /**\n * Find a skill by name.\n *\n * @param name - Skill name.\n * @returns The entry, or `undefined` when the catalog has no such skill.\n */\n find(name: string): SkillCatalogEntry | undefined;\n /**\n * Render a skill's instructions and resource list for the model.\n *\n * @param name - Skill name.\n */\n activate(name: string): SkillResult<string, UnknownSkillError>;\n /**\n * Read a bundled file.\n *\n * @param request - Either `name` and a skill-relative `path`, or a\n * qualified `path` such as `my-skill/references/guide.md`.\n */\n readResource(request: {\n readonly name?: string;\n readonly path: string;\n }): Promise<SkillResult<SkillCatalogResource, SkillResourceError>>;\n}\n\n/** A skill in a {@link SkillCatalog}. */\nexport interface SkillCatalogEntry {\n /** The parsed skill. */\n readonly skill: Skill;\n /** Id of the source that provided it. */\n readonly sourceId: string;\n /** Files bundled with the skill. */\n readonly resources: readonly SkillResourceInfo[];\n /** Absolute directory in the agent's filesystem, when the source has one. */\n readonly location?: string;\n}\n\n/** A resource read through a {@link SkillCatalog}. */\nexport interface SkillCatalogResource {\n /** The skill that owns the resource. */\n readonly entry: SkillCatalogEntry;\n /** The resource and its content. */\n readonly resource: SkillResource;\n}\n\n/** Why {@link SkillCatalog.readResource} failed. */\nexport type SkillResourceError =\n | UnknownSkillError\n | InvalidSkillResourcePathError\n | SkillResourceNotFoundError\n | SkillSourceError;\n\n/** A problem found while loading a catalog. Never fatal. */\nexport type SkillDiagnostic =\n | {\n /** A `SKILL.md` broke a spec rule and was skipped. */\n readonly _tag: \"InvalidSkill\";\n readonly sourceId: string;\n readonly location: string;\n readonly error: SkillParseError;\n }\n | {\n /**\n * A source could not be listed. With `previous`, its skills from the\n * previous catalog are kept (`keptPrevious`); otherwise it is skipped.\n */\n readonly _tag: \"SourceFailed\";\n readonly sourceId: string;\n readonly error: SkillSourceError;\n readonly keptPrevious: boolean;\n }\n | {\n /** A skill breaks a spec rule but was loaded anyway. */\n readonly _tag: \"SkillWarning\";\n readonly sourceId: string;\n readonly name: string;\n readonly error: SkillParseError;\n }\n | {\n /** A later source listed a name an earlier source already provided. */\n readonly _tag: \"DuplicateSkill\";\n readonly name: string;\n readonly sourceId: string;\n readonly keptSourceId: string;\n };\n\n/** The catalog has no skill with the requested name. */\nexport class UnknownSkillError extends Error {\n /** Stable tag for narrowing. */\n readonly _tag = \"UnknownSkillError\" as const;\n\n /** @param skill - The requested name. */\n constructor(readonly skill: string) {\n super(`Skill not found: ${skill}`);\n this.name = \"UnknownSkillError\";\n }\n}\n\n/** Options for {@link loadSkillCatalog}. */\nexport interface LoadSkillCatalogOptions {\n /**\n * The catalog this load replaces. When a source fails to list, its skills\n * from `previous` are kept, so a transient outage does not remove working\n * skills from the prompt and tools. Sources are matched by identity.\n */\n readonly previous?: SkillCatalog;\n}\n\n/**\n * Successful listings behind each catalog, by source object. Lets a later\n * load fall back to the last good listing of a failing source without\n * putting listings on the public catalog shape.\n */\nconst catalogListings = new WeakMap<\n SkillCatalog,\n ReadonlyMap<SkillSource, SkillListing>\n>();\n\n/**\n * Load every source and merge them into a catalog.\n *\n * Sources apply in order: the first source to list a name wins. A failing\n * source or an invalid skill becomes a diagnostic instead of an error, so\n * one bad source never hides the others. Skills that set\n * `disable-model-invocation: true` are left out.\n *\n * @param sources - Skill sources in priority order.\n * @param options - Pass `previous` to keep a failing source's last skills.\n * @returns The merged catalog.\n */\nexport async function loadSkillCatalog(\n sources: readonly SkillSource[],\n options: LoadSkillCatalogOptions = {}\n): Promise<SkillCatalog> {\n const previousListings = options.previous\n ? catalogListings.get(options.previous)\n : undefined;\n // Custom sources should return failures, but one that throws must still\n // not hide the others.\n const listings = await Promise.all(\n sources.map(async (source) => ({\n source,\n listed: await source\n .list()\n .catch((cause: unknown) =>\n err(new SkillSourceError(source.id, \"list\", cause))\n )\n }))\n );\n\n const diagnostics: SkillDiagnostic[] = [];\n const entries = new Map<string, SkillCatalogEntry>();\n // Resources are read from the source object that listed the skill, not\n // looked up by id, because two sources may share an id.\n const sourceBySkill = new Map<string, SkillSource>();\n const goodListings = new Map<SkillSource, SkillListing>();\n\n for (const { source, listed } of listings) {\n let listing: SkillListing;\n if (listed.ok) {\n listing = listed.value;\n } else {\n const fallback = previousListings?.get(source);\n diagnostics.push({\n _tag: \"SourceFailed\",\n sourceId: source.id,\n error: listed.error,\n keptPrevious: fallback !== undefined\n });\n if (!fallback) continue;\n listing = fallback;\n }\n goodListings.set(source, listing);\n for (const invalid of listing.invalid) {\n diagnostics.push({\n _tag: \"InvalidSkill\",\n sourceId: source.id,\n location: invalid.location,\n error: invalid.error\n });\n }\n for (const { skill, resources, location, warnings } of listing.skills) {\n const existing = entries.get(skill.name);\n if (existing) {\n diagnostics.push({\n _tag: \"DuplicateSkill\",\n name: skill.name,\n sourceId: source.id,\n keptSourceId: existing.sourceId\n });\n continue;\n }\n entries.set(skill.name, {\n skill,\n sourceId: source.id,\n resources,\n ...(location === undefined ? {} : { location })\n });\n sourceBySkill.set(skill.name, source);\n // Only for the copy the catalog keeps: a skipped duplicate already has\n // its own diagnostic, and \"was loaded\" would be false for it.\n for (const warning of warnings ?? []) {\n diagnostics.push({\n _tag: \"SkillWarning\",\n sourceId: source.id,\n name: skill.name,\n error: warning\n });\n }\n }\n }\n\n const skills = [...entries.values()].filter((entry) =>\n isModelInvocable(entry.skill)\n );\n const visible = new Map<string, SkillCatalogEntry>(\n skills.map((entry) => [entry.skill.name, entry])\n );\n const prompt = renderCatalogPrompt(skills);\n\n const catalog: SkillCatalog = {\n fingerprint: fingerprintOf(prompt ?? \"\"),\n skills,\n diagnostics,\n prompt: () => prompt,\n find: (name) => visible.get(name),\n activate(name) {\n const entry = visible.get(name);\n return entry\n ? ok(renderSkillActivation(entry))\n : err(new UnknownSkillError(name));\n },\n async readResource(request) {\n const target = resolveResourceTarget(visible, request);\n if (!target.ok) return target;\n const { entry, path } = target.value;\n const source = sourceBySkill.get(entry.skill.name);\n if (!source) return err(new UnknownSkillError(entry.skill.name));\n const read = await source\n .readResource(entry.skill.name, path)\n .catch((cause: unknown) =>\n err(new SkillSourceError(source.id, \"read-resource\", cause))\n );\n if (!read.ok) return read;\n return ok({ entry, resource: read.value });\n }\n };\n catalogListings.set(catalog, goodListings);\n return catalog;\n}\n\n/**\n * Describe a diagnostic in one line, for logs.\n *\n * @param diagnostic - A diagnostic from {@link SkillCatalog.diagnostics}.\n */\nexport function formatSkillDiagnostic(diagnostic: SkillDiagnostic): string {\n switch (diagnostic._tag) {\n case \"InvalidSkill\":\n return `Skipped invalid skill ${diagnostic.location} from source \"${diagnostic.sourceId}\": ${diagnostic.error.message}`;\n case \"SkillWarning\":\n return `Skill \"${diagnostic.name}\" from source \"${diagnostic.sourceId}\" breaks the Agent Skills spec but was loaded: ${diagnostic.error.message}`;\n case \"SourceFailed\":\n return `${diagnostic.error.message}. ${diagnostic.keptPrevious ? \"Its last listed skills were kept.\" : \"Its skills were skipped.\"}`;\n case \"DuplicateSkill\":\n return `Duplicate skill \"${diagnostic.name}\" from source \"${diagnostic.sourceId}\" ignored; already provided by \"${diagnostic.keptSourceId}\".`;\n }\n}\n\n/**\n * Render a resource read for the model.\n *\n * @param read - A resource returned by {@link SkillCatalog.readResource}.\n */\nexport function renderSkillResource(read: SkillCatalogResource): string {\n const { entry, resource } = read;\n return [\n `<skill_resource${attributes([\n [\"name\", entry.skill.name],\n [\"path\", resource.path],\n [\"kind\", resource.kind],\n [\"encoding\", resource.encoding],\n [\"mimeType\", resource.mimeType]\n ])}>`,\n resource.content,\n \"</skill_resource>\"\n ].join(\"\\n\");\n}\n\nfunction renderCatalogPrompt(\n skills: readonly SkillCatalogEntry[]\n): string | null {\n if (skills.length === 0) return null;\n return [\n \"Available skills. When a task matches a skill, use activate_skill with its name before proceeding.\",\n \"\",\n ...skills.map(\n ({ skill }) =>\n `- ${skill.name}: ${skill.description.replace(/\\s+/g, \" \")}`\n )\n ].join(\"\\n\");\n}\n\nfunction renderSkillActivation(entry: SkillCatalogEntry): string {\n const lines = [\n `<skill_content${attributes([\n [\"name\", entry.skill.name],\n [\"location\", entry.location]\n ])}>`,\n entry.skill.body.trim()\n ];\n if (entry.resources.length > 0) {\n lines.push(\"\", \"<skill_resources>\");\n for (const resource of entry.resources) {\n lines.push(\n ` <file${attributes([\n [\"kind\", resource.kind],\n [\"encoding\", resource.encoding],\n [\n \"size\",\n resource.size === undefined ? undefined : String(resource.size)\n ]\n ])}>${resource.path}</file>`\n );\n }\n lines.push(\"</skill_resources>\");\n }\n lines.push(\"</skill_content>\");\n return lines.join(\"\\n\");\n}\n\nfunction resolveResourceTarget(\n skills: ReadonlyMap<string, SkillCatalogEntry>,\n request: { readonly name?: string; readonly path: string }\n): SkillResult<\n {\n entry: SkillCatalogEntry;\n path: SkillResourceInfo[\"path\"];\n },\n UnknownSkillError | InvalidSkillResourcePathError | SkillResourceNotFoundError\n> {\n let name = request.name;\n let relative = request.path;\n if (name === undefined) {\n const slash = relative.indexOf(\"/\");\n if (slash <= 0) return err(new InvalidSkillResourcePathError(relative));\n name = relative.slice(0, slash);\n relative = relative.slice(slash + 1);\n }\n const entry = skills.get(name);\n if (!entry) return err(new UnknownSkillError(name));\n const path = parseSkillResourcePath(relative);\n if (!path.ok) return path;\n // Only files the source listed are readable, whatever the source's store\n // holds beside them.\n if (!entry.resources.some((resource) => resource.path === path.value)) {\n return err(new SkillResourceNotFoundError(entry.skill.name, path.value));\n }\n return ok({ entry, path: path.value });\n}\n\nfunction attributes(\n pairs: ReadonlyArray<readonly [string, string | undefined]>\n): string {\n return pairs\n .filter((pair): pair is readonly [string, string] => pair[1] !== undefined)\n .map(([key, value]) => ` ${key}=\"${value.replace(/\"/g, \"&quot;\")}\"`)\n .join(\"\");\n}\n\n/** Two FNV-1a passes with different seeds: cheap and stable across isolates. */\nfunction fingerprintOf(text: string): string {\n let a = 0x811c9dc5;\n let b = 0x01000193;\n for (let index = 0; index < text.length; index++) {\n const code = text.charCodeAt(index);\n a = Math.imul(a ^ code, 0x01000193);\n b = Math.imul(b ^ code, 0x811c9dc5);\n }\n return `${(a >>> 0).toString(16).padStart(8, \"0\")}${(b >>> 0).toString(16).padStart(8, \"0\")}`;\n}\n"],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ import {
2
+ d as SkillResourceInfo,
3
+ h as SkillResult,
4
+ i as SkillParseError,
5
+ l as InvalidSkillResourcePathError,
6
+ n as Skill,
7
+ u as SkillResource
8
+ } from "./skill-DRBcIBjC.js";
9
+ import {
10
+ a as SkillSource,
11
+ i as SkillResourceNotFoundError,
12
+ o as SkillSourceError
13
+ } from "./source-9RQzlEhM.js";
14
+
15
+ //#region src/skills/catalog.d.ts
16
+ /**
17
+ * The skills an agent can use right now, merged from its sources.
18
+ *
19
+ * Load one with {@link loadSkillCatalog}; load it again to pick up changes.
20
+ * Framework adapters (Think's AI SDK tools, the pi `skills()` extension)
21
+ * wrap a catalog so every framework shows the model the same catalog text,
22
+ * activation output, and resource output.
23
+ */
24
+ interface SkillCatalog {
25
+ /** Changes whenever {@link prompt} would change. */
26
+ readonly fingerprint: string;
27
+ /** Skills the model may activate, in source priority order. */
28
+ readonly skills: readonly SkillCatalogEntry[];
29
+ /** Problems found while loading: invalid skills, failed sources, duplicates. */
30
+ readonly diagnostics: readonly SkillDiagnostic[];
31
+ /**
32
+ * System-prompt text listing each skill's name and description.
33
+ *
34
+ * @returns The catalog prompt, or `null` when there are no skills.
35
+ */
36
+ prompt(): string | null;
37
+ /**
38
+ * Find a skill by name.
39
+ *
40
+ * @param name - Skill name.
41
+ * @returns The entry, or `undefined` when the catalog has no such skill.
42
+ */
43
+ find(name: string): SkillCatalogEntry | undefined;
44
+ /**
45
+ * Render a skill's instructions and resource list for the model.
46
+ *
47
+ * @param name - Skill name.
48
+ */
49
+ activate(name: string): SkillResult<string, UnknownSkillError>;
50
+ /**
51
+ * Read a bundled file.
52
+ *
53
+ * @param request - Either `name` and a skill-relative `path`, or a
54
+ * qualified `path` such as `my-skill/references/guide.md`.
55
+ */
56
+ readResource(request: {
57
+ readonly name?: string;
58
+ readonly path: string;
59
+ }): Promise<SkillResult<SkillCatalogResource, SkillResourceError>>;
60
+ }
61
+ /** A skill in a {@link SkillCatalog}. */
62
+ interface SkillCatalogEntry {
63
+ /** The parsed skill. */
64
+ readonly skill: Skill;
65
+ /** Id of the source that provided it. */
66
+ readonly sourceId: string;
67
+ /** Files bundled with the skill. */
68
+ readonly resources: readonly SkillResourceInfo[];
69
+ /** Absolute directory in the agent's filesystem, when the source has one. */
70
+ readonly location?: string;
71
+ }
72
+ /** A resource read through a {@link SkillCatalog}. */
73
+ interface SkillCatalogResource {
74
+ /** The skill that owns the resource. */
75
+ readonly entry: SkillCatalogEntry;
76
+ /** The resource and its content. */
77
+ readonly resource: SkillResource;
78
+ }
79
+ /** Why {@link SkillCatalog.readResource} failed. */
80
+ type SkillResourceError =
81
+ | UnknownSkillError
82
+ | InvalidSkillResourcePathError
83
+ | SkillResourceNotFoundError
84
+ | SkillSourceError;
85
+ /** A problem found while loading a catalog. Never fatal. */
86
+ type SkillDiagnostic =
87
+ | {
88
+ /** A `SKILL.md` broke a spec rule and was skipped. */ readonly _tag: "InvalidSkill";
89
+ readonly sourceId: string;
90
+ readonly location: string;
91
+ readonly error: SkillParseError;
92
+ }
93
+ | {
94
+ /**
95
+ * A source could not be listed. With `previous`, its skills from the
96
+ * previous catalog are kept (`keptPrevious`); otherwise it is skipped.
97
+ */
98
+ readonly _tag: "SourceFailed";
99
+ readonly sourceId: string;
100
+ readonly error: SkillSourceError;
101
+ readonly keptPrevious: boolean;
102
+ }
103
+ | {
104
+ /** A skill breaks a spec rule but was loaded anyway. */ readonly _tag: "SkillWarning";
105
+ readonly sourceId: string;
106
+ readonly name: string;
107
+ readonly error: SkillParseError;
108
+ }
109
+ | {
110
+ /** A later source listed a name an earlier source already provided. */ readonly _tag: "DuplicateSkill";
111
+ readonly name: string;
112
+ readonly sourceId: string;
113
+ readonly keptSourceId: string;
114
+ };
115
+ /** The catalog has no skill with the requested name. */
116
+ declare class UnknownSkillError extends Error {
117
+ readonly skill: string;
118
+ /** Stable tag for narrowing. */
119
+ readonly _tag: "UnknownSkillError";
120
+ /** @param skill - The requested name. */
121
+ constructor(skill: string);
122
+ }
123
+ /** Options for {@link loadSkillCatalog}. */
124
+ interface LoadSkillCatalogOptions {
125
+ /**
126
+ * The catalog this load replaces. When a source fails to list, its skills
127
+ * from `previous` are kept, so a transient outage does not remove working
128
+ * skills from the prompt and tools. Sources are matched by identity.
129
+ */
130
+ readonly previous?: SkillCatalog;
131
+ }
132
+ /**
133
+ * Load every source and merge them into a catalog.
134
+ *
135
+ * Sources apply in order: the first source to list a name wins. A failing
136
+ * source or an invalid skill becomes a diagnostic instead of an error, so
137
+ * one bad source never hides the others. Skills that set
138
+ * `disable-model-invocation: true` are left out.
139
+ *
140
+ * @param sources - Skill sources in priority order.
141
+ * @param options - Pass `previous` to keep a failing source's last skills.
142
+ * @returns The merged catalog.
143
+ */
144
+ declare function loadSkillCatalog(
145
+ sources: readonly SkillSource[],
146
+ options?: LoadSkillCatalogOptions
147
+ ): Promise<SkillCatalog>;
148
+ /**
149
+ * Describe a diagnostic in one line, for logs.
150
+ *
151
+ * @param diagnostic - A diagnostic from {@link SkillCatalog.diagnostics}.
152
+ */
153
+ declare function formatSkillDiagnostic(diagnostic: SkillDiagnostic): string;
154
+ /**
155
+ * Render a resource read for the model.
156
+ *
157
+ * @param read - A resource returned by {@link SkillCatalog.readResource}.
158
+ */
159
+ declare function renderSkillResource(read: SkillCatalogResource): string;
160
+ //#endregion
161
+ export {
162
+ SkillDiagnostic as a,
163
+ formatSkillDiagnostic as c,
164
+ SkillCatalogResource as i,
165
+ loadSkillCatalog as l,
166
+ SkillCatalog as n,
167
+ SkillResourceError as o,
168
+ SkillCatalogEntry as r,
169
+ UnknownSkillError as s,
170
+ LoadSkillCatalogOptions as t,
171
+ renderSkillResource as u
172
+ };
173
+ //# sourceMappingURL=catalog-BpiVV1OF.d.ts.map
@@ -9,7 +9,7 @@ import {
9
9
  _ as FiberRecoveryContext$1,
10
10
  at as isPositionlessAgentToolChunk,
11
11
  z as AgentToolEventState
12
- } from "../agent-routing-wS1TimZ_.js";
12
+ } from "../agent-routing-vVMA7m8Y.js";
13
13
  import { _ as TaskStep, m as TaskRunOptions } from "../tasks-E89KdwkS.js";
14
14
  import {
15
15
  n as ClientToolSchema,
@@ -34,7 +34,7 @@ import {
34
34
  r as AgentToolProgressEmitResult,
35
35
  s as interceptAgentToolBroadcast,
36
36
  t as AgentToolBroadcastHooks
37
- } from "../agent-tools-Bamxxb6Y.js";
37
+ } from "../agent-tools-gGXXkf1z.js";
38
38
  import { l as SessionMessage } from "../types-B7LojTe4.js";
39
39
  import { ModelMessage, UIMessage } from "ai";
40
40
  import { Connection, FiberRecoveryContext } from "agents";
@@ -2,7 +2,7 @@ import {
2
2
  c as Agent,
3
3
  nn as DynamicAgentStub,
4
4
  tn as DynamicAgentClass
5
- } from "../agent-routing-wS1TimZ_.js";
5
+ } from "../agent-routing-vVMA7m8Y.js";
6
6
  import { Lock, QueueEntry, StateAdapter } from "chat";
7
7
 
8
8
  //#region src/chat-sdk/agent.d.ts
@@ -1,4 +1,4 @@
1
- import { i as getCurrentAgent, t as Agent } from "../src-BGolXG_H.js";
1
+ import { i as getCurrentAgent, t as Agent } from "../src-DoGNJ4Ud.js";
2
2
  //#region src/chat-sdk/agent.ts
3
3
  const NEXT_CLEANUP_AT_KEY = "next_cleanup_at";
4
4
  const CLEANUP_SCHEDULE_ID_KEY = "cleanup_schedule_id";
@@ -1,4 +1,4 @@
1
- import { c as Agent } from "./agent-routing-wS1TimZ_.js";
1
+ import { c as Agent } from "./agent-routing-vVMA7m8Y.js";
2
2
  import {
3
3
  ClientParameters,
4
4
  Method,
@@ -445,4 +445,4 @@ export {
445
445
  splitCallOptions as x,
446
446
  isTerminalCloseEvent as y
447
447
  };
448
- //# sourceMappingURL=client-wn4-yqGz.d.ts.map
448
+ //# sourceMappingURL=client-eSfgYvd3.d.ts.map
package/dist/client.d.ts CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  v as createStubProxy,
22
22
  x as splitCallOptions,
23
23
  y as isTerminalCloseEvent
24
- } from "./client-wn4-yqGz.js";
24
+ } from "./client-eSfgYvd3.js";
25
25
  export {
26
26
  AgentClient,
27
27
  AgentClientFetchOptions,
@@ -124,7 +124,10 @@ var ManagedSpan = class {
124
124
  fail(cause) {
125
125
  if (_classPrivateFieldGet2(_closed, this)) return;
126
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 });
127
+ else {
128
+ setAttributes(this.span, { "error.type": cause instanceof Error ? cause.name || "Error" : typeof cause });
129
+ setErrorStatus(this.span);
130
+ }
128
131
  this.close();
129
132
  }
130
133
  close() {
@@ -176,6 +179,12 @@ function setAttributes(span, attributes) {
176
179
  for (const [key, value] of Object.entries(attributes)) if (value !== void 0) span.setAttribute(key, value);
177
180
  } catch {}
178
181
  }
182
+ function setErrorStatus(span) {
183
+ if (!span.isTraced || typeof span.setStatus !== "function") return;
184
+ try {
185
+ span.setStatus({ code: "error" });
186
+ } catch {}
187
+ }
179
188
  function isPromiseLike(value) {
180
189
  return value !== null && value !== void 0 && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
181
190
  }
@@ -189,6 +198,13 @@ function isCancellation(cause) {
189
198
  return typeof cause === "object" && cause !== null && "name" in cause && cause.name === "AbortError";
190
199
  }
191
200
  //#endregion
201
+ //#region src/observability/tracing/native.ts
202
+ /** Returns `tracing` when it carries the methods the Agents SDK needs. */
203
+ function resolveNativeTracing(tracing) {
204
+ const candidate = tracing;
205
+ return typeof candidate?.startActiveSpan === "function" && typeof candidate.getActiveSpan === "function" ? candidate : void 0;
206
+ }
207
+ //#endregion
192
208
  //#region src/observability/tracing/cloudflare.ts
193
209
  const noopSpan = {
194
210
  isTraced: false,
@@ -198,14 +214,20 @@ const noopSpan = {
198
214
  const noopRuntime = { startActiveSpan(_name, run) {
199
215
  return run(noopSpan);
200
216
  } };
201
- const runtime = resolveCloudflareSpanRuntime(cloudflareWorkers.tracing);
217
+ const workersTracing = cloudflareWorkers.tracing;
218
+ const runtime = resolveCloudflareSpanRuntime(workersTracing);
202
219
  /** Selects native Cloudflare tracing or a no-op for unsupported runtimes. */
203
220
  function resolveCloudflareSpanRuntime(runtime) {
204
221
  const candidate = runtime;
205
222
  return typeof candidate?.startActiveSpan === "function" ? candidate : noopRuntime;
206
223
  }
207
224
  const tracer = createTracer(runtime);
225
+ /**
226
+ * Workers native tracing, when the runtime can carry the OpenTelemetry bridge
227
+ * (`startActiveSpan` and `getActiveSpan`). `undefined` on older runtimes.
228
+ */
229
+ const nativeTracing = resolveNativeTracing(workersTracing);
208
230
  //#endregion
209
- export { withInvocationScope as n, writeSpanAttributes as r, tracer as t };
231
+ export { writeSpanAttributes as i, tracer as n, withInvocationScope as r, nativeTracing as t };
210
232
 
211
- //# sourceMappingURL=cloudflare-Dzvc7V2N.js.map
233
+ //# sourceMappingURL=cloudflare-CUUm_9q9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-CUUm_9q9.js","names":[],"sources":["../src/observability/tracing/tracer.ts","../src/observability/tracing/native.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 * Sets the span status. Workers added `Span.setStatus()` in the 2026-10-26\n * runtime release; older runtimes do not have it.\n */\n setStatus?(status: { readonly code: \"error\" }): unknown;\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 // error.type stays the low-cardinality, queryable marker; status is span\n // state, set where the runtime supports it. No description: the cause\n // message is never recorded.\n setAttributes(this.span, {\n \"error.type\":\n cause instanceof Error ? cause.name || \"Error\" : typeof cause\n });\n setErrorStatus(this.span);\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 setErrorStatus(span: SpanWriter): void {\n if (!span.isTraced || typeof span.setStatus !== \"function\") {\n return;\n }\n\n // Fail-safe, like setAttributes: telemetry must not replace the\n // application's original error.\n try {\n span.setStatus({ code: \"error\" });\n } catch {\n // 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","/**\n * The subset of Workers native tracing (`import { tracing } from\n * \"cloudflare:workers\"`) that the Agents SDK builds on. Methods added in later\n * runtime releases are optional and feature-detected per call, so an older\n * runtime degrades (no IDs, no status, no rename) instead of throwing.\n */\n\n/** A scalar attribute value accepted by native spans. */\nexport type NativeAttributeValue = string | number | boolean;\n\n/** Native span identity, matching the IDs Workers Observability exports. */\nexport type NativeSpanContext = {\n readonly traceId: string;\n readonly spanId: string;\n readonly traceFlags: number;\n};\n\n/** Native span status. */\nexport type NativeSpanStatus = {\n readonly code: \"unset\" | \"ok\" | \"error\";\n readonly message?: string;\n};\n\n/** An exception accepted by `Span.recordException`. */\nexport type NativeException =\n | string\n | {\n readonly code?: string | number;\n readonly name?: string;\n readonly message?: string;\n readonly stack?: string;\n };\n\n/** A native span. */\nexport type NativeSpan = {\n /**\n * False when observability is disabled, and after `end()`. Does not reflect\n * head sampling: an unsampled request can report `true`.\n */\n readonly isTraced: boolean;\n setAttribute(key: string, value: NativeAttributeValue): unknown;\n recordException(exception: NativeException): void;\n /** Idempotent; no effect on the invocation root span. */\n end(): void;\n /** Added in the 2026-10-26 runtime release. */\n spanContext?(): NativeSpanContext;\n /**\n * Added in the 2026-10-26 runtime release. Applies OTel's rules: `ok` is\n * final, `unset` has no effect, the message is kept only with `error`, and\n * calls after `end()` are ignored.\n */\n setStatus?(status: NativeSpanStatus): unknown;\n /** Added in the 2026-10-26 runtime release. */\n updateName?(name: string): unknown;\n};\n\n/** Native tracing: async-context span activation. */\nexport type NativeTracing = {\n /**\n * Opens a span that is the active parent while `callback` runs. The caller\n * ends it; it stays open after `callback` returns but is no longer active.\n */\n startActiveSpan<T>(name: string, callback: (span: NativeSpan) => T): T;\n /**\n * The active span: the innermost custom span, or the invocation root span.\n * `undefined` outside a request.\n */\n getActiveSpan(): NativeSpan | undefined;\n};\n\n/** Returns `tracing` when it carries the methods the Agents SDK needs. */\nexport function resolveNativeTracing(\n tracing: unknown\n): NativeTracing | undefined {\n const candidate = tracing as Partial<NativeTracing> | null | undefined;\n return typeof candidate?.startActiveSpan === \"function\" &&\n typeof candidate.getActiveSpan === \"function\"\n ? (candidate as NativeTracing)\n : undefined;\n}\n","import * as cloudflareWorkers from \"cloudflare:workers\";\nimport { createTracer } from \"./tracer\";\nimport type { SpanRuntime, SpanWriter, AgentTracer } from \"./tracer\";\nimport { resolveNativeTracing } from \"./native\";\nimport type { NativeTracing } from \"./native\";\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 because this loads with the main `agents` entry.\n// Runtimes can omit `tracing` or expose it without `startActiveSpan`; both\n// degrade to no-op tracing instead of breaking Agent behavior.\nconst workersTracing = (cloudflareWorkers as { tracing?: unknown }).tracing;\nconst runtime = resolveCloudflareSpanRuntime(workersTracing);\n\n/** Selects native Cloudflare tracing or a no-op for unsupported runtimes. */\nexport function resolveCloudflareSpanRuntime(runtime: unknown): SpanRuntime {\n const candidate = runtime as Partial<SpanRuntime> | null | undefined;\n return typeof candidate?.startActiveSpan === \"function\"\n ? (candidate as SpanRuntime)\n : noopRuntime;\n}\n\nexport const tracer: AgentTracer = createTracer(runtime);\n\n/**\n * Workers native tracing, when the runtime can carry the OpenTelemetry bridge\n * (`startActiveSpan` and `getActiveSpan`). `undefined` on older runtimes.\n */\nexport const nativeTracing: NativeTracing | undefined =\n resolveNativeTracing(workersTracing);\n"],"mappings":"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"}