autotel-genai 0.1.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 (108) hide show
  1. package/README.md +149 -0
  2. package/dist/agent/index.cjs +24 -0
  3. package/dist/agent/index.d.cts +3 -0
  4. package/dist/agent/index.d.ts +3 -0
  5. package/dist/agent/index.js +3 -0
  6. package/dist/agent-CqXauTpC.js +951 -0
  7. package/dist/agent-CqXauTpC.js.map +1 -0
  8. package/dist/agent-eo4jY4Xg.cjs +1076 -0
  9. package/dist/agent-eo4jY4Xg.cjs.map +1 -0
  10. package/dist/ai-sdk-bridge.cjs +134 -0
  11. package/dist/ai-sdk-bridge.cjs.map +1 -0
  12. package/dist/ai-sdk-bridge.d.cts +59 -0
  13. package/dist/ai-sdk-bridge.d.cts.map +1 -0
  14. package/dist/ai-sdk-bridge.d.ts +59 -0
  15. package/dist/ai-sdk-bridge.d.ts.map +1 -0
  16. package/dist/ai-sdk-bridge.js +127 -0
  17. package/dist/ai-sdk-bridge.js.map +1 -0
  18. package/dist/attributes--Pdezjj6.js +119 -0
  19. package/dist/attributes--Pdezjj6.js.map +1 -0
  20. package/dist/attributes-DB35Boji.cjs +166 -0
  21. package/dist/attributes-DB35Boji.cjs.map +1 -0
  22. package/dist/attributes-QRj0DPJH.d.ts +106 -0
  23. package/dist/attributes-QRj0DPJH.d.ts.map +1 -0
  24. package/dist/attributes-kyiOdake.d.cts +106 -0
  25. package/dist/attributes-kyiOdake.d.cts.map +1 -0
  26. package/dist/cost-DXTkBUUW.d.cts +72 -0
  27. package/dist/cost-DXTkBUUW.d.cts.map +1 -0
  28. package/dist/cost-DXTkBUUW.d.ts +72 -0
  29. package/dist/cost-DXTkBUUW.d.ts.map +1 -0
  30. package/dist/cost.cjs +138 -0
  31. package/dist/cost.cjs.map +1 -0
  32. package/dist/cost.d.cts +2 -0
  33. package/dist/cost.d.ts +2 -0
  34. package/dist/cost.js +134 -0
  35. package/dist/cost.js.map +1 -0
  36. package/dist/events.cjs +88 -0
  37. package/dist/events.cjs.map +1 -0
  38. package/dist/events.d.cts +89 -0
  39. package/dist/events.d.cts.map +1 -0
  40. package/dist/events.d.ts +89 -0
  41. package/dist/events.d.ts.map +1 -0
  42. package/dist/events.js +84 -0
  43. package/dist/events.js.map +1 -0
  44. package/dist/index-D1gH80Xd.d.ts +403 -0
  45. package/dist/index-D1gH80Xd.d.ts.map +1 -0
  46. package/dist/index-DtjGz80V.d.cts +403 -0
  47. package/dist/index-DtjGz80V.d.cts.map +1 -0
  48. package/dist/index.cjs +72 -0
  49. package/dist/index.d.cts +9 -0
  50. package/dist/index.d.ts +9 -0
  51. package/dist/index.js +10 -0
  52. package/dist/metrics.cjs +166 -0
  53. package/dist/metrics.cjs.map +1 -0
  54. package/dist/metrics.d.cts +52 -0
  55. package/dist/metrics.d.cts.map +1 -0
  56. package/dist/metrics.d.ts +52 -0
  57. package/dist/metrics.d.ts.map +1 -0
  58. package/dist/metrics.js +161 -0
  59. package/dist/metrics.js.map +1 -0
  60. package/dist/semconv-CGiMo_LV.d.cts +190 -0
  61. package/dist/semconv-CGiMo_LV.d.cts.map +1 -0
  62. package/dist/semconv-CGiMo_LV.d.ts +190 -0
  63. package/dist/semconv-CGiMo_LV.d.ts.map +1 -0
  64. package/dist/semconv.cjs +196 -0
  65. package/dist/semconv.cjs.map +1 -0
  66. package/dist/semconv.d.cts +2 -0
  67. package/dist/semconv.d.ts +2 -0
  68. package/dist/semconv.js +186 -0
  69. package/dist/semconv.js.map +1 -0
  70. package/dist/trace.cjs +119 -0
  71. package/dist/trace.cjs.map +1 -0
  72. package/dist/trace.d.cts +42 -0
  73. package/dist/trace.d.cts.map +1 -0
  74. package/dist/trace.d.ts +42 -0
  75. package/dist/trace.d.ts.map +1 -0
  76. package/dist/trace.js +115 -0
  77. package/dist/trace.js.map +1 -0
  78. package/package.json +113 -0
  79. package/src/agent/agent.test.ts +874 -0
  80. package/src/agent/attributes.ts +162 -0
  81. package/src/agent/constants.ts +1 -0
  82. package/src/agent/context.ts +125 -0
  83. package/src/agent/delegation.ts +98 -0
  84. package/src/agent/hash.ts +44 -0
  85. package/src/agent/identity-registry.ts +188 -0
  86. package/src/agent/index.ts +45 -0
  87. package/src/agent/metadata.ts +254 -0
  88. package/src/agent/non-repudiation.ts +70 -0
  89. package/src/agent/privacy.ts +128 -0
  90. package/src/agent/runtime.ts +294 -0
  91. package/src/agent/scoped-tool.ts +221 -0
  92. package/src/agent/session.ts +66 -0
  93. package/src/agent/types.ts +311 -0
  94. package/src/ai-sdk-bridge.test.ts +96 -0
  95. package/src/ai-sdk-bridge.ts +209 -0
  96. package/src/attributes.test.ts +148 -0
  97. package/src/attributes.ts +265 -0
  98. package/src/cost.test.ts +92 -0
  99. package/src/cost.ts +196 -0
  100. package/src/events.test.ts +82 -0
  101. package/src/events.ts +210 -0
  102. package/src/index.ts +178 -0
  103. package/src/metrics.test.ts +60 -0
  104. package/src/metrics.ts +128 -0
  105. package/src/semconv.test.ts +88 -0
  106. package/src/semconv.ts +240 -0
  107. package/src/trace.test.ts +167 -0
  108. package/src/trace.ts +181 -0
