@agent-inspect/mcp-server 6.31.21 → 6.31.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-L5YP42Q6.mjs → chunk-VNZYYTP5.mjs} +326 -34
- package/dist/chunk-VNZYYTP5.mjs.map +1 -0
- package/dist/cli.cjs +324 -32
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.cjs +324 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
- package/dist/chunk-L5YP42Q6.mjs.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -4092,6 +4092,168 @@ function runTraceChecks(input, options = {}) {
|
|
|
4092
4092
|
};
|
|
4093
4093
|
}
|
|
4094
4094
|
|
|
4095
|
+
// packages/core/src/checks/canonical-equality.ts
|
|
4096
|
+
var DEFAULT_MAX_DEPTH = 8;
|
|
4097
|
+
var DEFAULT_MAX_BYTES = 16384;
|
|
4098
|
+
function sortKeysDeep(input, depth, maxDepth) {
|
|
4099
|
+
if (depth > maxDepth) {
|
|
4100
|
+
throw new Error("AI_CHECK_CANONICAL_DEPTH_EXCEEDED");
|
|
4101
|
+
}
|
|
4102
|
+
if (input === null || typeof input !== "object") return input;
|
|
4103
|
+
if (Array.isArray(input)) {
|
|
4104
|
+
return input.map((item) => sortKeysDeep(item, depth + 1, maxDepth));
|
|
4105
|
+
}
|
|
4106
|
+
const record = input;
|
|
4107
|
+
const out = {};
|
|
4108
|
+
for (const key of Object.keys(record).sort()) {
|
|
4109
|
+
out[key] = sortKeysDeep(record[key], depth + 1, maxDepth);
|
|
4110
|
+
}
|
|
4111
|
+
return out;
|
|
4112
|
+
}
|
|
4113
|
+
function encodeCanonicalStructured(value, limits) {
|
|
4114
|
+
const maxDepth = DEFAULT_MAX_DEPTH;
|
|
4115
|
+
const maxBytes = DEFAULT_MAX_BYTES;
|
|
4116
|
+
try {
|
|
4117
|
+
const sorted = sortKeysDeep(value, 0, maxDepth);
|
|
4118
|
+
const encoded = JSON.stringify(sorted);
|
|
4119
|
+
if (encoded === void 0) {
|
|
4120
|
+
return {
|
|
4121
|
+
ok: false,
|
|
4122
|
+
reason: "Value is not JSON-serializable for canonical comparison.",
|
|
4123
|
+
code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
|
|
4124
|
+
};
|
|
4125
|
+
}
|
|
4126
|
+
if (Buffer.byteLength(encoded, "utf8") > maxBytes) {
|
|
4127
|
+
return {
|
|
4128
|
+
ok: false,
|
|
4129
|
+
reason: "Canonical structured value exceeds bounded size limit.",
|
|
4130
|
+
code: "AI_CHECK_CANONICAL_SIZE_EXCEEDED"
|
|
4131
|
+
};
|
|
4132
|
+
}
|
|
4133
|
+
return { ok: true, value: encoded };
|
|
4134
|
+
} catch (error) {
|
|
4135
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4136
|
+
if (message === "AI_CHECK_CANONICAL_DEPTH_EXCEEDED") {
|
|
4137
|
+
return {
|
|
4138
|
+
ok: false,
|
|
4139
|
+
reason: "Canonical structured value exceeds bounded depth limit.",
|
|
4140
|
+
code: "AI_CHECK_CANONICAL_DEPTH_EXCEEDED"
|
|
4141
|
+
};
|
|
4142
|
+
}
|
|
4143
|
+
return {
|
|
4144
|
+
ok: false,
|
|
4145
|
+
reason: "Canonical structured encoding failed.",
|
|
4146
|
+
code: "AI_CHECK_CANONICAL_UNSERIALIZABLE"
|
|
4147
|
+
};
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
|
|
4151
|
+
// packages/core/src/persisted/delivery-identity.ts
|
|
4152
|
+
var DELIVERY_CONFLICT_ATTR = "agent_inspect.delivery_conflict";
|
|
4153
|
+
var IDENTITY_CONFLICT_ATTR = {
|
|
4154
|
+
operationId: "agent_inspect.identity_conflict.operation_id",
|
|
4155
|
+
attemptId: "agent_inspect.identity_conflict.attempt_id",
|
|
4156
|
+
retryOf: "agent_inspect.identity_conflict.retry_of",
|
|
4157
|
+
attemptNumber: "agent_inspect.identity_conflict.attempt_number"
|
|
4158
|
+
};
|
|
4159
|
+
var SYNTHETIC_DELIVERY_ID = /^(?:manual|inspect):[A-Za-z0-9_-]+:[A-Za-z0-9_-]+:[A-Za-z0-9_-]+:\d+$/;
|
|
4160
|
+
function stripReaderDeliveryDiscriminator(eventId) {
|
|
4161
|
+
if (!SYNTHETIC_DELIVERY_ID.test(eventId)) return eventId;
|
|
4162
|
+
return eventId.replace(/:\d+$/, "");
|
|
4163
|
+
}
|
|
4164
|
+
function canonicalDigest(value) {
|
|
4165
|
+
if (value === void 0) return null;
|
|
4166
|
+
const encoded = encodeCanonicalStructured(value);
|
|
4167
|
+
return encoded.ok ? encoded.value : `unencodable:${encoded.code}`;
|
|
4168
|
+
}
|
|
4169
|
+
function capturedContentDigest(attributes) {
|
|
4170
|
+
if (!attributes || typeof attributes !== "object") {
|
|
4171
|
+
return { args: null, result: null };
|
|
4172
|
+
}
|
|
4173
|
+
const nested = attributes.metadata && typeof attributes.metadata === "object" ? attributes.metadata : void 0;
|
|
4174
|
+
const args = attributes.arguments ?? attributes.args ?? attributes.input ?? nested?.arguments ?? nested?.args ?? nested?.input;
|
|
4175
|
+
const result = attributes.result ?? attributes.output ?? attributes.response ?? nested?.result ?? nested?.output ?? nested?.response;
|
|
4176
|
+
return {
|
|
4177
|
+
args: args === void 0 ? null : canonicalDigest(args),
|
|
4178
|
+
result: result === void 0 ? null : canonicalDigest(result)
|
|
4179
|
+
};
|
|
4180
|
+
}
|
|
4181
|
+
function timeKey(fields) {
|
|
4182
|
+
if (typeof fields.startedAt === "string" && fields.startedAt.trim() !== "") {
|
|
4183
|
+
return fields.startedAt;
|
|
4184
|
+
}
|
|
4185
|
+
if (typeof fields.timestamp === "string" && fields.timestamp.trim() !== "") {
|
|
4186
|
+
return fields.timestamp;
|
|
4187
|
+
}
|
|
4188
|
+
if (typeof fields.timestamp === "number" && Number.isFinite(fields.timestamp)) {
|
|
4189
|
+
return String(fields.timestamp);
|
|
4190
|
+
}
|
|
4191
|
+
return null;
|
|
4192
|
+
}
|
|
4193
|
+
function deliverySemanticFingerprint(fields) {
|
|
4194
|
+
const content = capturedContentDigest(fields.attributes);
|
|
4195
|
+
return JSON.stringify({
|
|
4196
|
+
stableEventId: stripReaderDeliveryDiscriminator(fields.eventId),
|
|
4197
|
+
runId: fields.runId,
|
|
4198
|
+
kind: fields.kind,
|
|
4199
|
+
name: fields.name,
|
|
4200
|
+
status: fields.status ?? null,
|
|
4201
|
+
parentId: fields.parentId ?? null,
|
|
4202
|
+
sourceType: fields.sourceType ?? null,
|
|
4203
|
+
time: timeKey(fields),
|
|
4204
|
+
operationId: fields.operationId ?? null,
|
|
4205
|
+
attemptId: fields.attemptId ?? null,
|
|
4206
|
+
attemptNumber: fields.attemptNumber ?? null,
|
|
4207
|
+
retryOf: fields.retryOf ?? null,
|
|
4208
|
+
argsDigest: content.args,
|
|
4209
|
+
resultDigest: content.result
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
function identityFieldsFromAttributes(attributes) {
|
|
4213
|
+
if (!attributes || typeof attributes !== "object") {
|
|
4214
|
+
return {
|
|
4215
|
+
operationId: null,
|
|
4216
|
+
attemptId: null,
|
|
4217
|
+
attemptNumber: null,
|
|
4218
|
+
retryOf: null
|
|
4219
|
+
};
|
|
4220
|
+
}
|
|
4221
|
+
const nested = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? attributes.metadata : void 0;
|
|
4222
|
+
const pickString3 = (key) => {
|
|
4223
|
+
const direct = attributes[key];
|
|
4224
|
+
if (typeof direct === "string" && direct.trim() !== "") return direct.trim();
|
|
4225
|
+
const nestedValue = nested?.[key];
|
|
4226
|
+
if (typeof nestedValue === "string" && nestedValue.trim() !== "") {
|
|
4227
|
+
return nestedValue.trim();
|
|
4228
|
+
}
|
|
4229
|
+
return null;
|
|
4230
|
+
};
|
|
4231
|
+
const pickNumber2 = () => {
|
|
4232
|
+
const direct = attributes.attemptNumber ?? attributes.attempt;
|
|
4233
|
+
if (typeof direct === "number" && Number.isFinite(direct)) return direct;
|
|
4234
|
+
const nestedValue = nested?.attemptNumber ?? nested?.attempt;
|
|
4235
|
+
if (typeof nestedValue === "number" && Number.isFinite(nestedValue)) {
|
|
4236
|
+
return nestedValue;
|
|
4237
|
+
}
|
|
4238
|
+
return null;
|
|
4239
|
+
};
|
|
4240
|
+
return {
|
|
4241
|
+
operationId: pickString3("operationId"),
|
|
4242
|
+
attemptId: pickString3("attemptId"),
|
|
4243
|
+
retryOf: pickString3("retryOf"),
|
|
4244
|
+
attemptNumber: pickNumber2()
|
|
4245
|
+
};
|
|
4246
|
+
}
|
|
4247
|
+
function stampDeliveryConflict(event) {
|
|
4248
|
+
return {
|
|
4249
|
+
...event,
|
|
4250
|
+
attributes: {
|
|
4251
|
+
...event.attributes ?? {},
|
|
4252
|
+
[DELIVERY_CONFLICT_ATTR]: true
|
|
4253
|
+
}
|
|
4254
|
+
};
|
|
4255
|
+
}
|
|
4256
|
+
|
|
4095
4257
|
// packages/core/src/checks/contract.ts
|
|
4096
4258
|
new Set(OBSERVED_OUTCOME_METHODS);
|
|
4097
4259
|
|
|
@@ -4129,18 +4291,18 @@ function escapeMarkdown(value) {
|
|
|
4129
4291
|
function escapeHtml(value) {
|
|
4130
4292
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
4131
4293
|
}
|
|
4132
|
-
function
|
|
4294
|
+
function sortKeysDeep2(input) {
|
|
4133
4295
|
if (input === null || typeof input !== "object") return input;
|
|
4134
|
-
if (Array.isArray(input)) return input.map(
|
|
4296
|
+
if (Array.isArray(input)) return input.map(sortKeysDeep2);
|
|
4135
4297
|
const o = input;
|
|
4136
4298
|
const out = {};
|
|
4137
4299
|
for (const k of Object.keys(o).sort()) {
|
|
4138
|
-
out[k] =
|
|
4300
|
+
out[k] = sortKeysDeep2(o[k]);
|
|
4139
4301
|
}
|
|
4140
4302
|
return out;
|
|
4141
4303
|
}
|
|
4142
4304
|
function stableJson(value, pretty) {
|
|
4143
|
-
const sorted =
|
|
4305
|
+
const sorted = sortKeysDeep2(value);
|
|
4144
4306
|
return pretty === true ? JSON.stringify(sorted, null, 2) : JSON.stringify(sorted);
|
|
4145
4307
|
}
|
|
4146
4308
|
function compactAttributes(attrs2, options) {
|
|
@@ -4965,7 +5127,47 @@ var TreeBuilder = class {
|
|
|
4965
5127
|
const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);
|
|
4966
5128
|
const nodes = /* @__PURE__ */ new Map();
|
|
4967
5129
|
for (const e of sorted) {
|
|
4968
|
-
nodes.
|
|
5130
|
+
const existing = nodes.get(e.eventId);
|
|
5131
|
+
if (!existing) {
|
|
5132
|
+
nodes.set(e.eventId, { event: e, children: [], depth: 0 });
|
|
5133
|
+
continue;
|
|
5134
|
+
}
|
|
5135
|
+
const existingAttrs = existing.event.attributes && typeof existing.event.attributes === "object" ? existing.event.attributes : void 0;
|
|
5136
|
+
const nextAttrs = e.attributes && typeof e.attributes === "object" ? e.attributes : void 0;
|
|
5137
|
+
const existingIdentity = identityFieldsFromAttributes(existingAttrs);
|
|
5138
|
+
const nextIdentity = identityFieldsFromAttributes(nextAttrs);
|
|
5139
|
+
const existingFp = deliverySemanticFingerprint({
|
|
5140
|
+
eventId: existing.event.eventId,
|
|
5141
|
+
runId: existing.event.runId,
|
|
5142
|
+
kind: existing.event.kind,
|
|
5143
|
+
name: existing.event.name,
|
|
5144
|
+
status: existing.event.status,
|
|
5145
|
+
parentId: existing.event.parentId,
|
|
5146
|
+
timestamp: existing.event.timestamp,
|
|
5147
|
+
sourceType: existing.event.source?.type,
|
|
5148
|
+
attributes: existingAttrs,
|
|
5149
|
+
...existingIdentity
|
|
5150
|
+
});
|
|
5151
|
+
const nextFp = deliverySemanticFingerprint({
|
|
5152
|
+
eventId: e.eventId,
|
|
5153
|
+
runId: e.runId,
|
|
5154
|
+
kind: e.kind,
|
|
5155
|
+
name: e.name,
|
|
5156
|
+
status: e.status,
|
|
5157
|
+
parentId: e.parentId,
|
|
5158
|
+
timestamp: e.timestamp,
|
|
5159
|
+
sourceType: e.source?.type,
|
|
5160
|
+
attributes: nextAttrs,
|
|
5161
|
+
...nextIdentity
|
|
5162
|
+
});
|
|
5163
|
+
if (existingFp === nextFp) {
|
|
5164
|
+
continue;
|
|
5165
|
+
}
|
|
5166
|
+
nodes.set(e.eventId, {
|
|
5167
|
+
event: stampDeliveryConflict(e),
|
|
5168
|
+
children: [],
|
|
5169
|
+
depth: 0
|
|
5170
|
+
});
|
|
4969
5171
|
}
|
|
4970
5172
|
const { roots, summary } = linkNodesVisibilityFirst(nodes);
|
|
4971
5173
|
const confidenceBreakdown = {
|
|
@@ -6430,6 +6632,12 @@ function promoteAgentInspectWorkflowIdentity(attributes, pathPrefix) {
|
|
|
6430
6632
|
["agent_inspect.retry_of", "retryOf", "string"],
|
|
6431
6633
|
["agent_inspect.attempt_number", "attemptNumber", "int"]
|
|
6432
6634
|
];
|
|
6635
|
+
const conflictMapping = [
|
|
6636
|
+
["agent_inspect.identity_conflict.operation_id", "operationId", "string"],
|
|
6637
|
+
["agent_inspect.identity_conflict.attempt_id", "attemptId", "string"],
|
|
6638
|
+
["agent_inspect.identity_conflict.retry_of", "retryOf", "string"],
|
|
6639
|
+
["agent_inspect.identity_conflict.attempt_number", "attemptNumber", "int"]
|
|
6640
|
+
];
|
|
6433
6641
|
const metadata = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? { ...attributes.metadata } : {};
|
|
6434
6642
|
for (const [dotted, camel, kind] of mapping) {
|
|
6435
6643
|
const raw = attributes[dotted];
|
|
@@ -6481,6 +6689,46 @@ function promoteAgentInspectWorkflowIdentity(attributes, pathPrefix) {
|
|
|
6481
6689
|
if (direct === void 0) attributes[camel] = promoted;
|
|
6482
6690
|
if (nested === void 0) metadata[camel] = promoted;
|
|
6483
6691
|
}
|
|
6692
|
+
for (const [dotted, camel, kind] of conflictMapping) {
|
|
6693
|
+
const raw = attributes[dotted];
|
|
6694
|
+
if (raw === void 0 || raw === null) continue;
|
|
6695
|
+
let alternate;
|
|
6696
|
+
if (kind === "int") {
|
|
6697
|
+
const n = typeof raw === "number" ? raw : typeof raw === "string" ? Number(raw) : NaN;
|
|
6698
|
+
if (!Number.isFinite(n) || n < 1) {
|
|
6699
|
+
warnings.push({
|
|
6700
|
+
code: "otlp_identity_invalid",
|
|
6701
|
+
message: `Ignoring invalid ${dotted} identity conflict value.`,
|
|
6702
|
+
severity: "warning",
|
|
6703
|
+
field: `${pathPrefix}.${dotted}`
|
|
6704
|
+
});
|
|
6705
|
+
continue;
|
|
6706
|
+
}
|
|
6707
|
+
alternate = Math.trunc(n);
|
|
6708
|
+
} else if (typeof raw === "string" && raw.trim() !== "") {
|
|
6709
|
+
alternate = raw.trim();
|
|
6710
|
+
} else {
|
|
6711
|
+
warnings.push({
|
|
6712
|
+
code: "otlp_identity_invalid",
|
|
6713
|
+
message: `Ignoring non-string ${dotted} identity conflict value.`,
|
|
6714
|
+
severity: "warning",
|
|
6715
|
+
field: `${pathPrefix}.${dotted}`
|
|
6716
|
+
});
|
|
6717
|
+
continue;
|
|
6718
|
+
}
|
|
6719
|
+
const preferred = attributes[camel];
|
|
6720
|
+
if (preferred !== void 0 && preferred !== alternate) {
|
|
6721
|
+
metadata[camel] = alternate;
|
|
6722
|
+
warnings.push({
|
|
6723
|
+
code: "otlp_identity_conflict",
|
|
6724
|
+
message: `Conflicting ${camel}: attributes.${camel} vs nested alternate from ${dotted}; retaining both.`,
|
|
6725
|
+
severity: "warning",
|
|
6726
|
+
field: `${pathPrefix}.${dotted}`
|
|
6727
|
+
});
|
|
6728
|
+
} else if (preferred === void 0) {
|
|
6729
|
+
metadata[camel] = alternate;
|
|
6730
|
+
}
|
|
6731
|
+
}
|
|
6484
6732
|
if (Object.keys(metadata).length > 0) {
|
|
6485
6733
|
attributes.metadata = metadata;
|
|
6486
6734
|
}
|
|
@@ -7667,43 +7915,81 @@ var STRUCTURAL_IDENTITY_KEYS = [
|
|
|
7667
7915
|
"attemptNumber",
|
|
7668
7916
|
"attempt"
|
|
7669
7917
|
];
|
|
7670
|
-
function
|
|
7918
|
+
function nestedBag(bag) {
|
|
7671
7919
|
if (!bag || typeof bag !== "object") return void 0;
|
|
7672
|
-
const
|
|
7673
|
-
if (typeof
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
if (
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7920
|
+
const nested = bag.metadata;
|
|
7921
|
+
if (!nested || typeof nested !== "object" || Array.isArray(nested)) return void 0;
|
|
7922
|
+
return nested;
|
|
7923
|
+
}
|
|
7924
|
+
function pickBoundedIdentityString(bag, key, maxLen) {
|
|
7925
|
+
if (!bag || typeof bag !== "object") return {};
|
|
7926
|
+
const directRaw = bag[key];
|
|
7927
|
+
const nestedRaw = nestedBag(bag)?.[key];
|
|
7928
|
+
const direct = typeof directRaw === "string" && directRaw.trim() !== "" ? directRaw.trim().slice(0, maxLen) : void 0;
|
|
7929
|
+
const nested = typeof nestedRaw === "string" && nestedRaw.trim() !== "" ? nestedRaw.trim().slice(0, maxLen) : void 0;
|
|
7930
|
+
if (direct !== void 0 && nested !== void 0 && direct !== nested) {
|
|
7931
|
+
return { value: direct, conflictAlternate: nested };
|
|
7932
|
+
}
|
|
7933
|
+
if (direct !== void 0) return { value: direct };
|
|
7934
|
+
if (nested !== void 0) return { value: nested };
|
|
7935
|
+
return {};
|
|
7681
7936
|
}
|
|
7682
7937
|
function pickBoundedIdentityNumber(bag, key) {
|
|
7683
|
-
if (!bag || typeof bag !== "object") return
|
|
7684
|
-
const
|
|
7685
|
-
|
|
7686
|
-
const
|
|
7687
|
-
|
|
7688
|
-
|
|
7938
|
+
if (!bag || typeof bag !== "object") return {};
|
|
7939
|
+
const directRaw = bag[key];
|
|
7940
|
+
const nestedRaw = nestedBag(bag)?.[key];
|
|
7941
|
+
const direct = typeof directRaw === "number" && Number.isFinite(directRaw) ? directRaw : void 0;
|
|
7942
|
+
const nested = typeof nestedRaw === "number" && Number.isFinite(nestedRaw) ? nestedRaw : void 0;
|
|
7943
|
+
if (direct !== void 0 && nested !== void 0 && direct !== nested) {
|
|
7944
|
+
return { value: direct, conflictAlternate: nested };
|
|
7945
|
+
}
|
|
7946
|
+
if (direct !== void 0) return { value: direct };
|
|
7947
|
+
if (nested !== void 0) return { value: nested };
|
|
7948
|
+
return {};
|
|
7689
7949
|
}
|
|
7690
7950
|
function appendStructuralIdentityAttrs(attrs2, meta, maxLen) {
|
|
7951
|
+
const conflicts = [];
|
|
7691
7952
|
const operationId = pickBoundedIdentityString(meta, "operationId", maxLen);
|
|
7692
|
-
if (operationId !== void 0) {
|
|
7693
|
-
attrs2.push(stringAttr2("agent_inspect.operation_id", operationId));
|
|
7953
|
+
if (operationId.value !== void 0) {
|
|
7954
|
+
attrs2.push(stringAttr2("agent_inspect.operation_id", operationId.value));
|
|
7955
|
+
}
|
|
7956
|
+
if (operationId.conflictAlternate !== void 0) {
|
|
7957
|
+
attrs2.push(
|
|
7958
|
+
stringAttr2(IDENTITY_CONFLICT_ATTR.operationId, operationId.conflictAlternate)
|
|
7959
|
+
);
|
|
7960
|
+
conflicts.push("operationId");
|
|
7694
7961
|
}
|
|
7695
7962
|
const attemptId = pickBoundedIdentityString(meta, "attemptId", maxLen);
|
|
7696
|
-
if (attemptId !== void 0) {
|
|
7697
|
-
attrs2.push(stringAttr2("agent_inspect.attempt_id", attemptId));
|
|
7963
|
+
if (attemptId.value !== void 0) {
|
|
7964
|
+
attrs2.push(stringAttr2("agent_inspect.attempt_id", attemptId.value));
|
|
7965
|
+
}
|
|
7966
|
+
if (attemptId.conflictAlternate !== void 0) {
|
|
7967
|
+
attrs2.push(stringAttr2(IDENTITY_CONFLICT_ATTR.attemptId, attemptId.conflictAlternate));
|
|
7968
|
+
conflicts.push("attemptId");
|
|
7698
7969
|
}
|
|
7699
7970
|
const retryOf = pickBoundedIdentityString(meta, "retryOf", maxLen);
|
|
7700
|
-
if (retryOf !== void 0) {
|
|
7701
|
-
attrs2.push(stringAttr2("agent_inspect.retry_of", retryOf));
|
|
7971
|
+
if (retryOf.value !== void 0) {
|
|
7972
|
+
attrs2.push(stringAttr2("agent_inspect.retry_of", retryOf.value));
|
|
7702
7973
|
}
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7974
|
+
if (retryOf.conflictAlternate !== void 0) {
|
|
7975
|
+
attrs2.push(stringAttr2(IDENTITY_CONFLICT_ATTR.retryOf, retryOf.conflictAlternate));
|
|
7976
|
+
conflicts.push("retryOf");
|
|
7977
|
+
}
|
|
7978
|
+
const attemptNumberPrimary = pickBoundedIdentityNumber(meta, "attemptNumber");
|
|
7979
|
+
const attemptNumber = attemptNumberPrimary.value !== void 0 || attemptNumberPrimary.conflictAlternate !== void 0 ? attemptNumberPrimary : pickBoundedIdentityNumber(meta, "attempt");
|
|
7980
|
+
if (attemptNumber.value !== void 0) {
|
|
7981
|
+
attrs2.push(intAttr("agent_inspect.attempt_number", attemptNumber.value));
|
|
7706
7982
|
}
|
|
7983
|
+
if (attemptNumber.conflictAlternate !== void 0) {
|
|
7984
|
+
attrs2.push(
|
|
7985
|
+
intAttr(IDENTITY_CONFLICT_ATTR.attemptNumber, attemptNumber.conflictAlternate)
|
|
7986
|
+
);
|
|
7987
|
+
conflicts.push("attemptNumber");
|
|
7988
|
+
}
|
|
7989
|
+
if (meta?.[DELIVERY_CONFLICT_ATTR] === true) {
|
|
7990
|
+
attrs2.push(boolAttr(DELIVERY_CONFLICT_ATTR, true));
|
|
7991
|
+
}
|
|
7992
|
+
return conflicts;
|
|
7707
7993
|
}
|
|
7708
7994
|
function resolveSpanTimes(ev) {
|
|
7709
7995
|
const startedAtMs = typeof ev.attributes?.startedAtMs === "number" && Number.isFinite(ev.attributes.startedAtMs) ? ev.attributes.startedAtMs : void 0;
|
|
@@ -7726,7 +8012,8 @@ function exportOtlpJson(tree, options) {
|
|
|
7726
8012
|
"OTLP JSON export uses OTel GenAI-aligned attributes where applicable; experimental until verified against specific collectors.",
|
|
7727
8013
|
"Not OTLP gRPC/protobuf \u2014 JSON mapping only. Generated locally; no network upload.",
|
|
7728
8014
|
"Status and span kind use OTLP numeric enums (StatusCode 0/1/2, SpanKind INTERNAL=1).",
|
|
7729
|
-
"When present on source events, operationId/attemptId/retryOf/attemptNumber are emitted as bounded agent_inspect.* identity attributes (not a broad attribute dump)."
|
|
8015
|
+
"When present on source events, operationId/attemptId/retryOf/attemptNumber are emitted as bounded agent_inspect.* identity attributes (not a broad attribute dump).",
|
|
8016
|
+
"When direct and nested identity disagree, export prefers direct for non-strict consumers and emits agent_inspect.identity_conflict.* for the nested alternate; this does not certify conflicting identity."
|
|
7730
8017
|
];
|
|
7731
8018
|
const traceId = hexFrom2(`trace:${tree.runId}`, 16);
|
|
7732
8019
|
const includeAttributes = options?.includeAttributes ?? false;
|
|
@@ -7774,11 +8061,16 @@ function exportOtlpJson(tree, options) {
|
|
|
7774
8061
|
if (typeof inp === "number") attrs2.push(intAttr("gen_ai.usage.input_tokens", inp));
|
|
7775
8062
|
if (typeof outp === "number") attrs2.push(intAttr("gen_ai.usage.output_tokens", outp));
|
|
7776
8063
|
}
|
|
7777
|
-
appendStructuralIdentityAttrs(
|
|
8064
|
+
const identityConflicts = appendStructuralIdentityAttrs(
|
|
7778
8065
|
attrs2,
|
|
7779
8066
|
meta && typeof meta === "object" ? meta : void 0,
|
|
7780
8067
|
maxLen
|
|
7781
8068
|
);
|
|
8069
|
+
if (identityConflicts.length > 0) {
|
|
8070
|
+
warnings.push(
|
|
8071
|
+
`Identity representation conflict on event ${ev.eventId}: ${identityConflicts.join(", ")} (direct preferred; nested retained on agent_inspect.identity_conflict.*).`
|
|
8072
|
+
);
|
|
8073
|
+
}
|
|
7782
8074
|
if (includeAttributes && meta && typeof meta === "object") {
|
|
7783
8075
|
const skipKeys = /* @__PURE__ */ new Set([
|
|
7784
8076
|
"tokens",
|