agent-inspect 6.31.21 → 6.31.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-N5JN26MW.mjs → chunk-P27XTK5U.mjs} +347 -36
- package/packages/cli/dist/chunk-P27XTK5U.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +434 -63
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +81 -33
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-VMGRSTG7.mjs → src-EWZYLDST.mjs} +3 -3
- package/packages/cli/dist/{src-VMGRSTG7.mjs.map → src-EWZYLDST.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +280 -10
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +6 -5
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +185 -27
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +2 -1
- package/packages/core/dist/{chunk-JE3TUFAQ.mjs → chunk-77PUPLPG.mjs} +14 -8
- package/packages/core/dist/chunk-77PUPLPG.mjs.map +1 -0
- package/packages/core/dist/chunk-AN5MOADW.mjs +204 -0
- package/packages/core/dist/chunk-AN5MOADW.mjs.map +1 -0
- package/packages/core/dist/{chunk-4CDX5GDS.mjs → chunk-IMCM42W6.mjs} +110 -99
- package/packages/core/dist/chunk-IMCM42W6.mjs.map +1 -0
- package/packages/core/dist/{chunk-YU6XT5A2.mjs → chunk-J2ST4VCX.mjs} +45 -3
- package/packages/core/dist/chunk-J2ST4VCX.mjs.map +1 -0
- package/packages/core/dist/{chunk-EIP5CNEL.mjs → chunk-JJSL346L.mjs} +58 -3
- package/packages/core/dist/chunk-JJSL346L.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +91 -29
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +78 -29
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/logs.cjs +206 -1
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.mjs +3 -2
- package/packages/core/dist/logs.mjs.map +1 -1
- package/packages/core/dist/persisted.cjs +226 -8
- package/packages/core/dist/persisted.cjs.map +1 -1
- package/packages/core/dist/persisted.mjs +9 -5
- package/packages/core/dist/persisted.mjs.map +1 -1
- package/packages/core/dist/readers.cjs +276 -6
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +4 -3
- package/packages/cli/dist/chunk-N5JN26MW.mjs.map +0 -1
- package/packages/core/dist/chunk-4CDX5GDS.mjs.map +0 -1
- package/packages/core/dist/chunk-EIP5CNEL.mjs.map +0 -1
- package/packages/core/dist/chunk-JE3TUFAQ.mjs.map +0 -1
- package/packages/core/dist/chunk-YU6XT5A2.mjs.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export { buildTraceFacts, createBaselineRegressionRule, createDecisionRule, createGuardrailRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRetrievalRule, createRunDepthRule, createRunDurationRule, createRunEventCountRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStepOrderingRule, createStructureCycleRule, createStructureIncompleteRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolFailureRule, createToolOrderingRule, createToolUsageRule, defineTraceContract, deriveFailureFacts, deriveRelationshipFacts, evaluateToolArgumentValue, evaluateTraceContract, evaluateTraceContractRead, explainTraceContract, extractToolArgumentPayload, lintTraceContract, resolveJsonPointer, resolveTraceContractScope, runTraceChecks, summarizeSemanticParity, workflowMetadataForRun } from './chunk-
|
|
1
|
+
export { buildTraceFacts, createBaselineRegressionRule, createDecisionRule, createGuardrailRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRetrievalRule, createRunDepthRule, createRunDurationRule, createRunEventCountRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStepOrderingRule, createStructureCycleRule, createStructureIncompleteRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolFailureRule, createToolOrderingRule, createToolUsageRule, defineTraceContract, deriveFailureFacts, deriveRelationshipFacts, evaluateToolArgumentValue, evaluateTraceContract, evaluateTraceContractRead, explainTraceContract, extractToolArgumentPayload, lintTraceContract, resolveJsonPointer, resolveTraceContractScope, runTraceChecks, summarizeSemanticParity, workflowMetadataForRun } from './chunk-IMCM42W6.mjs';
|
|
2
2
|
import './chunk-77UZIMMD.mjs';
|
|
3
3
|
import './chunk-EOXUEQB6.mjs';
|
|
4
4
|
import './chunk-VLVCLAPB.mjs';
|
|
5
5
|
export { projectLogicalEvents, resolveCanonicalToolName } from './chunk-AHUZNHFI.mjs';
|
|
6
6
|
export { PROGRAMMATIC_DIAGNOSTIC_SPECS, formatProgrammaticDiagnostic } from './chunk-S6LQBLX5.mjs';
|
|
7
|
+
import './chunk-AN5MOADW.mjs';
|
|
7
8
|
import './chunk-7DHSWDKB.mjs';
|
|
8
9
|
export { ATTRIBUTION_CONFIDENCES, ATTRIBUTION_CONFIDENCE_RANK, isAttributionConfidence } from './chunk-EE5Z2GQ3.mjs';
|
|
9
10
|
import './chunk-7TGZLWEE.mjs';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { projectLogicalEvents } from './chunk-AHUZNHFI.mjs';
|
|
2
2
|
import { extractCorrelationMetadata } from './chunk-S4YWKV4G.mjs';
|
|
3
|
-
import { TreeBuilder } from './chunk-
|
|
3
|
+
import { TreeBuilder } from './chunk-J2ST4VCX.mjs';
|
|
4
|
+
import { deliveryEventBaseFromIndexedId, DELIVERY_EVENT_BASE_ATTR } from './chunk-AN5MOADW.mjs';
|
|
4
5
|
import { isPersistedInspectEvent } from './chunk-EE5Z2GQ3.mjs';
|
|
5
6
|
|
|
6
7
|
// packages/core/src/persisted/token-usage.ts
|
|
@@ -118,6 +119,11 @@ function compactAttributes(entries) {
|
|
|
118
119
|
}
|
|
119
120
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
120
121
|
}
|
|
122
|
+
function stampDeliveryEventBase(eventId, attributes) {
|
|
123
|
+
const base = deliveryEventBaseFromIndexedId(eventId);
|
|
124
|
+
if (!base) return attributes;
|
|
125
|
+
return { ...attributes ?? {}, [DELIVERY_EVENT_BASE_ATTR]: base };
|
|
126
|
+
}
|
|
121
127
|
function traceEventToPersistedInspectEvent(event, options) {
|
|
122
128
|
const eventIndex = options?.eventIndex ?? 0;
|
|
123
129
|
const eventId = createPersistedEventId(event, eventIndex);
|
|
@@ -147,7 +153,7 @@ function traceEventToPersistedInspectEvent(event, options) {
|
|
|
147
153
|
startedAt: tsStart.iso,
|
|
148
154
|
confidence: "explicit",
|
|
149
155
|
source,
|
|
150
|
-
attributes
|
|
156
|
+
attributes: stampDeliveryEventBase(eventId, attributes)
|
|
151
157
|
};
|
|
152
158
|
}
|
|
153
159
|
case "run_completed": {
|
|
@@ -170,7 +176,7 @@ function traceEventToPersistedInspectEvent(event, options) {
|
|
|
170
176
|
durationMs: event.durationMs,
|
|
171
177
|
confidence: "explicit",
|
|
172
178
|
source,
|
|
173
|
-
attributes,
|
|
179
|
+
attributes: stampDeliveryEventBase(eventId, attributes),
|
|
174
180
|
error
|
|
175
181
|
};
|
|
176
182
|
}
|
|
@@ -195,7 +201,7 @@ function traceEventToPersistedInspectEvent(event, options) {
|
|
|
195
201
|
startedAt: tsStart.iso,
|
|
196
202
|
confidence: "explicit",
|
|
197
203
|
source,
|
|
198
|
-
attributes
|
|
204
|
+
attributes: stampDeliveryEventBase(eventId, attributes)
|
|
199
205
|
};
|
|
200
206
|
if (event.parentId !== void 0) {
|
|
201
207
|
out.parentId = event.parentId;
|
|
@@ -226,7 +232,7 @@ function traceEventToPersistedInspectEvent(event, options) {
|
|
|
226
232
|
durationMs: event.durationMs,
|
|
227
233
|
confidence: "explicit",
|
|
228
234
|
source,
|
|
229
|
-
attributes,
|
|
235
|
+
attributes: stampDeliveryEventBase(eventId, attributes),
|
|
230
236
|
error
|
|
231
237
|
};
|
|
232
238
|
}
|
|
@@ -253,7 +259,7 @@ function traceEventToPersistedInspectEvent(event, options) {
|
|
|
253
259
|
timestamp: tsMain.iso,
|
|
254
260
|
confidence: "explicit",
|
|
255
261
|
source,
|
|
256
|
-
attributes
|
|
262
|
+
attributes: stampDeliveryEventBase(eventId, attributes)
|
|
257
263
|
};
|
|
258
264
|
if (event.parentId !== void 0) {
|
|
259
265
|
out.parentId = event.parentId;
|
|
@@ -448,5 +454,5 @@ function traceEventsToPersistedRunTrees(events, options) {
|
|
|
448
454
|
}
|
|
449
455
|
|
|
450
456
|
export { normalizeTokenUsage, persistedInspectEventToInspectEvent, persistedInspectEventsToInspectEvents, persistedInspectEventsToRunTrees, traceEventToPersistedInspectEvent, traceEventsToPersistedInspectEvents, traceEventsToPersistedRunTrees };
|
|
451
|
-
//# sourceMappingURL=chunk-
|
|
452
|
-
//# sourceMappingURL=chunk-
|
|
457
|
+
//# sourceMappingURL=chunk-77PUPLPG.mjs.map
|
|
458
|
+
//# sourceMappingURL=chunk-77PUPLPG.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/persisted/token-usage.ts","../src/persisted/from-trace-event.ts","../src/persisted/to-inspect-event.ts","../src/persisted/tree-bridge.ts"],"names":["compactAttributes"],"mappings":"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","file":"chunk-77PUPLPG.mjs","sourcesContent":["import type { PersistedTokenUsage } from \"../types/persisted-inspect-event.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonNegativeFinite(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0\n ? value\n : undefined;\n}\n\n/**\n * Keeps the approved token vocabulary and derives total only when it is absent.\n * Cached / cache-write / reasoning tokens are informational and are never added to total.\n */\nexport function normalizeTokenUsage(\n value: unknown,\n): PersistedTokenUsage | undefined {\n if (!isRecord(value)) return undefined;\n\n const input = nonNegativeFinite(value.input);\n const output = nonNegativeFinite(value.output);\n const suppliedTotal = nonNegativeFinite(value.total);\n const cached = nonNegativeFinite(value.cached);\n const cacheWrite = nonNegativeFinite(value.cacheWrite);\n const reasoning = nonNegativeFinite(value.reasoning);\n const derivedTotal =\n input !== undefined && output !== undefined && Number.isFinite(input + output)\n ? input + output\n : undefined;\n const total = suppliedTotal ?? derivedTotal;\n\n if (\n input === undefined &&\n output === undefined &&\n total === undefined &&\n cached === undefined &&\n cacheWrite === undefined &&\n reasoning === undefined\n ) {\n return undefined;\n }\n\n return {\n ...(input !== undefined ? { input } : {}),\n ...(output !== undefined ? { output } : {}),\n ...(total !== undefined ? { total } : {}),\n ...(cached !== undefined ? { cached } : {}),\n ...(cacheWrite !== undefined ? { cacheWrite } : {}),\n ...(reasoning !== undefined ? { reasoning } : {}),\n };\n}\n","import { extractCorrelationMetadata } from \"../correlation-metadata.js\";\nimport type { InspectKind } from \"../types/inspect-event.js\";\nimport type {\n ErrorInfo,\n StepMetadata,\n StepType,\n TraceEvent,\n} from \"../types.js\";\nimport type {\n PersistedEventSource,\n PersistedEventStatus,\n PersistedInspectError,\n PersistedInspectEvent,\n PersistedTokenUsage,\n} from \"../types/persisted-inspect-event.js\";\nimport {\n DELIVERY_EVENT_BASE_ATTR,\n deliveryEventBaseFromIndexedId,\n} from \"./delivery-identity.js\";\nimport { normalizeTokenUsage } from \"./token-usage.js\";\n\nexport interface TraceEventToPersistedOptions {\n /**\n * Stable index within the source event list.\n * Used only to make synthetic eventId deterministic when v0.1 has no eventId.\n */\n eventIndex?: number;\n\n /**\n * Optional source name override.\n * Default: \"trace-event\"\n */\n sourceName?: string;\n\n /**\n * Optional source version override.\n * Default: \"0.1\"\n */\n sourceVersion?: string;\n}\n\nfunction sanitizeIdPart(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n}\n\nfunction nodeIdForEvent(event: TraceEvent): string {\n switch (event.event) {\n case \"run_started\":\n case \"run_completed\":\n return event.runId;\n case \"step_started\":\n case \"step_completed\":\n return event.stepId;\n case \"outcome_observed\":\n return event.outcomeId;\n default:\n return \"unknown\";\n }\n}\n\nfunction createPersistedEventId(event: TraceEvent, eventIndex: number): string {\n const runId = sanitizeIdPart(event.runId);\n const ev = sanitizeIdPart(event.event);\n const node = sanitizeIdPart(nodeIdForEvent(event));\n return `manual:${runId}:${ev}:${node}:${eventIndex}`;\n}\n\nfunction toIsoTimestamp(\n ms: number,\n): { iso: string; invalidTimestamp: boolean } {\n if (typeof ms !== \"number\" || !Number.isFinite(ms)) {\n return { iso: new Date(0).toISOString(), invalidTimestamp: true };\n }\n return { iso: new Date(ms).toISOString(), invalidTimestamp: false };\n}\n\nfunction buildSource(options?: TraceEventToPersistedOptions): PersistedEventSource {\n return {\n type: \"manual\",\n name: options?.sourceName ?? \"trace-event\",\n version: options?.sourceVersion ?? \"0.1\",\n };\n}\n\nfunction mapStepTypeToInspectKind(type: StepType): InspectKind {\n switch (type) {\n case \"run\":\n return \"RUN\";\n case \"llm\":\n return \"LLM\";\n case \"tool\":\n return \"TOOL\";\n case \"decision\":\n return \"DECISION\";\n case \"logic\":\n case \"state\":\n case \"custom\":\n return \"LOGIC\";\n default:\n return \"LOGIC\";\n }\n}\n\nfunction mapRunOrStepStatus(\n status: \"success\" | \"error\",\n): PersistedEventStatus {\n return status === \"success\" ? \"ok\" : \"error\";\n}\n\nfunction mapErrorInfo(\n error: ErrorInfo | undefined,\n): {\n persisted?: PersistedInspectError;\n errorStack?: string;\n} {\n if (!error?.message) {\n return {};\n }\n const out: {\n persisted: PersistedInspectError;\n errorStack?: string;\n } = {\n persisted: {\n message: error.message,\n name: \"Error\",\n },\n };\n if (typeof error.stack === \"string\" && error.stack.length > 0) {\n out.errorStack = error.stack;\n }\n return out;\n}\n\nfunction mapTokenUsageFromMetadata(\n metadata: StepMetadata | undefined,\n): PersistedTokenUsage | undefined {\n return normalizeTokenUsage(metadata?.tokens);\n}\n\nfunction compactAttributes(\n entries: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(entries)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** Stamp converter provenance so redelivery can strip only minted indexes. */\nfunction stampDeliveryEventBase(\n eventId: string,\n attributes: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n const base = deliveryEventBaseFromIndexedId(eventId);\n if (!base) return attributes;\n return { ...(attributes ?? {}), [DELIVERY_EVENT_BASE_ATTR]: base };\n}\n\n/**\n * Maps one v0.1 {@link TraceEvent} to a v0.2 {@link PersistedInspectEvent}.\n * Does not mutate `event`.\n */\nexport function traceEventToPersistedInspectEvent(\n event: TraceEvent,\n options?: TraceEventToPersistedOptions,\n): PersistedInspectEvent {\n const eventIndex = options?.eventIndex ?? 0;\n const eventId = createPersistedEventId(event, eventIndex);\n const source = buildSource(options);\n const tsMain = toIsoTimestamp(event.timestamp);\n\n switch (event.event) {\n case \"run_started\": {\n const tsStart = toIsoTimestamp(event.startTime);\n const correlation = extractCorrelationMetadata(event.metadata);\n const attributes = compactAttributes({\n legacyEvent: \"run_started\",\n metadata:\n event.metadata !== undefined ? { ...event.metadata } : undefined,\n correlationId: correlation?.correlationId,\n requestId: correlation?.requestId,\n decisionId: correlation?.decisionId,\n groupId: correlation?.groupId,\n invalidTimestamp:\n tsMain.invalidTimestamp || tsStart.invalidTimestamp ? true : undefined,\n });\n\n return {\n schemaVersion: \"0.2\",\n eventId,\n runId: event.runId,\n kind: \"RUN\",\n name: event.name,\n status: \"running\",\n timestamp: tsMain.iso,\n startedAt: tsStart.iso,\n confidence: \"explicit\",\n source,\n attributes: stampDeliveryEventBase(eventId, attributes),\n };\n }\n\n case \"run_completed\": {\n const tsEnd = toIsoTimestamp(event.endTime);\n const { persisted: error, errorStack } = mapErrorInfo(event.error);\n const attributes = compactAttributes({\n legacyEvent: \"run_completed\",\n errorStack,\n invalidTimestamp:\n tsMain.invalidTimestamp || tsEnd.invalidTimestamp ? true : undefined,\n });\n\n return {\n schemaVersion: \"0.2\",\n eventId,\n runId: event.runId,\n kind: \"RUN\",\n name: \"run\",\n status: mapRunOrStepStatus(event.status),\n timestamp: tsMain.iso,\n endedAt: tsEnd.iso,\n durationMs: event.durationMs,\n confidence: \"explicit\",\n source,\n attributes: stampDeliveryEventBase(eventId, attributes),\n error,\n };\n }\n\n case \"step_started\": {\n const tsStart = toIsoTimestamp(event.startTime);\n const tokenUsage = mapTokenUsageFromMetadata(event.metadata);\n const attributes = compactAttributes({\n legacyEvent: \"step_started\",\n stepId: event.stepId,\n stepType: event.type,\n metadata:\n event.metadata !== undefined ? { ...event.metadata } : undefined,\n invalidTimestamp:\n tsMain.invalidTimestamp || tsStart.invalidTimestamp ? true : undefined,\n });\n\n const out: PersistedInspectEvent = {\n schemaVersion: \"0.2\",\n eventId,\n runId: event.runId,\n kind: mapStepTypeToInspectKind(event.type),\n name: event.name,\n status: \"running\",\n timestamp: tsMain.iso,\n startedAt: tsStart.iso,\n confidence: \"explicit\",\n source,\n attributes: stampDeliveryEventBase(eventId, attributes),\n };\n if (event.parentId !== undefined) {\n out.parentId = event.parentId;\n }\n if (tokenUsage !== undefined) {\n out.tokenUsage = tokenUsage;\n }\n return out;\n }\n\n case \"step_completed\": {\n const tsEnd = toIsoTimestamp(event.endTime);\n const { persisted: error, errorStack } = mapErrorInfo(event.error);\n const attributes = compactAttributes({\n legacyEvent: \"step_completed\",\n stepId: event.stepId,\n errorStack,\n invalidTimestamp:\n tsMain.invalidTimestamp || tsEnd.invalidTimestamp ? true : undefined,\n });\n\n return {\n schemaVersion: \"0.2\",\n eventId,\n runId: event.runId,\n kind: \"LOGIC\",\n name: event.stepId,\n status: mapRunOrStepStatus(event.status),\n timestamp: tsMain.iso,\n endedAt: tsEnd.iso,\n durationMs: event.durationMs,\n confidence: \"explicit\",\n source,\n attributes: stampDeliveryEventBase(eventId, attributes),\n error,\n };\n }\n\n case \"outcome_observed\": {\n const tsObserved = toIsoTimestamp(event.observedAt);\n const attributes = compactAttributes({\n legacyEvent: \"outcome_observed\",\n outcomeId: event.outcomeId,\n outcomeStatus: event.status,\n expectation: event.expectation,\n method: event.method,\n actual: event.actual,\n evidence: event.evidence,\n observedAt: tsObserved.iso,\n invalidTimestamp:\n tsMain.invalidTimestamp || tsObserved.invalidTimestamp ? true : undefined,\n });\n\n const out: PersistedInspectEvent = {\n schemaVersion: \"0.2\",\n eventId,\n runId: event.runId,\n kind: \"OUTCOME\",\n name: event.name,\n status: event.status === \"failed\" ? \"error\" : \"ok\",\n timestamp: tsMain.iso,\n confidence: \"explicit\",\n source,\n attributes: stampDeliveryEventBase(eventId, attributes),\n };\n if (event.parentId !== undefined) {\n out.parentId = event.parentId;\n }\n if (event.actual !== undefined) {\n out.outputSummary = event.actual;\n }\n return out;\n }\n\n default: {\n const _exhaustive: never = event;\n throw new Error(`Unsupported trace event: ${(_exhaustive as TraceEvent).event}`);\n }\n }\n}\n\n/**\n * Maps a v0.1 trace event list to persisted v0.2 events (one output per input).\n */\nexport function traceEventsToPersistedInspectEvents(\n events: readonly TraceEvent[],\n options?: Omit<TraceEventToPersistedOptions, \"eventIndex\">,\n): PersistedInspectEvent[] {\n return events.map((event, index) =>\n traceEventToPersistedInspectEvent(event, { ...options, eventIndex: index }),\n );\n}\n","import type { EventSource, InspectEvent } from \"../types/inspect-event.js\";\nimport {\n isPersistedInspectEvent,\n type PersistedEventSourceType,\n type PersistedInspectEvent,\n} from \"../types/persisted-inspect-event.js\";\n\nexport interface PersistedToInspectEventOptions {\n /**\n * If true, invalid persisted events are skipped by batch conversion.\n * If false or omitted, invalid events throw.\n */\n skipInvalid?: boolean;\n}\n\nfunction compactAttributes(\n entries: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(entries)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction parseIsoToMs(iso: string): { ms: number; invalidTimestamp: boolean } {\n const parsed = Date.parse(iso);\n if (!Number.isFinite(parsed)) {\n return { ms: 0, invalidTimestamp: true };\n }\n return { ms: parsed, invalidTimestamp: false };\n}\n\nfunction mapPersistedSourceToInspect(\n event: PersistedInspectEvent,\n): EventSource {\n const attrs = event.attributes ?? {};\n const sourceName = event.source.name;\n\n if (sourceName === \"pino\") {\n return {\n type: \"pino\",\n file: typeof attrs.sourceFile === \"string\" ? attrs.sourceFile : undefined,\n line: typeof attrs.sourceLine === \"number\" ? attrs.sourceLine : undefined,\n };\n }\n if (sourceName === \"winston\") {\n return {\n type: \"winston\",\n file: typeof attrs.sourceFile === \"string\" ? attrs.sourceFile : undefined,\n line: typeof attrs.sourceLine === \"number\" ? attrs.sourceLine : undefined,\n };\n }\n\n const mapType = (t: PersistedEventSourceType): EventSource[\"type\"] => {\n switch (t) {\n case \"manual\":\n return \"manual\";\n case \"json-log\":\n return \"json-log\";\n case \"log4js\":\n return \"log4js\";\n case \"adapter\":\n case \"ai-sdk\":\n case \"otel\":\n return \"adapter\";\n default:\n return \"json-log\";\n }\n };\n\n return {\n type: mapType(event.source.type),\n file: typeof attrs.sourceFile === \"string\" ? attrs.sourceFile : undefined,\n line: typeof attrs.sourceLine === \"number\" ? attrs.sourceLine : undefined,\n };\n}\n\nfunction buildInspectAttributes(event: PersistedInspectEvent): Record<string, unknown> {\n const attrs =\n event.attributes !== undefined ? { ...event.attributes } : {};\n\n if (event.inputSummary !== undefined) {\n attrs.inputSummary = event.inputSummary;\n }\n if (event.outputSummary !== undefined) {\n attrs.outputSummary = event.outputSummary;\n }\n\n if (event.error) {\n if (event.error.name !== undefined) {\n attrs.errorName = event.error.name;\n }\n attrs.errorMessage = event.error.message;\n if (event.error.code !== undefined) {\n attrs.errorCode = event.error.code;\n }\n }\n\n if (event.tokenUsage) {\n attrs.tokens = { ...event.tokenUsage };\n }\n\n if (event.source.type === \"ai-sdk\" || event.source.type === \"otel\") {\n attrs.originalSourceType = event.source.type;\n }\n\n if (event.source.name !== undefined) {\n attrs.sourceName = event.source.name;\n }\n if (event.source.version !== undefined) {\n attrs.sourceVersion = event.source.version;\n }\n\n return attrs;\n}\n\n/**\n * Maps one v0.2 {@link PersistedInspectEvent} to in-memory {@link InspectEvent}.\n * Throws if `event` fails {@link isPersistedInspectEvent}.\n */\nexport function persistedInspectEventToInspectEvent(\n event: PersistedInspectEvent,\n): InspectEvent {\n if (!isPersistedInspectEvent(event)) {\n throw new Error(\"Invalid PersistedInspectEvent: failed isPersistedInspectEvent\");\n }\n\n const ts = parseIsoToMs(event.timestamp);\n const attrs = buildInspectAttributes(event);\n if (ts.invalidTimestamp) {\n attrs.invalidTimestamp = true;\n }\n\n let status: InspectEvent[\"status\"] | undefined;\n if (\n event.status === \"running\" ||\n event.status === \"ok\" ||\n event.status === \"error\"\n ) {\n status = event.status;\n } else if (event.status === \"unknown\") {\n attrs.persistedStatus = \"unknown\";\n }\n\n const out: InspectEvent = {\n eventId: event.eventId,\n runId: event.runId,\n name: event.name,\n kind: event.kind,\n timestamp: ts.ms,\n confidence: event.confidence,\n source: mapPersistedSourceToInspect(event),\n attributes: compactAttributes(attrs),\n };\n\n if (event.parentId !== undefined) {\n out.parentId = event.parentId;\n }\n if (status !== undefined) {\n out.status = status;\n }\n if (\n event.durationMs !== undefined &&\n Number.isFinite(event.durationMs) &&\n event.durationMs >= 0\n ) {\n out.durationMs = event.durationMs;\n }\n if (event.startedAt !== undefined) {\n const started = parseIsoToMs(event.startedAt);\n if (!started.invalidTimestamp) {\n attrs.startedAtMs = started.ms;\n // Prefer real start instant for span timing when timestamp alone is completion-skewed.\n out.timestamp = started.ms;\n }\n }\n if (event.endedAt !== undefined) {\n const ended = parseIsoToMs(event.endedAt);\n if (!ended.invalidTimestamp) {\n attrs.endedAtMs = ended.ms;\n if (\n out.durationMs === undefined &&\n typeof attrs.startedAtMs === \"number\" &&\n ended.ms >= attrs.startedAtMs\n ) {\n out.durationMs = ended.ms - attrs.startedAtMs;\n }\n }\n }\n out.attributes = compactAttributes(attrs);\n\n return out;\n}\n\n/**\n * Maps persisted v0.2 events to in-memory {@link InspectEvent} rows.\n */\nexport function persistedInspectEventsToInspectEvents(\n events: readonly PersistedInspectEvent[],\n options?: PersistedToInspectEventOptions,\n): InspectEvent[] {\n const skipInvalid = options?.skipInvalid === true;\n const out: InspectEvent[] = [];\n\n for (const event of events) {\n if (!isPersistedInspectEvent(event)) {\n if (skipInvalid) {\n continue;\n }\n throw new Error(\"Invalid PersistedInspectEvent: failed isPersistedInspectEvent\");\n }\n out.push(persistedInspectEventToInspectEvent(event));\n }\n\n return out;\n}\n","import {\n projectLogicalEvents,\n type LogicalTraceEvent,\n} from \"../checks/logical-events.js\";\nimport { TreeBuilder } from \"../logs/tree-builder.js\";\nimport type { InspectRunTree } from \"../types/inspect-event.js\";\nimport type { PersistedInspectEvent } from \"../types/persisted-inspect-event.js\";\nimport type { TraceEvent } from \"../types.js\";\n\nimport { traceEventsToPersistedInspectEvents } from \"./from-trace-event.js\";\nimport { persistedInspectEventsToInspectEvents } from \"./to-inspect-event.js\";\n\nexport interface PersistedTreeBridgeOptions {\n /**\n * If true, invalid persisted events are skipped.\n * If false or omitted, invalid persisted events throw.\n */\n skipInvalid?: boolean;\n /**\n * When true, pair v0.1 start/complete lifecycle rows into logical events\n * before tree construction (CLI export fidelity). Schema 1.0 completed-only\n * rows are unchanged. Yields one RUN span per run when run_started+completed\n * pair, and one span per logical tool/step.\n */\n coalesceLifecycle?: boolean;\n}\n\nfunction logicalToPersisted(event: LogicalTraceEvent): PersistedInspectEvent {\n const { sourceEventIds: _sourceEventIds, projection: _projection, ...rest } =\n event;\n return rest;\n}\n\n/**\n * Builds {@link InspectRunTree} rows from v0.2 {@link PersistedInspectEvent} input.\n * Uses {@link TreeBuilder} as the canonical tree builder. Does not mutate `events`.\n */\nexport function persistedInspectEventsToRunTrees(\n events: readonly PersistedInspectEvent[],\n options?: PersistedTreeBridgeOptions,\n): InspectRunTree[] {\n const sourceEvents =\n options?.coalesceLifecycle === true\n ? projectLogicalEvents(events).logicalEvents.map(logicalToPersisted)\n : events;\n const inspectEvents = persistedInspectEventsToInspectEvents(sourceEvents, {\n skipInvalid: options?.skipInvalid,\n });\n return new TreeBuilder().build(inspectEvents);\n}\n\n/**\n * Builds {@link InspectRunTree} rows from legacy v0.1 {@link TraceEvent} input\n * via the persisted-event model. Does not mutate `events`.\n */\nexport function traceEventsToPersistedRunTrees(\n events: readonly TraceEvent[],\n options?: PersistedTreeBridgeOptions,\n): InspectRunTree[] {\n const persisted = traceEventsToPersistedInspectEvents(events);\n return persistedInspectEventsToRunTrees(persisted, options);\n}\n"]}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// packages/core/src/checks/canonical-equality.ts
|
|
2
|
+
var DEFAULT_MAX_DEPTH = 8;
|
|
3
|
+
var DEFAULT_MAX_BYTES = 16384;
|
|
4
|
+
function sortKeysDeep(input, depth, maxDepth) {
|
|
5
|
+
if (depth > maxDepth) {
|
|
6
|
+
throw new Error("AI_CHECK_CANONICAL_DEPTH_EXCEEDED");
|
|
7
|
+
}
|
|
8
|
+
if (input === null || typeof input !== "object") return input;
|
|
9
|
+
if (Array.isArray(input)) {
|
|
10
|
+
return input.map((item) => sortKeysDeep(item, depth + 1, maxDepth));
|
|
11
|
+
}
|
|
12
|
+
const record = input;
|
|
13
|
+
const out = {};
|
|
14
|
+
for (const key of Object.keys(record).sort()) {
|
|
15
|
+
out[key] = sortKeysDeep(record[key], depth + 1, maxDepth);
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
function encodeCanonicalStructured(value, limits) {
|
|
20
|
+
const maxDepth = limits?.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
21
|
+
const maxBytes = limits?.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
22
|
+
try {
|
|
23
|
+
const sorted = sortKeysDeep(value, 0, maxDepth);
|
|
24
|
+
const encoded = JSON.stringify(sorted);
|
|
25
|
+
if (encoded === void 0) {
|
|
26
|
+
return {
|
|
27
|
+
ok: false,
|
|
28
|
+
reason: "Value is not JSON-serializable for canonical comparison.",
|
|
29
|
+
code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (Buffer.byteLength(encoded, "utf8") > maxBytes) {
|
|
33
|
+
return {
|
|
34
|
+
ok: false,
|
|
35
|
+
reason: "Canonical structured value exceeds bounded size limit.",
|
|
36
|
+
code: "AI_CHECK_CANONICAL_SIZE_EXCEEDED"
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return { ok: true, value: encoded };
|
|
40
|
+
} catch (error) {
|
|
41
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
42
|
+
if (message === "AI_CHECK_CANONICAL_DEPTH_EXCEEDED") {
|
|
43
|
+
return {
|
|
44
|
+
ok: false,
|
|
45
|
+
reason: "Canonical structured value exceeds bounded depth limit.",
|
|
46
|
+
code: "AI_CHECK_CANONICAL_DEPTH_EXCEEDED"
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
reason: "Canonical structured encoding failed.",
|
|
52
|
+
code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function canonicalStructuredEqual(left, right, limits) {
|
|
57
|
+
const a = encodeCanonicalStructured(left, limits);
|
|
58
|
+
if (!a.ok) return { equal: false, reason: a.reason, code: a.code };
|
|
59
|
+
const b = encodeCanonicalStructured(right, limits);
|
|
60
|
+
if (!b.ok) return { equal: false, reason: b.reason, code: b.code };
|
|
61
|
+
if (a.value !== b.value) {
|
|
62
|
+
return {
|
|
63
|
+
equal: false,
|
|
64
|
+
reason: "Canonical structured values differ.",
|
|
65
|
+
code: "AI_CHECK_CANONICAL_NOT_EQUAL"
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return { equal: true };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// packages/core/src/persisted/delivery-identity.ts
|
|
72
|
+
var DELIVERY_CONFLICT_ATTR = "agent_inspect.delivery_conflict";
|
|
73
|
+
var DELIVERY_EVENT_BASE_ATTR = "agent_inspect.delivery_event_base";
|
|
74
|
+
var IDENTITY_CONFLICT_ATTR = {
|
|
75
|
+
operationId: "agent_inspect.identity_conflict.operation_id",
|
|
76
|
+
attemptId: "agent_inspect.identity_conflict.attempt_id",
|
|
77
|
+
retryOf: "agent_inspect.identity_conflict.retry_of",
|
|
78
|
+
attemptNumber: "agent_inspect.identity_conflict.attempt_number",
|
|
79
|
+
/** Comma-separated field names when a conflict survives lossy bounding. */
|
|
80
|
+
fields: "agent_inspect.identity_conflict.fields"
|
|
81
|
+
};
|
|
82
|
+
var MAX_CONFLICT_FIELDS = 8;
|
|
83
|
+
var MAX_DELIVERY_BASE_LEN = 500;
|
|
84
|
+
function stripReaderDeliveryDiscriminator(eventId, attributes) {
|
|
85
|
+
if (!eventId) return eventId;
|
|
86
|
+
const rawBase = attributes?.[DELIVERY_EVENT_BASE_ATTR];
|
|
87
|
+
if (typeof rawBase !== "string" || rawBase.trim() === "") return eventId;
|
|
88
|
+
const base = rawBase.trim().slice(0, MAX_DELIVERY_BASE_LEN);
|
|
89
|
+
if (eventId === base) return base;
|
|
90
|
+
const prefix = `${base}:`;
|
|
91
|
+
if (!eventId.startsWith(prefix)) return eventId;
|
|
92
|
+
const suffix = eventId.slice(prefix.length);
|
|
93
|
+
if (/^\d+$/.test(suffix)) return base;
|
|
94
|
+
return eventId;
|
|
95
|
+
}
|
|
96
|
+
function deliveryEventBaseFromIndexedId(eventId) {
|
|
97
|
+
if (!/:\d+$/.test(eventId)) return void 0;
|
|
98
|
+
const base = eventId.replace(/:\d+$/, "");
|
|
99
|
+
return base.length > 0 ? base.slice(0, MAX_DELIVERY_BASE_LEN) : void 0;
|
|
100
|
+
}
|
|
101
|
+
function canonicalDigest(value) {
|
|
102
|
+
if (value === void 0) return null;
|
|
103
|
+
const encoded = encodeCanonicalStructured(value);
|
|
104
|
+
return encoded.ok ? encoded.value : `unencodable:${encoded.code}`;
|
|
105
|
+
}
|
|
106
|
+
function capturedContentDigest(attributes) {
|
|
107
|
+
if (!attributes || typeof attributes !== "object") {
|
|
108
|
+
return { args: null, result: null };
|
|
109
|
+
}
|
|
110
|
+
const nested = attributes.metadata && typeof attributes.metadata === "object" ? attributes.metadata : void 0;
|
|
111
|
+
const args = attributes.arguments ?? attributes.args ?? attributes.input ?? nested?.arguments ?? nested?.args ?? nested?.input;
|
|
112
|
+
const result = attributes.result ?? attributes.output ?? attributes.response ?? nested?.result ?? nested?.output ?? nested?.response;
|
|
113
|
+
return {
|
|
114
|
+
args: args === void 0 ? null : canonicalDigest(args),
|
|
115
|
+
result: result === void 0 ? null : canonicalDigest(result)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function timeKey(fields) {
|
|
119
|
+
if (typeof fields.startedAt === "string" && fields.startedAt.trim() !== "") {
|
|
120
|
+
return fields.startedAt;
|
|
121
|
+
}
|
|
122
|
+
if (typeof fields.timestamp === "string" && fields.timestamp.trim() !== "") {
|
|
123
|
+
return fields.timestamp;
|
|
124
|
+
}
|
|
125
|
+
if (typeof fields.timestamp === "number" && Number.isFinite(fields.timestamp)) {
|
|
126
|
+
return String(fields.timestamp);
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
function deliverySemanticFingerprint(fields) {
|
|
131
|
+
const content = capturedContentDigest(fields.attributes);
|
|
132
|
+
return JSON.stringify({
|
|
133
|
+
stableEventId: stripReaderDeliveryDiscriminator(fields.eventId, fields.attributes),
|
|
134
|
+
runId: fields.runId,
|
|
135
|
+
kind: fields.kind,
|
|
136
|
+
name: fields.name,
|
|
137
|
+
status: fields.status ?? null,
|
|
138
|
+
parentId: fields.parentId ?? null,
|
|
139
|
+
sourceType: fields.sourceType ?? null,
|
|
140
|
+
time: timeKey(fields),
|
|
141
|
+
operationId: fields.operationId ?? null,
|
|
142
|
+
attemptId: fields.attemptId ?? null,
|
|
143
|
+
attemptNumber: fields.attemptNumber ?? null,
|
|
144
|
+
retryOf: fields.retryOf ?? null,
|
|
145
|
+
argsDigest: content.args,
|
|
146
|
+
resultDigest: content.result
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function identityFieldsFromAttributes(attributes) {
|
|
150
|
+
if (!attributes || typeof attributes !== "object") {
|
|
151
|
+
return {
|
|
152
|
+
operationId: null,
|
|
153
|
+
attemptId: null,
|
|
154
|
+
attemptNumber: null,
|
|
155
|
+
retryOf: null
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
const nested = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? attributes.metadata : void 0;
|
|
159
|
+
const pickString = (key) => {
|
|
160
|
+
const direct = attributes[key];
|
|
161
|
+
if (typeof direct === "string" && direct.trim() !== "") return direct.trim();
|
|
162
|
+
const nestedValue = nested?.[key];
|
|
163
|
+
if (typeof nestedValue === "string" && nestedValue.trim() !== "") {
|
|
164
|
+
return nestedValue.trim();
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
};
|
|
168
|
+
const pickNumber = () => {
|
|
169
|
+
const direct = attributes.attemptNumber ?? attributes.attempt;
|
|
170
|
+
if (typeof direct === "number" && Number.isFinite(direct)) return direct;
|
|
171
|
+
const nestedValue = nested?.attemptNumber ?? nested?.attempt;
|
|
172
|
+
if (typeof nestedValue === "number" && Number.isFinite(nestedValue)) {
|
|
173
|
+
return nestedValue;
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
};
|
|
177
|
+
return {
|
|
178
|
+
operationId: pickString("operationId"),
|
|
179
|
+
attemptId: pickString("attemptId"),
|
|
180
|
+
retryOf: pickString("retryOf"),
|
|
181
|
+
attemptNumber: pickNumber()
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function identityConflictFieldsFromAttributes(attributes) {
|
|
185
|
+
const raw = attributes?.[IDENTITY_CONFLICT_ATTR.fields];
|
|
186
|
+
if (typeof raw !== "string" || raw.trim() === "") return [];
|
|
187
|
+
return raw.split(",").map((part) => part.trim()).filter((part) => part.length > 0).slice(0, MAX_CONFLICT_FIELDS);
|
|
188
|
+
}
|
|
189
|
+
function hasDeliveryConflictMarker(attributes) {
|
|
190
|
+
return attributes?.[DELIVERY_CONFLICT_ATTR] === true;
|
|
191
|
+
}
|
|
192
|
+
function stampDeliveryConflict(event) {
|
|
193
|
+
return {
|
|
194
|
+
...event,
|
|
195
|
+
attributes: {
|
|
196
|
+
...event.attributes ?? {},
|
|
197
|
+
[DELIVERY_CONFLICT_ATTR]: true
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export { DELIVERY_CONFLICT_ATTR, DELIVERY_EVENT_BASE_ATTR, IDENTITY_CONFLICT_ATTR, canonicalStructuredEqual, deliveryEventBaseFromIndexedId, deliverySemanticFingerprint, encodeCanonicalStructured, hasDeliveryConflictMarker, identityConflictFieldsFromAttributes, identityFieldsFromAttributes, stampDeliveryConflict };
|
|
203
|
+
//# sourceMappingURL=chunk-AN5MOADW.mjs.map
|
|
204
|
+
//# sourceMappingURL=chunk-AN5MOADW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/checks/canonical-equality.ts","../src/persisted/delivery-identity.ts"],"names":[],"mappings":"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","file":"chunk-AN5MOADW.mjs","sourcesContent":["/**\n * Bounded canonical structured equality for TraceContract checks (6.29.2).\n *\n * Key-sorted JSON comparison with depth/size limits. Missing or unbounded\n * evidence must not become a silent pass.\n *\n * @experimental\n */\n\nconst DEFAULT_MAX_DEPTH = 8;\nconst DEFAULT_MAX_BYTES = 16_384;\n\nexport interface CanonicalEqualityLimits {\n maxDepth?: number;\n maxBytes?: number;\n}\n\nexport type CanonicalEncodeResult =\n | { ok: true; value: string }\n | { ok: false; reason: string; code: string };\n\nfunction sortKeysDeep(input: unknown, depth: number, maxDepth: number): unknown {\n if (depth > maxDepth) {\n throw new Error(\"AI_CHECK_CANONICAL_DEPTH_EXCEEDED\");\n }\n if (input === null || typeof input !== \"object\") return input;\n if (Array.isArray(input)) {\n return input.map((item) => sortKeysDeep(item, depth + 1, maxDepth));\n }\n const record = input as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(record).sort()) {\n out[key] = sortKeysDeep(record[key], depth + 1, maxDepth);\n }\n return out;\n}\n\n/**\n * Encode a JSON-like value into a deterministic string for equality checks.\n */\nexport function encodeCanonicalStructured(\n value: unknown,\n limits?: CanonicalEqualityLimits,\n): CanonicalEncodeResult {\n const maxDepth = limits?.maxDepth ?? DEFAULT_MAX_DEPTH;\n const maxBytes = limits?.maxBytes ?? DEFAULT_MAX_BYTES;\n try {\n const sorted = sortKeysDeep(value, 0, maxDepth);\n const encoded = JSON.stringify(sorted);\n if (encoded === undefined) {\n return {\n ok: false,\n reason: \"Value is not JSON-serializable for canonical comparison.\",\n code: \"AI_CHECK_CANONICAL_UNSERIALIZABLE\",\n };\n }\n if (Buffer.byteLength(encoded, \"utf8\") > maxBytes) {\n return {\n ok: false,\n reason: \"Canonical structured value exceeds bounded size limit.\",\n code: \"AI_CHECK_CANONICAL_SIZE_EXCEEDED\",\n };\n }\n return { ok: true, value: encoded };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message === \"AI_CHECK_CANONICAL_DEPTH_EXCEEDED\") {\n return {\n ok: false,\n reason: \"Canonical structured value exceeds bounded depth limit.\",\n code: \"AI_CHECK_CANONICAL_DEPTH_EXCEEDED\",\n };\n }\n return {\n ok: false,\n reason: \"Canonical structured encoding failed.\",\n code: \"AI_CHECK_CANONICAL_UNSERIALIZABLE\",\n };\n }\n}\n\n/**\n * Compare two JSON-like values with canonical key order.\n * Returns unavailable/fail codes rather than throwing.\n */\nexport function canonicalStructuredEqual(\n left: unknown,\n right: unknown,\n limits?: CanonicalEqualityLimits,\n):\n | { equal: true }\n | { equal: false; reason: string; code: string } {\n const a = encodeCanonicalStructured(left, limits);\n if (!a.ok) return { equal: false, reason: a.reason, code: a.code };\n const b = encodeCanonicalStructured(right, limits);\n if (!b.ok) return { equal: false, reason: b.reason, code: b.code };\n if (a.value !== b.value) {\n return {\n equal: false,\n reason: \"Canonical structured values differ.\",\n code: \"AI_CHECK_CANONICAL_NOT_EQUAL\",\n };\n }\n return { equal: true };\n}\n","/**\n * Physical delivery vs logical execution identity helpers.\n *\n * Converters may mint indexed synthetic eventIds (`manual:…`, `inspect:…`) and\n * stamp `agent_inspect.delivery_event_base` when they do. Native opaque eventIds\n * must not be rewritten from string shape alone.\n *\n * @internal\n */\n\nimport { encodeCanonicalStructured } from \"../checks/canonical-equality.js\";\n\n/** Bounded marker stamped when a tree collapses conflicting same-eventId rows. */\nexport const DELIVERY_CONFLICT_ATTR = \"agent_inspect.delivery_conflict\";\n\n/**\n * Converter-stamped base eventId (without trailing delivery index).\n * Present only when AgentInspect minted the indexed synthetic id.\n */\nexport const DELIVERY_EVENT_BASE_ATTR = \"agent_inspect.delivery_event_base\";\n\n/** OTLP attrs carrying the non-preferred side of a direct/nested identity conflict. */\nexport const IDENTITY_CONFLICT_ATTR = {\n operationId: \"agent_inspect.identity_conflict.operation_id\",\n attemptId: \"agent_inspect.identity_conflict.attempt_id\",\n retryOf: \"agent_inspect.identity_conflict.retry_of\",\n attemptNumber: \"agent_inspect.identity_conflict.attempt_number\",\n /** Comma-separated field names when a conflict survives lossy bounding. */\n fields: \"agent_inspect.identity_conflict.fields\",\n} as const;\n\nconst MAX_CONFLICT_FIELDS = 8;\nconst MAX_DELIVERY_BASE_LEN = 500;\n\n/**\n * Strip a proven converter delivery discriminator only.\n * Requires `agent_inspect.delivery_event_base` provenance that matches the id.\n * Opaque native IDs (including synthetic-looking shapes) stay intact.\n */\nexport function stripReaderDeliveryDiscriminator(\n eventId: string,\n attributes?: Record<string, unknown>,\n): string {\n if (!eventId) return eventId;\n const rawBase = attributes?.[DELIVERY_EVENT_BASE_ATTR];\n if (typeof rawBase !== \"string\" || rawBase.trim() === \"\") return eventId;\n const base = rawBase.trim().slice(0, MAX_DELIVERY_BASE_LEN);\n if (eventId === base) return base;\n const prefix = `${base}:`;\n if (!eventId.startsWith(prefix)) return eventId;\n const suffix = eventId.slice(prefix.length);\n if (/^\\d+$/.test(suffix)) return base;\n return eventId;\n}\n\n/** Base id for a converter-minted `…:<index>` eventId (no provenance check). */\nexport function deliveryEventBaseFromIndexedId(eventId: string): string | undefined {\n if (!/:\\d+$/.test(eventId)) return undefined;\n const base = eventId.replace(/:\\d+$/, \"\");\n return base.length > 0 ? base.slice(0, MAX_DELIVERY_BASE_LEN) : undefined;\n}\n\nexport interface DeliveryIdentityFields {\n eventId: string;\n runId: string;\n kind: string;\n name: string;\n status?: string;\n parentId?: string;\n timestamp?: string | number;\n startedAt?: string;\n sourceType?: string;\n attributes?: Record<string, unknown>;\n operationId?: string | null;\n attemptId?: string | null;\n attemptNumber?: number | null;\n retryOf?: string | null;\n}\n\nfunction canonicalDigest(value: unknown): string | null {\n if (value === undefined) return null;\n const encoded = encodeCanonicalStructured(value);\n return encoded.ok ? encoded.value : `unencodable:${encoded.code}`;\n}\n\nfunction capturedContentDigest(attributes: Record<string, unknown> | undefined): {\n args: string | null;\n result: string | null;\n} {\n if (!attributes || typeof attributes !== \"object\") {\n return { args: null, result: null };\n }\n const nested =\n attributes.metadata && typeof attributes.metadata === \"object\"\n ? (attributes.metadata as Record<string, unknown>)\n : undefined;\n const args =\n attributes.arguments ??\n attributes.args ??\n attributes.input ??\n nested?.arguments ??\n nested?.args ??\n nested?.input;\n const result =\n attributes.result ??\n attributes.output ??\n attributes.response ??\n nested?.result ??\n nested?.output ??\n nested?.response;\n return {\n args: args === undefined ? null : canonicalDigest(args),\n result: result === undefined ? null : canonicalDigest(result),\n };\n}\n\nfunction timeKey(fields: DeliveryIdentityFields): string | null {\n if (typeof fields.startedAt === \"string\" && fields.startedAt.trim() !== \"\") {\n return fields.startedAt;\n }\n if (typeof fields.timestamp === \"string\" && fields.timestamp.trim() !== \"\") {\n return fields.timestamp;\n }\n if (typeof fields.timestamp === \"number\" && Number.isFinite(fields.timestamp)) {\n return String(fields.timestamp);\n }\n return null;\n}\n\n/**\n * Fingerprint for identical-redelivery collapse vs conflicting reuse.\n * Includes run scope, opaque (or provenance-stripped) eventId,\n * workflow identity, status/parent/source, time, and bounded captured content.\n */\nexport function deliverySemanticFingerprint(fields: DeliveryIdentityFields): string {\n const content = capturedContentDigest(fields.attributes);\n return JSON.stringify({\n stableEventId: stripReaderDeliveryDiscriminator(fields.eventId, fields.attributes),\n runId: fields.runId,\n kind: fields.kind,\n name: fields.name,\n status: fields.status ?? null,\n parentId: fields.parentId ?? null,\n sourceType: fields.sourceType ?? null,\n time: timeKey(fields),\n operationId: fields.operationId ?? null,\n attemptId: fields.attemptId ?? null,\n attemptNumber: fields.attemptNumber ?? null,\n retryOf: fields.retryOf ?? null,\n argsDigest: content.args,\n resultDigest: content.result,\n });\n}\n\n/**\n * Pull supported identity fields from a direct/nested attributes bag for\n * tree/export fingerprints (does not invent missing values).\n */\nexport function identityFieldsFromAttributes(\n attributes: Record<string, unknown> | undefined,\n): Pick<\n DeliveryIdentityFields,\n \"operationId\" | \"attemptId\" | \"attemptNumber\" | \"retryOf\"\n> {\n if (!attributes || typeof attributes !== \"object\") {\n return {\n operationId: null,\n attemptId: null,\n attemptNumber: null,\n retryOf: null,\n };\n }\n const nested =\n attributes.metadata &&\n typeof attributes.metadata === \"object\" &&\n !Array.isArray(attributes.metadata)\n ? (attributes.metadata as Record<string, unknown>)\n : undefined;\n const pickString = (key: \"operationId\" | \"attemptId\" | \"retryOf\"): string | null => {\n const direct = attributes[key];\n if (typeof direct === \"string\" && direct.trim() !== \"\") return direct.trim();\n const nestedValue = nested?.[key];\n if (typeof nestedValue === \"string\" && nestedValue.trim() !== \"\") {\n return nestedValue.trim();\n }\n return null;\n };\n const pickNumber = (): number | null => {\n const direct = attributes.attemptNumber ?? attributes.attempt;\n if (typeof direct === \"number\" && Number.isFinite(direct)) return direct;\n const nestedValue = nested?.attemptNumber ?? nested?.attempt;\n if (typeof nestedValue === \"number\" && Number.isFinite(nestedValue)) {\n return nestedValue;\n }\n return null;\n };\n return {\n operationId: pickString(\"operationId\"),\n attemptId: pickString(\"attemptId\"),\n retryOf: pickString(\"retryOf\"),\n attemptNumber: pickNumber(),\n };\n}\n\n/** Parse bounded export marker listing identity fields that conflicted. */\nexport function identityConflictFieldsFromAttributes(\n attributes: Record<string, unknown> | undefined,\n): string[] {\n const raw = attributes?.[IDENTITY_CONFLICT_ATTR.fields];\n if (typeof raw !== \"string\" || raw.trim() === \"\") return [];\n return raw\n .split(\",\")\n .map((part) => part.trim())\n .filter((part) => part.length > 0)\n .slice(0, MAX_CONFLICT_FIELDS);\n}\n\nexport function hasDeliveryConflictMarker(\n attributes: Record<string, unknown> | undefined,\n): boolean {\n return attributes?.[DELIVERY_CONFLICT_ATTR] === true;\n}\n\n/**\n * Stamp a bounded delivery-conflict marker without dropping provenance.\n * Does not mutate the input event object.\n */\nexport function stampDeliveryConflict<T extends { attributes?: Record<string, unknown> }>(\n event: T,\n): T {\n return {\n ...event,\n attributes: {\n ...(event.attributes ?? {}),\n [DELIVERY_CONFLICT_ATTR]: true,\n },\n };\n}\n"]}
|