@@ -0,0 +1,951 @@
1
+ import { estimateLLMCost } from "./cost.js";
2
+ import { i as genAiResponseAttributes, r as genAiRequestAttributes, s as genAiUsageAttributes } from "./attributes--Pdezjj6.js";
3
+ import { createNoopRequestLogger, createStructuredError, getRequestLoggerSafe, getTraceContext, otelTrace } from "autotel";
4
+ import { createHash } from "node:crypto";
5
+ import { forceKeepAuditEvent, withAudit } from "autotel-audit";
6
+
7
+ //#region src/agent/constants.ts
8
+ const AGENT_AUDIT_SCHEMA_VERSION = "1.1.0";
9
+
10
+ //#endregion
11
+ //#region src/agent/hash.ts
12
+ function canonicalize(value) {
13
+ if (value instanceof Date) return value.toISOString();
14
+ if (typeof value === "bigint") return value.toString(10);
15
+ if (Array.isArray(value)) return value.map((entry) => canonicalize(entry));
16
+ if (value && typeof value === "object") {
17
+ const entries = Object.entries(value);
18
+ entries.sort(([left], [right]) => left.localeCompare(right));
19
+ return Object.fromEntries(entries.map(([key, entryValue]) => [key, canonicalize(entryValue)]));
20
+ }
21
+ return value;
22
+ }
23
+ function canonicalizeForHash(value) {
24
+ return JSON.stringify(canonicalize(value));
25
+ }
26
+ function hashPayload(value, options = {}) {
27
+ const algorithm = options.algorithm ?? "sha256";
28
+ const canonical = canonicalizeForHash(value);
29
+ return `${algorithm}:${createHash(algorithm).update(canonical).digest("hex")}`;
30
+ }
31
+
32
+ //#endregion
33
+ //#region src/agent/metadata.ts
34
+ function defaultEventKind(metadata) {
35
+ if (metadata.eventKind) return metadata.eventKind;
36
+ if (metadata.tool) return "tool_call";
37
+ if (metadata.policy) return "policy_decision";
38
+ return "action";
39
+ }
40
+ function normalizeTool(tool) {
41
+ if (!tool) return void 0;
42
+ return {
43
+ name: tool.name,
44
+ ...tool.callId !== void 0 && { callId: tool.callId },
45
+ inputHash: tool.input === void 0 ? tool.inputHash : tool.inputHash ?? hashPayload(tool.input),
46
+ outputHash: tool.output === void 0 ? tool.outputHash : tool.outputHash ?? hashPayload(tool.output),
47
+ ...tool.status !== void 0 && { status: tool.status },
48
+ ...tool.executionMs !== void 0 && { executionMs: tool.executionMs }
49
+ };
50
+ }
51
+ function sanitizeTool(tool) {
52
+ if (!tool) return void 0;
53
+ return {
54
+ name: tool.name,
55
+ ...tool.callId !== void 0 && { callId: tool.callId },
56
+ ...tool.inputHash !== void 0 && { inputHash: tool.inputHash },
57
+ ...tool.outputHash !== void 0 && { outputHash: tool.outputHash },
58
+ ...tool.status !== void 0 && { status: tool.status },
59
+ ...tool.executionMs !== void 0 && { executionMs: tool.executionMs }
60
+ };
61
+ }
62
+ function sanitizeGovernance(governance) {
63
+ if (!governance) return void 0;
64
+ return {
65
+ ...governance.reviewRequired !== void 0 && { reviewRequired: governance.reviewRequired },
66
+ ...governance.reviewerId !== void 0 && { reviewerId: governance.reviewerId },
67
+ ...governance.controlId !== void 0 && { controlId: governance.controlId },
68
+ ...governance.documentationUrl !== void 0 && { documentationUrl: governance.documentationUrl },
69
+ ...governance.lifecycleStage !== void 0 && { lifecycleStage: governance.lifecycleStage },
70
+ ...governance.framework !== void 0 && { framework: governance.framework }
71
+ };
72
+ }
73
+ function normalizeDecision(decision, reasoningSummary) {
74
+ if (decision) return {
75
+ ...decision,
76
+ summary: decision.summary ?? reasoningSummary ?? ""
77
+ };
78
+ if (reasoningSummary === void 0) return void 0;
79
+ return { summary: reasoningSummary };
80
+ }
81
+ function createAgentAuditMetadata(metadata) {
82
+ const eventKind = defaultEventKind(metadata);
83
+ if (eventKind === "tool_call" && !metadata.tool) throw new Error("[autotel-genai] eventKind \"tool_call\" requires metadata.tool.");
84
+ if (eventKind === "policy_decision" && !metadata.policy) throw new Error("[autotel-genai] eventKind \"policy_decision\" requires metadata.policy.");
85
+ if (eventKind === "handoff" && !metadata.delegation) throw new Error("[autotel-genai] eventKind \"handoff\" requires metadata.delegation.");
86
+ const delegation = metadata.delegation && (metadata.delegation.authorityLineageHash === void 0 || metadata.delegation.depth === void 0) ? {
87
+ ...metadata.delegation,
88
+ ...metadata.delegation.authorityLineage && {
89
+ authorityLineageHash: metadata.delegation.authorityLineageHash ?? hashPayload(metadata.delegation.authorityLineage),
90
+ depth: metadata.delegation.depth ?? Math.max(metadata.delegation.authorityLineage.length - 1, 0)
91
+ }
92
+ } : metadata.delegation;
93
+ return {
94
+ ...metadata,
95
+ schemaVersion: metadata.schemaVersion ?? "1.1.0",
96
+ eventKind,
97
+ decision: normalizeDecision(metadata.decision, metadata.reasoningSummary),
98
+ ...delegation !== void 0 && { delegation }
99
+ };
100
+ }
101
+ function normalizeMetadata(metadata) {
102
+ const normalized = createAgentAuditMetadata(metadata);
103
+ return {
104
+ ...normalized,
105
+ tool: normalizeTool(normalized.tool)
106
+ };
107
+ }
108
+ function buildAuditMetadata(metadata) {
109
+ return {
110
+ action: metadata.action,
111
+ ...metadata.resource !== void 0 && { resource: metadata.resource },
112
+ actorId: metadata.actorId ?? metadata.delegation?.parentIdentity ?? metadata.agent.id,
113
+ category: metadata.category ?? "agent",
114
+ ...metadata.outcome !== void 0 && { outcome: metadata.outcome },
115
+ agentId: metadata.agent.id,
116
+ agentEventKind: metadata.eventKind,
117
+ agentAuditVersion: metadata.schemaVersion,
118
+ ...metadata.agent.version !== void 0 && { agentVersion: metadata.agent.version },
119
+ ...metadata.tool?.name !== void 0 && { toolName: metadata.tool.name },
120
+ ...metadata.policy?.decision !== void 0 && { policyDecision: metadata.policy.decision },
121
+ ...metadata.session?.status !== void 0 && { sessionStatus: metadata.session.status }
122
+ };
123
+ }
124
+ function buildLoggerContext(metadata) {
125
+ const tool = sanitizeTool(metadata.tool);
126
+ const governance = sanitizeGovernance(metadata.governance);
127
+ const context = {
128
+ agent: {
129
+ ...metadata.agent,
130
+ ...metadata.resource !== void 0 && { resource: metadata.resource },
131
+ ...metadata.outcome !== void 0 && { outcome: metadata.outcome },
132
+ ...metadata.reasoningSummary !== void 0 && { reasoningSummary: metadata.reasoningSummary },
133
+ schemaVersion: metadata.schemaVersion ?? "1.1.0",
134
+ eventKind: metadata.eventKind ?? defaultEventKind(metadata)
135
+ },
136
+ ...metadata.delegation !== void 0 && { delegation: metadata.delegation },
137
+ ...tool !== void 0 && { tool },
138
+ ...metadata.policy !== void 0 && { policy: metadata.policy },
139
+ ...governance !== void 0 && { governance },
140
+ ...metadata.session !== void 0 && { session: metadata.session },
141
+ ...metadata.decision !== void 0 && { decision: metadata.decision }
142
+ };
143
+ return structuredClone(context);
144
+ }
145
+ /**
146
+ * Context for the *completion* `logger.set()` of a specialized lifecycle
147
+ * wrapper. Carries only the domain state that finished mutating — tool or
148
+ * session status. Outcome is owned by `withAgentAction`, which wraps every
149
+ * variant and stamps it on both span and log. This deliberately omits the
150
+ * request-level `delegation`/`decision` blocks: those were set once at the
151
+ * start, and re-sending them would concatenate their array fields into the
152
+ * wide event (see `buildLoggerContext`).
153
+ */
154
+ function buildLifecycleUpdateContext(metadata) {
155
+ const tool = sanitizeTool(metadata.tool);
156
+ return {
157
+ ...tool !== void 0 && { tool },
158
+ ...metadata.session !== void 0 && { session: structuredClone(metadata.session) }
159
+ };
160
+ }
161
+
162
+ //#endregion
163
+ //#region src/agent/context.ts
164
+ const MISSING_CONTEXT_MESSAGE = "[autotel-genai] No active trace context. Wrap the call in trace()/instrument(), pass options.ctx, or set options.onMissingContext to \"warn\"/\"skip\" to degrade gracefully instead of throwing.";
165
+ /**
166
+ * Resolve an agent context without throwing. Returns `null` when no trace context
167
+ * is available, so callers can degrade gracefully (best-effort instrumentation).
168
+ */
169
+ const INVALID_TRACE_ID = "00000000000000000000000000000000";
170
+ function resolveContextSafe(ctx) {
171
+ if (ctx) return ctx;
172
+ const span = otelTrace.getActiveSpan();
173
+ if (!span) return null;
174
+ const ids = getTraceContext();
175
+ const sc = span.spanContext();
176
+ const traceId = ids?.traceId ?? sc.traceId;
177
+ if (!traceId || traceId === INVALID_TRACE_ID) return null;
178
+ return {
179
+ traceId,
180
+ spanId: ids?.spanId ?? sc.spanId,
181
+ correlationId: ids?.correlationId ?? traceId.slice(0, 16),
182
+ setAttribute: (key, value) => span.setAttribute(key, value),
183
+ setAttributes: (attrs) => span.setAttributes(attrs)
184
+ };
185
+ }
186
+ function resolveContext(ctx) {
187
+ const resolved = resolveContextSafe(ctx);
188
+ if (resolved) return resolved;
189
+ throw new Error(MISSING_CONTEXT_MESSAGE);
190
+ }
191
+ const warnedMissingContext = /* @__PURE__ */ new Set();
192
+ /** Warn (once per action) that an agent action is running without a trace context. */
193
+ function warnMissingContextOnce(action) {
194
+ if (warnedMissingContext.has(action)) return;
195
+ warnedMissingContext.add(action);
196
+ console.warn(`[autotel-genai] No active trace context for "${action}" — running un-audited. Wrap the call in trace()/instrument() or pass options.ctx to capture agent audit telemetry. (set options.onMissingContext: "throw" to fail fast, or "skip" to silence this warning)`);
197
+ }
198
+ function toAttributeValue(value) {
199
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
200
+ if (Array.isArray(value)) {
201
+ if (value.every((entry) => typeof entry === "string")) return value;
202
+ if (value.every((entry) => typeof entry === "number")) return value;
203
+ if (value.every((entry) => typeof entry === "boolean")) return value;
204
+ try {
205
+ return JSON.stringify(value);
206
+ } catch {
207
+ return "<serialization-failed>";
208
+ }
209
+ }
210
+ if (value instanceof Date) return value.toISOString();
211
+ if (typeof value === "bigint") return value.toString(10);
212
+ if (value === null || value === void 0) return;
213
+ try {
214
+ return JSON.stringify(value);
215
+ } catch {
216
+ return "<serialization-failed>";
217
+ }
218
+ }
219
+
220
+ //#endregion
221
+ //#region src/agent/attributes.ts
222
+ function setIfPresent(target, key, value) {
223
+ const attr = toAttributeValue(value);
224
+ if (attr !== void 0) target[key] = attr;
225
+ }
226
+ function appendIdentityAttributes(attrs, agent) {
227
+ setIfPresent(attrs, "agent.id", agent.id);
228
+ setIfPresent(attrs, "agent.version", agent.version);
229
+ setIfPresent(attrs, "agent.framework", agent.framework);
230
+ setIfPresent(attrs, "agent.model", agent.model);
231
+ setIfPresent(attrs, "agent.role", agent.role);
232
+ setIfPresent(attrs, "agent.session.id", agent.sessionId);
233
+ setIfPresent(attrs, "agent.conversation.id", agent.conversationId);
234
+ }
235
+ function appendDelegationAttributes(attrs, delegation) {
236
+ if (!delegation) return;
237
+ setIfPresent(attrs, "delegation.parent_identity", delegation.parentIdentity);
238
+ setIfPresent(attrs, "delegation.scope", delegation.scope);
239
+ setIfPresent(attrs, "delegation.token_id", delegation.tokenId);
240
+ setIfPresent(attrs, "delegation.id", delegation.delegationId);
241
+ setIfPresent(attrs, "delegation.authority_lineage", delegation.authorityLineage);
242
+ setIfPresent(attrs, "delegation.authority_lineage_hash", delegation.authorityLineageHash);
243
+ setIfPresent(attrs, "delegation.depth", delegation.depth);
244
+ setIfPresent(attrs, "delegation.issued_at", delegation.issuedAt);
245
+ setIfPresent(attrs, "delegation.expires_at", delegation.expiresAt);
246
+ }
247
+ function appendToolAttributes(attrs, tool) {
248
+ if (!tool) return;
249
+ setIfPresent(attrs, "tool.name", tool.name);
250
+ setIfPresent(attrs, "tool.call.id", tool.callId);
251
+ setIfPresent(attrs, "tool.input_hash", tool.inputHash);
252
+ setIfPresent(attrs, "tool.output_hash", tool.outputHash);
253
+ setIfPresent(attrs, "tool.status", tool.status);
254
+ setIfPresent(attrs, "tool.execution_ms", tool.executionMs);
255
+ }
256
+ function appendPolicyAttributes(attrs, policy) {
257
+ if (!policy) return;
258
+ setIfPresent(attrs, "policy.decision", policy.decision);
259
+ setIfPresent(attrs, "policy.id", policy.policyId);
260
+ setIfPresent(attrs, "policy.risk_score", policy.riskScore);
261
+ setIfPresent(attrs, "policy.reason", policy.reason);
262
+ }
263
+ function appendGovernanceAttributes(attrs, governance) {
264
+ if (!governance) return;
265
+ setIfPresent(attrs, "governance.review_required", governance.reviewRequired);
266
+ setIfPresent(attrs, "governance.reviewer_id", governance.reviewerId);
267
+ setIfPresent(attrs, "governance.control_id", governance.controlId);
268
+ setIfPresent(attrs, "governance.documentation_url", governance.documentationUrl);
269
+ setIfPresent(attrs, "governance.lifecycle_stage", governance.lifecycleStage);
270
+ setIfPresent(attrs, "governance.framework", governance.framework);
271
+ }
272
+ function appendSessionAttributes(attrs, session) {
273
+ if (!session) return;
274
+ setIfPresent(attrs, "agent.session.status", session.status);
275
+ setIfPresent(attrs, "agent.session.started_at", session.startedAt);
276
+ setIfPresent(attrs, "agent.session.ended_at", session.endedAt);
277
+ setIfPresent(attrs, "agent.session.delegated_by", session.delegatedBy);
278
+ }
279
+ function appendDecisionAttributes(attrs, decision) {
280
+ if (!decision) return;
281
+ setIfPresent(attrs, "decision.summary", decision.summary);
282
+ setIfPresent(attrs, "decision.input_hash", decision.inputHash);
283
+ setIfPresent(attrs, "decision.policy_ids", decision.policyIds);
284
+ setIfPresent(attrs, "decision.justification_codes", decision.justificationCodes);
285
+ setIfPresent(attrs, "decision.evidence_ids", decision.evidenceIds);
286
+ setIfPresent(attrs, "decision.review_required", decision.reviewRequired);
287
+ setIfPresent(attrs, "decision.confidence", decision.confidence);
288
+ }
289
+ function flattenAgentAttributes(metadata) {
290
+ const normalized = normalizeMetadata(metadata);
291
+ const attrs = {
292
+ "autotel.agent": true,
293
+ "agent.action": normalized.action,
294
+ "agent.audit.version": normalized.schemaVersion ?? "1.1.0",
295
+ "agent.event.kind": normalized.eventKind ?? defaultEventKind(normalized)
296
+ };
297
+ setIfPresent(attrs, "agent.resource", normalized.resource);
298
+ setIfPresent(attrs, "agent.outcome", normalized.outcome);
299
+ setIfPresent(attrs, "reasoning.summary", normalized.reasoningSummary);
300
+ appendIdentityAttributes(attrs, normalized.agent);
301
+ appendDelegationAttributes(attrs, normalized.delegation);
302
+ appendToolAttributes(attrs, normalized.tool);
303
+ appendPolicyAttributes(attrs, normalized.policy);
304
+ appendGovernanceAttributes(attrs, normalized.governance);
305
+ appendSessionAttributes(attrs, normalized.session);
306
+ appendDecisionAttributes(attrs, normalized.decision);
307
+ return attrs;
308
+ }
309
+ function setAgentAttributes(metadata, ctx) {
310
+ resolveContext(ctx).setAttributes(flattenAgentAttributes(metadata));
311
+ }
312
+ /**
313
+ * Stamp only the terminal outcome on the active span. Used by lifecycle
314
+ * wrappers on completion so they don't re-flatten (and clobber) richer state a
315
+ * nested step already wrote — e.g. a tool call's `tool.status=complete`.
316
+ */
317
+ function setAgentOutcome(outcome, ctx) {
318
+ resolveContext(ctx).setAttribute("agent.outcome", outcome);
319
+ }
320
+
321
+ //#endregion
322
+ //#region src/agent/runtime.ts
323
+ /**
324
+ * Record canonical OpenTelemetry GenAI semantic attributes for an LLM-backed
325
+ * agent action, reusing the local cost model. Best-effort: anything unknown is
326
+ * simply omitted. `gen_ai.request.model` is always recorded; token counts and
327
+ * the estimated `gen_ai.usage.cost.usd` are recorded when `usage` is available
328
+ * (up front via metadata, or post-call via `options.extractUsage`).
329
+ *
330
+ * Emits canonical v1.42.0 keys only — no `gen_ai.usage.total_tokens` (not a
331
+ * registry attribute) and no legacy `gen.ai.*` names.
332
+ */
333
+ function recordAiTelemetry(ctx, ai, usage) {
334
+ const attrs = {
335
+ ...genAiRequestAttributes({
336
+ operation: ai.operation,
337
+ provider: ai.provider,
338
+ model: ai.model
339
+ }),
340
+ ...genAiResponseAttributes({
341
+ model: ai.responseModel,
342
+ id: ai.responseId,
343
+ finishReasons: ai.finishReasons
344
+ })
345
+ };
346
+ if (usage) {
347
+ const cost = estimateLLMCost(ai.model, usage, ai.pricing ? { pricing: ai.pricing } : void 0);
348
+ Object.assign(attrs, genAiUsageAttributes({
349
+ ...usage,
350
+ costUsd: cost
351
+ }));
352
+ }
353
+ ctx.setAttributes(attrs);
354
+ }
355
+ async function withAgentAction(metadata, fn, options = {}) {
356
+ const normalized = normalizeMetadata(metadata);
357
+ return withAudit(buildAuditMetadata(normalized), async (ctx, logger) => {
358
+ setAgentAttributes(normalized, ctx);
359
+ logger.set(buildLoggerContext(normalized));
360
+ try {
361
+ const result = await fn(ctx, logger);
362
+ const outcome = normalized.outcome ?? "success";
363
+ setAgentOutcome(outcome, ctx);
364
+ logger.set({ agent: { outcome } });
365
+ if (normalized.ai) recordAiTelemetry(ctx, normalized.ai, options.extractUsage?.(result) ?? normalized.ai.usage);
366
+ return result;
367
+ } catch (error) {
368
+ setAgentOutcome("failure", ctx);
369
+ logger.set({ agent: { outcome: "failure" } });
370
+ if (normalized.ai) recordAiTelemetry(ctx, normalized.ai);
371
+ throw error;
372
+ }
373
+ }, options);
374
+ }
375
+ function recordPolicyDecision(metadata, options = {}) {
376
+ const normalized = normalizeMetadata(metadata);
377
+ const traceCtx = resolveContextSafe(options.ctx);
378
+ if (!traceCtx) {
379
+ const mode = options.onMissingContext ?? "warn";
380
+ if (mode === "throw") throw new Error(MISSING_CONTEXT_MESSAGE);
381
+ if (mode === "warn") warnMissingContextOnce(normalized.action);
382
+ return;
383
+ }
384
+ const logger = options.logger ?? getRequestLoggerSafe() ?? createNoopRequestLogger();
385
+ if (options.forceKeep !== false) forceKeepAuditEvent(traceCtx);
386
+ setAgentAttributes(normalized, traceCtx);
387
+ logger.set(buildLoggerContext(normalized));
388
+ if (options.emitNow) logger.emitNow();
389
+ }
390
+ function recordDecisionBasis(metadata, options = {}) {
391
+ if (!metadata.decision && !metadata.reasoningSummary) throw new Error("[autotel-genai] recordDecisionBasis requires metadata.decision or metadata.reasoningSummary.");
392
+ recordPolicyDecision(metadata, options);
393
+ }
394
+ /**
395
+ * Define a reusable, instrumented agent action — the `trace()`-style factory
396
+ * companion to `withAgentAction`. Declare it once at module scope and call the
397
+ * returned function many times; each call opens its own audit scope.
398
+ *
399
+ * `metadata` may be a static object or a function of the call arguments, so
400
+ * call-specific fields can be derived per invocation.
401
+ *
402
+ * @example
403
+ * ```ts
404
+ * const planTrip = defineAgentAction(
405
+ * (req: TripRequest) => ({
406
+ * action: 'agent.trip.plan',
407
+ * agent: { id: 'planner' },
408
+ * delegation: { parentIdentity: req.userId, scope: ['trip:plan'] },
409
+ * }),
410
+ * (ctx) => async (req: TripRequest) => planItinerary(req),
411
+ * );
412
+ *
413
+ * await planTrip({ userId: 'usr_1', destination: 'Lisbon' });
414
+ * ```
415
+ */
416
+ function defineAgentAction(metadata, factory, options = {}) {
417
+ return (...args) => {
418
+ return withAgentAction(typeof metadata === "function" ? metadata(...args) : metadata, (ctx, logger) => factory(ctx, logger)(...args), options);
419
+ };
420
+ }
421
+ /**
422
+ * Define a reusable, instrumented agent tool call — the `trace()`-style factory
423
+ * companion to `withAgentToolCall`. Declare it once and call it per invocation;
424
+ * tool inputs/results are hashed (never attached raw) on every call.
425
+ *
426
+ * Pass `metadata` as a function of the arguments when `tool.input` (or any other
427
+ * field) depends on the call, so each invocation hashes its own input.
428
+ *
429
+ * @example
430
+ * ```ts
431
+ * const handleRefund = defineAgentToolCall(
432
+ * (req: RefundRequest) => ({
433
+ * action: 'agent.refund.tool_call',
434
+ * resource: 'stripe_refund_v3',
435
+ * agent: { id: 'refunds-specialist' },
436
+ * tool: { name: 'stripe_refund_v3', input: { refundId: req.refundId } },
437
+ * }),
438
+ * (ctx) => async (req: RefundRequest) => stripe.refunds.create(req),
439
+ * );
440
+ *
441
+ * await handleRefund({ refundId: 're_123' });
442
+ * ```
443
+ */
444
+ function defineAgentToolCall(metadata, factory, options = {}) {
445
+ return (...args) => {
446
+ return withAgentToolCall(typeof metadata === "function" ? metadata(...args) : metadata, (ctx, logger) => factory(ctx, logger)(...args), options);
447
+ };
448
+ }
449
+ async function withAgentToolCall(metadata, fn, options = {}) {
450
+ const start = Date.now();
451
+ const normalized = normalizeMetadata({
452
+ ...metadata,
453
+ tool: {
454
+ ...metadata.tool,
455
+ status: metadata.tool?.status ?? "planned"
456
+ }
457
+ });
458
+ return withAgentAction(normalized, async (ctx, logger) => {
459
+ try {
460
+ const result = await fn(ctx, logger);
461
+ const executionMs = Date.now() - start;
462
+ const completed = {
463
+ ...normalized,
464
+ outcome: normalized.outcome ?? "success",
465
+ tool: {
466
+ ...metadata.tool,
467
+ inputHash: normalized.tool?.inputHash,
468
+ outputHash: normalized.tool?.outputHash ?? (options.hashResult === false ? void 0 : hashPayload(result)),
469
+ status: "complete",
470
+ executionMs
471
+ }
472
+ };
473
+ setAgentAttributes(completed, ctx);
474
+ logger.set(buildLifecycleUpdateContext(normalizeMetadata(completed)));
475
+ return result;
476
+ } catch (error) {
477
+ const failed = {
478
+ ...normalized,
479
+ outcome: "failure",
480
+ tool: {
481
+ ...metadata.tool,
482
+ inputHash: normalized.tool?.inputHash,
483
+ status: "error",
484
+ executionMs: Date.now() - start
485
+ }
486
+ };
487
+ setAgentAttributes(failed, ctx);
488
+ logger.set(buildLifecycleUpdateContext(normalizeMetadata(failed)));
489
+ throw error;
490
+ }
491
+ }, options);
492
+ }
493
+
494
+ //#endregion
495
+ //#region src/agent/delegation.ts
496
+ function buildAuthorityLineage(parentIdentity, agentId, existingLineage) {
497
+ const lineage = existingLineage ? [...existingLineage] : [parentIdentity];
498
+ if (lineage.at(-1) !== agentId) lineage.push(agentId);
499
+ return lineage;
500
+ }
501
+ function delegateToAgent(input) {
502
+ const authorityLineage = buildAuthorityLineage(input.parentIdentity, input.targetAgentId, input.authorityLineage);
503
+ return {
504
+ parentIdentity: input.parentIdentity,
505
+ ...input.scope !== void 0 && { scope: input.scope },
506
+ ...input.tokenId !== void 0 && { tokenId: input.tokenId },
507
+ ...input.delegationId !== void 0 && { delegationId: input.delegationId },
508
+ authorityLineage,
509
+ authorityLineageHash: hashPayload(authorityLineage),
510
+ depth: Math.max(authorityLineage.length - 1, 0),
511
+ issuedAt: input.issuedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
512
+ ...input.expiresAt !== void 0 && { expiresAt: input.expiresAt }
513
+ };
514
+ }
515
+ function recordAgentHandoff(metadata, options = {}) {
516
+ const authorityLineage = metadata.authorityLineage ?? [metadata.parentIdentity, metadata.fromAgent.id];
517
+ const delegation = delegateToAgent({
518
+ parentIdentity: metadata.parentIdentity,
519
+ targetAgentId: metadata.toAgent.id,
520
+ scope: metadata.scope,
521
+ tokenId: metadata.tokenId,
522
+ delegationId: metadata.delegationId,
523
+ authorityLineage
524
+ });
525
+ recordPolicyDecision({
526
+ action: metadata.action,
527
+ resource: metadata.resource,
528
+ eventKind: "handoff",
529
+ agent: metadata.toAgent,
530
+ delegation,
531
+ governance: metadata.governance,
532
+ reasoningSummary: `Control passed from ${metadata.fromAgent.id} to ${metadata.toAgent.id}.`
533
+ }, options);
534
+ }
535
+
536
+ //#endregion
537
+ //#region src/agent/session.ts
538
+ function toIsoString$2(value) {
539
+ if (!value) return (/* @__PURE__ */ new Date()).toISOString();
540
+ return value instanceof Date ? value.toISOString() : value;
541
+ }
542
+ async function withAgentSession(metadata, fn, options = {}) {
543
+ const startedAt = toIsoString$2(metadata.session?.startedAt);
544
+ return withAgentAction({
545
+ ...metadata,
546
+ category: metadata.category ?? "agent_session",
547
+ session: {
548
+ ...metadata.session,
549
+ status: metadata.session?.status ?? "active",
550
+ startedAt
551
+ }
552
+ }, async (ctx, logger) => {
553
+ try {
554
+ const result = await fn(ctx, logger);
555
+ const completed = {
556
+ ...metadata,
557
+ outcome: metadata.outcome ?? "success",
558
+ session: {
559
+ ...metadata.session,
560
+ status: "completed",
561
+ startedAt,
562
+ endedAt: (/* @__PURE__ */ new Date()).toISOString()
563
+ }
564
+ };
565
+ setAgentAttributes(completed, ctx);
566
+ logger.set(buildLifecycleUpdateContext(completed));
567
+ return result;
568
+ } catch (error) {
569
+ const failed = {
570
+ ...metadata,
571
+ outcome: "failure",
572
+ session: {
573
+ ...metadata.session,
574
+ status: "failed",
575
+ startedAt,
576
+ endedAt: (/* @__PURE__ */ new Date()).toISOString()
577
+ }
578
+ };
579
+ setAgentAttributes(failed, ctx);
580
+ logger.set(buildLifecycleUpdateContext(failed));
581
+ throw error;
582
+ }
583
+ }, options);
584
+ }
585
+
586
+ //#endregion
587
+ //#region src/agent/identity-registry.ts
588
+ function toIsoString$1(value) {
589
+ if (!value) return void 0;
590
+ return value instanceof Date ? value.toISOString() : value;
591
+ }
592
+ function normalizeScopes$1(scope) {
593
+ if (!scope) return [];
594
+ return Array.isArray(scope) ? [...scope] : [scope];
595
+ }
596
+ function isExpired(record, at) {
597
+ return record.expiresAt !== void 0 && record.expiresAt < at;
598
+ }
599
+ function createAgentIdentityRegistry(initial = []) {
600
+ const records = /* @__PURE__ */ new Map();
601
+ const provisionIdentity = (input) => {
602
+ const now = toIsoString$1(input.provisionedAt) ?? (/* @__PURE__ */ new Date()).toISOString();
603
+ const record = {
604
+ agent: input.agent,
605
+ scopes: input.scopes ?? [],
606
+ status: "active",
607
+ tokenId: input.tokenId,
608
+ tokenHash: input.tokenId === void 0 ? void 0 : hashPayload(input.tokenId),
609
+ delegatedBy: input.delegatedBy,
610
+ provisionedAt: now,
611
+ expiresAt: toIsoString$1(input.expiresAt),
612
+ metadata: input.metadata
613
+ };
614
+ records.set(input.agent.id, record);
615
+ return record;
616
+ };
617
+ for (const item of initial) provisionIdentity(item);
618
+ return {
619
+ provisionIdentity,
620
+ rotateIdentity(agentId, input = {}) {
621
+ const existing = records.get(agentId);
622
+ if (!existing) throw new Error(`[autotel-genai] Cannot rotate unknown agent identity "${agentId}".`);
623
+ const rotatedAt = toIsoString$1(input.rotatedAt) ?? (/* @__PURE__ */ new Date()).toISOString();
624
+ const record = {
625
+ ...existing,
626
+ scopes: input.scopes ?? existing.scopes,
627
+ status: "rotated",
628
+ tokenId: input.tokenId ?? existing.tokenId,
629
+ tokenHash: input.tokenId === void 0 ? existing.tokenHash : hashPayload(input.tokenId),
630
+ delegatedBy: input.delegatedBy ?? existing.delegatedBy,
631
+ rotatedAt,
632
+ expiresAt: toIsoString$1(input.expiresAt) ?? existing.expiresAt,
633
+ metadata: input.metadata ?? existing.metadata
634
+ };
635
+ records.set(agentId, record);
636
+ return record;
637
+ },
638
+ revokeIdentity(agentId, input) {
639
+ const existing = records.get(agentId);
640
+ if (!existing) throw new Error(`[autotel-genai] Cannot revoke unknown agent identity "${agentId}".`);
641
+ const revokedAt = toIsoString$1(input.revokedAt) ?? (/* @__PURE__ */ new Date()).toISOString();
642
+ const record = {
643
+ ...existing,
644
+ status: "revoked",
645
+ revokedAt,
646
+ revocationReason: input.reason
647
+ };
648
+ records.set(agentId, record);
649
+ return record;
650
+ },
651
+ getIdentity(agentId) {
652
+ return records.get(agentId);
653
+ },
654
+ getIdentityStatus(agentId, at = (/* @__PURE__ */ new Date()).toISOString()) {
655
+ const record = records.get(agentId);
656
+ if (!record) return;
657
+ return isExpired(record, at) ? "expired" : record.status;
658
+ },
659
+ assertUsable(agentId, at = (/* @__PURE__ */ new Date()).toISOString()) {
660
+ const record = records.get(agentId);
661
+ if (!record) throw new Error(`[autotel-genai] Unknown agent identity "${agentId}". Provision it before use.`);
662
+ const status = isExpired(record, at) ? "expired" : record.status;
663
+ if (status !== "active" && status !== "rotated") throw new Error(`[autotel-genai] Agent identity "${agentId}" is ${status} and cannot execute delegated work.`);
664
+ return record;
665
+ },
666
+ assertScopes(agentId, requiredScopes) {
667
+ const record = this.assertUsable(agentId);
668
+ const missing = requiredScopes.filter((scope) => !record.scopes.includes(scope));
669
+ if (missing.length > 0) throw new Error(`[autotel-genai] Agent identity "${agentId}" is missing delegated scopes: ${missing.join(", ")}.`);
670
+ return record;
671
+ },
672
+ issueDelegation(agentId, input) {
673
+ const record = this.assertUsable(agentId);
674
+ const scope = normalizeScopes$1(input.scope);
675
+ if (scope.length > 0) this.assertScopes(agentId, scope);
676
+ return delegateToAgent({
677
+ parentIdentity: input.parentIdentity,
678
+ targetAgentId: record.agent.id,
679
+ scope: input.scope ?? record.scopes,
680
+ tokenId: input.tokenId ?? record.tokenId,
681
+ delegationId: input.delegationId,
682
+ authorityLineage: input.authorityLineage,
683
+ issuedAt: input.issuedAt,
684
+ expiresAt: input.expiresAt ?? record.expiresAt
685
+ });
686
+ },
687
+ list() {
688
+ return [...records.values()];
689
+ }
690
+ };
691
+ }
692
+
693
+ //#endregion
694
+ //#region src/agent/privacy.ts
695
+ const PRIVACY_PROFILES = {
696
+ strict: {
697
+ name: "strict",
698
+ hashKeys: [
699
+ /email/i,
700
+ /phone/i,
701
+ /user_?id/i,
702
+ /account/i,
703
+ /customer/i,
704
+ /card/i,
705
+ /iban/i,
706
+ /tax/i
707
+ ],
708
+ dropKeys: [
709
+ /secret/i,
710
+ /token/i,
711
+ /api[_-]?key/i,
712
+ /authorization/i,
713
+ /cookie/i,
714
+ /password/i,
715
+ /bearer/i
716
+ ],
717
+ maskKeys: [
718
+ /name/i,
719
+ /address/i,
720
+ /prompt/i,
721
+ /message/i,
722
+ /content/i
723
+ ],
724
+ maxStringLength: 256
725
+ },
726
+ pci: {
727
+ name: "pci",
728
+ hashKeys: [
729
+ /card/i,
730
+ /pan/i,
731
+ /account/i,
732
+ /customer/i,
733
+ /email/i
734
+ ],
735
+ dropKeys: [
736
+ /cvv/i,
737
+ /cvc/i,
738
+ /secret/i,
739
+ /token/i,
740
+ /api[_-]?key/i
741
+ ],
742
+ maskKeys: [/name/i, /address/i],
743
+ maxStringLength: 128
744
+ },
745
+ healthcare: {
746
+ name: "healthcare",
747
+ hashKeys: [
748
+ /patient/i,
749
+ /mrn/i,
750
+ /member/i,
751
+ /email/i,
752
+ /phone/i
753
+ ],
754
+ dropKeys: [
755
+ /diagnosis/i,
756
+ /notes/i,
757
+ /secret/i,
758
+ /token/i,
759
+ /password/i
760
+ ],
761
+ maskKeys: [
762
+ /name/i,
763
+ /address/i,
764
+ /symptom/i
765
+ ],
766
+ maxStringLength: 128
767
+ }
768
+ };
769
+ function maskValue(value) {
770
+ if (typeof value !== "string") return "<masked>";
771
+ if (value.length <= 6) return "***";
772
+ return `${value.slice(0, 3)}***${value.slice(-3)}`;
773
+ }
774
+ function matches(patterns, key) {
775
+ return patterns?.some((pattern) => pattern.test(key)) ?? false;
776
+ }
777
+ function truncateString(value, maxLength) {
778
+ if (maxLength === void 0 || value.length <= maxLength) return value;
779
+ return `${value.slice(0, maxLength)}…`;
780
+ }
781
+ function sanitizeNode(value, profile, keyPath) {
782
+ if (value instanceof Date) return value.toISOString();
783
+ const lowered = keyPath.toLowerCase();
784
+ if (matches(profile.dropKeys, lowered)) return "<redacted>";
785
+ if (matches(profile.hashKeys, lowered)) return hashPayload(value);
786
+ if (matches(profile.maskKeys, lowered)) return maskValue(value);
787
+ if (typeof value === "string") return truncateString(value, profile.maxStringLength);
788
+ if (Array.isArray(value)) return value.map((entry, index) => sanitizeNode(entry, profile, `${keyPath}[${index}]`));
789
+ if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeNode(entry, profile, keyPath ? `${keyPath}.${key}` : key)]));
790
+ if (typeof value === "bigint") return value.toString(10);
791
+ return value;
792
+ }
793
+ function resolvePrivacyProfile(profile = "strict") {
794
+ return typeof profile === "string" ? PRIVACY_PROFILES[profile] : profile;
795
+ }
796
+ function sanitizeAuditPayload(value, profile = "strict") {
797
+ return sanitizeNode(value, resolvePrivacyProfile(profile), "");
798
+ }
799
+
800
+ //#endregion
801
+ //#region src/agent/non-repudiation.ts
802
+ function toIsoString(value) {
803
+ if (!value) return (/* @__PURE__ */ new Date()).toISOString();
804
+ return value instanceof Date ? value.toISOString() : value;
805
+ }
806
+ async function createSignedEventEnvelope(metadata, options = {}) {
807
+ const normalized = normalizeMetadata(metadata);
808
+ const envelopeBase = {
809
+ schemaVersion: normalized.schemaVersion ?? "1.1.0",
810
+ emittedAt: toIsoString(options.emittedAt),
811
+ ...options.previousEventHash !== void 0 && { previousEventHash: options.previousEventHash },
812
+ metadata: normalized,
813
+ ...options.evidence !== void 0 && { evidence: sanitizeAuditPayload(options.evidence, options.privacyProfile ?? "strict") }
814
+ };
815
+ const eventHash = hashPayload(envelopeBase);
816
+ const signature = options.signer ? await options.signer(canonicalizeForHash(envelopeBase)) : void 0;
817
+ return {
818
+ ...envelopeBase,
819
+ eventHash,
820
+ ...signature !== void 0 && { signature }
821
+ };
822
+ }
823
+ function verifyEventEnvelopeHash(envelope) {
824
+ const expected = hashPayload({
825
+ schemaVersion: envelope.schemaVersion,
826
+ emittedAt: envelope.emittedAt,
827
+ ...envelope.previousEventHash !== void 0 && { previousEventHash: envelope.previousEventHash },
828
+ metadata: envelope.metadata,
829
+ ...envelope.evidence !== void 0 && { evidence: envelope.evidence }
830
+ });
831
+ return envelope.eventHash === expected;
832
+ }
833
+
834
+ //#endregion
835
+ //#region src/agent/scoped-tool.ts
836
+ function normalizeScopes(scope) {
837
+ if (!scope) return [];
838
+ return Array.isArray(scope) ? scope : [scope];
839
+ }
840
+ function missingScopes(delegated, required) {
841
+ return required.filter((scope) => !delegated.includes(scope));
842
+ }
843
+ /**
844
+ * Decide whether a scoped tool call must be denied.
845
+ *
846
+ * When the identity is registry-backed, the registry is authoritative: a
847
+ * delegation may only *narrow* the stored grant, never widen it. Scopes a
848
+ * caller claims that the registry never granted are a forged escalation and are
849
+ * denied before any missing-scope check — otherwise passing an explicit
850
+ * `delegation.scope` could grant access the registry record does not allow.
851
+ */
852
+ function resolveScopeDenial(claimedScopes, requiredScopes, registryScopes) {
853
+ const unauthorized = registryScopes ? claimedScopes.filter((scope) => !registryScopes.includes(scope)) : [];
854
+ if (unauthorized.length > 0) return {
855
+ scopes: unauthorized,
856
+ reason: `unauthorized_scope:${unauthorized.join(",")}`,
857
+ why: `Delegation claims scopes the identity was never granted: ${unauthorized.join(", ")}`
858
+ };
859
+ const missing = missingScopes(claimedScopes, requiredScopes);
860
+ if (missing.length > 0) return {
861
+ scopes: missing,
862
+ reason: `missing_scope:${missing.join(",")}`,
863
+ why: `Missing delegated scopes: ${missing.join(", ")}`
864
+ };
865
+ }
866
+ function resolveDelegation(definition) {
867
+ const registry = definition.identityRegistry;
868
+ if (registry) registry.assertUsable(definition.agent.id);
869
+ return definition.delegation;
870
+ }
871
+ function buildGovernance(governance, reviewRequired) {
872
+ if (!governance && reviewRequired === void 0) return governance;
873
+ return {
874
+ ...governance,
875
+ ...reviewRequired !== void 0 && { reviewRequired }
876
+ };
877
+ }
878
+ function buildDecision(input, decision, privacyProfile) {
879
+ if (!decision) return void 0;
880
+ const sanitizedInput = sanitizeAuditPayload(input, privacyProfile ?? "strict");
881
+ return {
882
+ ...decision,
883
+ inputHash: decision.inputHash ?? hashPayload(sanitizedInput)
884
+ };
885
+ }
886
+ async function withScopedTool(definition, input, fn, options = {}) {
887
+ const requiredScopes = definition.requiredScopes ?? [];
888
+ const delegation = resolveDelegation(definition);
889
+ const registryScopes = definition.identityRegistry?.getIdentity(definition.agent.id)?.scopes;
890
+ const denial = resolveScopeDenial(normalizeScopes(delegation?.scope ?? registryScopes), requiredScopes, registryScopes);
891
+ const policy = definition.policyId || definition.riskScore !== void 0 || denial ? {
892
+ decision: denial ? "deny" : "permit",
893
+ ...definition.policyId !== void 0 && { policyId: definition.policyId },
894
+ ...definition.riskScore !== void 0 && { riskScore: definition.riskScore },
895
+ ...denial && { reason: denial.reason }
896
+ } : void 0;
897
+ const governance = buildGovernance(definition.governance, definition.reviewRequired);
898
+ if (policy && policy.decision === "deny" && denial) {
899
+ recordPolicyDecision({
900
+ action: definition.action,
901
+ resource: definition.resource ?? definition.tool.name,
902
+ category: definition.category,
903
+ agent: definition.agent,
904
+ delegation,
905
+ policy,
906
+ governance,
907
+ decision: buildDecision(input, definition.decision, definition.privacyProfile)
908
+ }, options);
909
+ throw createStructuredError({
910
+ status: 403,
911
+ code: "AGENT_SCOPE_DENIED",
912
+ message: `Agent "${definition.agent.id}" cannot invoke ${definition.tool.name}.`,
913
+ why: denial.why,
914
+ fix: "Grant the missing scopes or route the task to an agent with the required delegation."
915
+ });
916
+ }
917
+ if (policy) recordPolicyDecision({
918
+ action: `${definition.action}.policy`,
919
+ resource: definition.resource ?? definition.tool.name,
920
+ category: definition.category,
921
+ agent: definition.agent,
922
+ delegation,
923
+ policy,
924
+ governance
925
+ }, options);
926
+ if (definition.decision) recordDecisionBasis({
927
+ action: `${definition.action}.decision`,
928
+ resource: definition.resource ?? definition.tool.name,
929
+ category: definition.category,
930
+ agent: definition.agent,
931
+ delegation,
932
+ governance,
933
+ decision: buildDecision(input, definition.decision, definition.privacyProfile)
934
+ }, options);
935
+ return withAgentToolCall({
936
+ action: definition.action,
937
+ resource: definition.resource ?? definition.tool.name,
938
+ category: definition.category,
939
+ agent: definition.agent,
940
+ delegation,
941
+ governance,
942
+ tool: {
943
+ ...definition.tool,
944
+ input
945
+ }
946
+ }, fn, options);
947
+ }
948
+
949
+ //#endregion
950
+ export { setAgentAttributes as _, sanitizeAuditPayload as a, hashPayload as b, delegateToAgent as c, defineAgentToolCall as d, recordDecisionBasis as f, flattenAgentAttributes as g, withAgentToolCall as h, resolvePrivacyProfile as i, recordAgentHandoff as l, withAgentAction as m, createSignedEventEnvelope as n, createAgentIdentityRegistry as o, recordPolicyDecision as p, verifyEventEnvelopeHash as r, withAgentSession as s, withScopedTool as t, defineAgentAction as u, createAgentAuditMetadata as v, AGENT_AUDIT_SCHEMA_VERSION as x, canonicalizeForHash as y };
951
+ //# sourceMappingURL=agent-CqXauTpC.js.map