@geminixiang/mikan 1.0.0-beta.52 → 1.0.0-beta.53
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/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +9 -1
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/update-diagnostics.d.ts +14 -0
- package/dist/adapters/slack/update-diagnostics.d.ts.map +1 -0
- package/dist/adapters/slack/update-diagnostics.js +150 -0
- package/dist/adapters/slack/update-diagnostics.js.map +1 -0
- package/dist/main.js +8 -4
- package/dist/main.js.map +1 -1
- package/dist/observability/sentry.d.ts +16 -2
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +95 -1
- package/dist/observability/sentry.js.map +1 -1
- package/dist/observability/types.d.ts +17 -1
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/platform-messages.d.ts +1 -0
- package/dist/platform-messages.d.ts.map +1 -1
- package/dist/platform-messages.js +3 -0
- package/dist/platform-messages.js.map +1 -1
- package/dist/process-lifecycle.d.ts.map +1 -1
- package/dist/process-lifecycle.js +8 -1
- package/dist/process-lifecycle.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +21 -9
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +3 -1
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +2 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +34 -3
- package/dist/tools/subagent.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ const REDACTED = "[REDACTED]";
|
|
|
4
4
|
const REDACTED_PATH = "[REDACTED_PATH]";
|
|
5
5
|
const MAX_STRING_LENGTH = 256;
|
|
6
6
|
const MAX_DEPTH = 4;
|
|
7
|
+
const MAX_FINGERPRINT_CLASS_LENGTH = 80;
|
|
7
8
|
const TRACE_ATTRIBUTION_TTL_MS = 5 * 60 * 1000;
|
|
8
9
|
const SENSITIVE_KEYS = new Set([
|
|
9
10
|
"accesstoken",
|
|
@@ -57,6 +58,9 @@ export function createSentryInitOptions(dsn) {
|
|
|
57
58
|
dsn,
|
|
58
59
|
environment: readEnv("SENTRY_ENVIRONMENT") ?? "production",
|
|
59
60
|
enabled: Boolean(dsn) && readEnv("SENTRY_ENABLED") !== "false",
|
|
61
|
+
// Also keeps gen_ai inputs/outputs off. Do not add a `dataCollection`
|
|
62
|
+
// block here: its mere presence switches the SDK base to all-true, and
|
|
63
|
+
// prompts and completions start shipping unless every key is set false.
|
|
60
64
|
sendDefaultPii: false,
|
|
61
65
|
tracesSampleRate: 1.0,
|
|
62
66
|
includeLocalVariables: false,
|
|
@@ -160,6 +164,10 @@ export function applyRunScope(scope, context) {
|
|
|
160
164
|
scope.setTag(key, value);
|
|
161
165
|
}
|
|
162
166
|
scope.setAttributes(attributes);
|
|
167
|
+
// Agent Monitoring groups gen_ai spans by this id. The session key is the
|
|
168
|
+
// thread-level unit (a shared channel has one conversationId across many
|
|
169
|
+
// threads) and is already emitted as the session_key tag.
|
|
170
|
+
scope.setConversationId(context.sessionKey);
|
|
163
171
|
scope.setUser({
|
|
164
172
|
id: context.userId,
|
|
165
173
|
username: context.userName,
|
|
@@ -198,7 +206,9 @@ export function sanitizeEvent(event, _hint) {
|
|
|
198
206
|
extra: sanitizeValue(event.extra),
|
|
199
207
|
contexts: sanitizeValue(event.contexts),
|
|
200
208
|
request: sanitizeRequest(event.request),
|
|
201
|
-
|
|
209
|
+
// Keep the identity applyRunScope set so Conversations show who sent each
|
|
210
|
+
// message; drop anything else the SDK may have attached (email, IP).
|
|
211
|
+
user: event.user ? { id: event.user.id, username: event.user.username } : undefined,
|
|
202
212
|
server_name: undefined,
|
|
203
213
|
};
|
|
204
214
|
if (sanitized.message) {
|
|
@@ -344,4 +354,88 @@ function sanitizeString(value) {
|
|
|
344
354
|
}
|
|
345
355
|
return sanitized;
|
|
346
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* Subagent outcomes that page. Everything else is a bounded, expected end
|
|
359
|
+
* state the parent model already sees in the tool result: a budget or clock
|
|
360
|
+
* ran out, the caller aborted, or a dependency failed upstream.
|
|
361
|
+
*/
|
|
362
|
+
const UNEXPECTED_SUBAGENT_STATUSES = new Set([
|
|
363
|
+
"failed",
|
|
364
|
+
"invalid_output",
|
|
365
|
+
]);
|
|
366
|
+
/**
|
|
367
|
+
* Record one subagent outcome: a run counter and duration for every status,
|
|
368
|
+
* a lifecycle breadcrumb, and a Sentry error only for statuses in
|
|
369
|
+
* `UNEXPECTED_SUBAGENT_STATUSES`. Fingerprinted on the error's prefix before
|
|
370
|
+
* the first colon so one failure class is one issue regardless of which
|
|
371
|
+
* tool, file, or model message follows it.
|
|
372
|
+
*/
|
|
373
|
+
export function recordSubagentOutcome(report) {
|
|
374
|
+
const attributes = metricAttributes({
|
|
375
|
+
status: report.status,
|
|
376
|
+
profile: report.profile,
|
|
377
|
+
mode: report.mode,
|
|
378
|
+
});
|
|
379
|
+
Sentry.metrics.count("agent.subagent.runs", 1, { attributes });
|
|
380
|
+
if (report.durationMs !== undefined) {
|
|
381
|
+
Sentry.metrics.distribution("agent.subagent.duration", report.durationMs, {
|
|
382
|
+
unit: "millisecond",
|
|
383
|
+
attributes,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
addLifecycleBreadcrumb("agent.subagent.completed", {
|
|
387
|
+
item_id: report.itemId,
|
|
388
|
+
status: report.status,
|
|
389
|
+
profile: report.profile,
|
|
390
|
+
mode: report.mode,
|
|
391
|
+
turns: report.turns,
|
|
392
|
+
tool_calls: report.toolCalls,
|
|
393
|
+
tokens: report.tokens,
|
|
394
|
+
cost_usd: report.costUsd,
|
|
395
|
+
duration_ms: report.durationMs,
|
|
396
|
+
cleanup_pending: report.cleanupPending,
|
|
397
|
+
});
|
|
398
|
+
if (!UNEXPECTED_SUBAGENT_STATUSES.has(report.status))
|
|
399
|
+
return undefined;
|
|
400
|
+
const errorClass = sanitizeString((report.error ?? report.status).split(":")[0].trim()).slice(0, MAX_FINGERPRINT_CLASS_LENGTH);
|
|
401
|
+
return reportUserFacingError(new Error(`Subagent ${report.status}: ${report.error ?? "no error detail"}`), {
|
|
402
|
+
domain: "subagent",
|
|
403
|
+
surface: "subagent_tool",
|
|
404
|
+
operation: "run",
|
|
405
|
+
severity: "error",
|
|
406
|
+
toolName: "subagent",
|
|
407
|
+
fingerprint: ["subagent", report.status, errorClass],
|
|
408
|
+
tags: {
|
|
409
|
+
subagent_status: report.status,
|
|
410
|
+
subagent_profile: report.profile,
|
|
411
|
+
subagent_mode: report.mode,
|
|
412
|
+
cleanup_pending: report.cleanupPending,
|
|
413
|
+
},
|
|
414
|
+
context: {
|
|
415
|
+
itemId: report.itemId,
|
|
416
|
+
error: report.error,
|
|
417
|
+
turns: report.turns,
|
|
418
|
+
toolCalls: report.toolCalls,
|
|
419
|
+
tokens: report.tokens,
|
|
420
|
+
costUsd: report.costUsd,
|
|
421
|
+
durationMs: report.durationMs,
|
|
422
|
+
},
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* A subagent that never started: unknown profile, ungranted tool, or a
|
|
427
|
+
* harness rejection. The throw still reaches the parent model as a tool
|
|
428
|
+
* error; this only makes sure it also reaches Sentry.
|
|
429
|
+
*/
|
|
430
|
+
export function reportSubagentLaunchError(error, report) {
|
|
431
|
+
return reportUserFacingError(error, {
|
|
432
|
+
domain: "subagent",
|
|
433
|
+
surface: "subagent_tool",
|
|
434
|
+
operation: "launch",
|
|
435
|
+
severity: "error",
|
|
436
|
+
toolName: "subagent",
|
|
437
|
+
tags: { subagent_profile: report.profile, subagent_mode: report.mode },
|
|
438
|
+
context: { itemId: report.itemId },
|
|
439
|
+
});
|
|
440
|
+
}
|
|
347
441
|
//# sourceMappingURL=sentry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentry.js","sourceRoot":"","sources":["../../src/observability/sentry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Breadcrumb, ErrorEvent, Event, EventHint, Scope } from \"@sentry/node\";\nimport * as Sentry from \"@sentry/node\";\nimport { readEnv } from \"../env-manifest.js\";\n\nconst REDACTED = \"[REDACTED]\";\nconst REDACTED_PATH = \"[REDACTED_PATH]\";\nconst MAX_STRING_LENGTH = 256;\nconst MAX_DEPTH = 4;\nconst TRACE_ATTRIBUTION_TTL_MS = 5 * 60 * 1000;\n\nconst SENSITIVE_KEYS = new Set([\n \"accesstoken\",\n \"apikey\",\n \"args\",\n \"attachment\",\n \"attachments\",\n \"authorization\",\n \"body\",\n \"clientsecret\",\n \"code\",\n \"content\",\n \"contents\",\n \"cookie\",\n \"cookies\",\n \"credential\",\n \"filepath\",\n \"headers\",\n \"image\",\n \"imageattachments\",\n \"images\",\n \"localpath\",\n \"messages\",\n \"newusermessage\",\n \"password\",\n \"path\",\n \"paths\",\n \"prompt\",\n \"refreshtoken\",\n \"response\",\n \"result\",\n \"secret\",\n \"systemprompt\",\n \"text\",\n \"thinking\",\n \"token\",\n \"url\",\n \"uri\",\n \"workspacepath\",\n]);\n\nconst ABSOLUTE_PATH_PATTERN =\n /(?:\\/Users\\/[^\\s\"'`]+|\\/workspace\\/[^\\s\"'`]+|\\/tmp\\/[^\\s\"'`]+|\\/var\\/folders\\/[^\\s\"'`]+|[A-Za-z]:\\\\[^\\s\"'`]+)/;\nconst TOKEN_PATTERNS = [\n /\\bsk-[A-Za-z0-9_-]{12,}\\b/,\n /\\bxox[a-z]-[A-Za-z0-9-]{10,}\\b/,\n /\\bAIza[0-9A-Za-z_-]{20,}\\b/,\n /\\bgh[pousr]_[A-Za-z0-9]{20,}\\b/,\n];\n\nexport type {\n ReportUserFacingErrorOptions,\n SentryAttributionAttributes,\n SentryRunScopeContext,\n SentrySpanPayload,\n SentryTransactionPayload,\n} from \"./types.js\";\nimport type {\n ReportUserFacingErrorOptions,\n SentryAttributionAttributes,\n SentryRunScopeContext,\n SentrySpanPayload,\n SentryTransactionPayload,\n} from \"./types.js\";\n\ntype TraceAttributionEntry = {\n attributes: SentryAttributionAttributes;\n expiresAt: number;\n};\n\nconst traceAttribution = new Map<string, TraceAttributionEntry>();\n\nexport function createSentryInitOptions(dsn?: string) {\n return {\n dsn,\n environment: readEnv(\"SENTRY_ENVIRONMENT\") ?? \"production\",\n enabled: Boolean(dsn) && readEnv(\"SENTRY_ENABLED\") !== \"false\",\n sendDefaultPii: false,\n tracesSampleRate: 1.0,\n includeLocalVariables: false,\n enableLogs: true,\n // Sentry's OpenAI APIPromise wrapper leaks a second rejection when an\n // in-flight request is aborted (for example by an agent budget limit).\n // Keep all other default integrations until the upstream wrapper handles\n // both withResponse() branches without an unhandled rejection.\n integrations(defaultIntegrations: ReturnType<typeof Sentry.getDefaultIntegrations>) {\n return defaultIntegrations.filter((integration) => integration.name !== \"OpenAI\");\n },\n beforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null {\n return sanitizeEvent(event, hint);\n },\n beforeSendSpan(span: SentrySpanPayload): SentrySpanPayload {\n return applySpanAttribution(span);\n },\n beforeSendTransaction(event: SentryTransactionPayload): SentryTransactionPayload | null {\n return sanitizeTransactionEvent(event);\n },\n beforeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {\n return sanitizeBreadcrumb(breadcrumb);\n },\n };\n}\n\nexport function reportUserFacingError(\n error: unknown,\n options: ReportUserFacingErrorOptions,\n): string | undefined {\n if (options.expected) return undefined;\n\n const exception = error instanceof Error ? error : new Error(String(error));\n return Sentry.withScope((scope) => {\n scope.setLevel(options.severity ?? \"error\");\n scope.setTag(\"user_facing\", \"true\");\n scope.setTag(\"expected\", \"false\");\n scope.setTag(\"error_domain\", options.domain);\n scope.setTag(\"error_surface\", options.surface);\n scope.setTag(\"operation\", options.operation);\n setOptionalTag(scope, \"platform\", options.platform);\n setOptionalTag(scope, \"provider\", options.provider);\n setOptionalTag(scope, \"model\", options.model);\n setOptionalTag(scope, \"tool\", options.toolName);\n setOptionalTag(scope, \"stop_reason\", options.stopReason);\n for (const [key, value] of Object.entries(options.tags ?? {})) {\n if (value !== undefined) scope.setTag(key, String(value));\n }\n if (options.fingerprint) scope.setFingerprint(options.fingerprint);\n scope.setContext(\"user_facing_error\", {\n domain: options.domain,\n surface: options.surface,\n operation: options.operation,\n severity: options.severity ?? \"error\",\n platform: options.platform,\n provider: options.provider,\n model: options.model,\n toolName: options.toolName,\n stopReason: options.stopReason,\n ...(sanitizeValue(options.context ?? {}) as Record<string, unknown>),\n });\n return Sentry.captureException(exception);\n });\n}\n\nfunction setOptionalTag(scope: Scope, key: string, value: string | undefined): void {\n if (value !== undefined) scope.setTag(key, value);\n}\n\nexport function createRunAttributionAttributes(\n context: SentryRunScopeContext,\n): SentryAttributionAttributes {\n return metricAttributes({\n conversation_id: context.conversationId,\n channel_id: context.conversationId,\n session_key: context.sessionKey,\n message_id: context.messageId,\n platform: context.platform,\n user_id: context.userId,\n thread_ts: context.threadTs,\n provider: context.provider,\n model: context.model,\n });\n}\n\nexport function registerTraceAttribution(\n span: { setAttributes(attributes: SentryAttributionAttributes): unknown },\n attributes: SentryAttributionAttributes,\n): void {\n span.setAttributes(attributes);\n const traceId = Sentry.spanToJSON(span as Parameters<typeof Sentry.spanToJSON>[0]).trace_id;\n if (!traceId) return;\n\n const now = Date.now();\n pruneExpiredTraceAttributions(now);\n traceAttribution.set(traceId, {\n attributes: { ...traceAttribution.get(traceId)?.attributes, ...attributes },\n expiresAt: now + TRACE_ATTRIBUTION_TTL_MS,\n });\n}\n\nexport function updateActiveSpanAttribution(attributes: SentryAttributionAttributes): void {\n const span = Sentry.getActiveSpan();\n if (!span) return;\n registerTraceAttribution(span, attributes);\n}\n\nexport function applyRunScope(scope: Scope, context: SentryRunScopeContext): void {\n const attributes = createRunAttributionAttributes(context);\n\n for (const [key, value] of Object.entries(attributes)) {\n scope.setTag(key, value);\n }\n scope.setAttributes(attributes);\n scope.setUser({\n id: context.userId,\n username: context.userName,\n });\n scope.setContext(\"agent_run\", {\n conversationId: context.conversationId,\n channelId: context.conversationId,\n sessionKey: context.sessionKey,\n messageId: context.messageId,\n threadTs: context.threadTs,\n platform: context.platform,\n provider: context.provider,\n model: context.model,\n });\n}\n\nexport function metricAttributes(\n attributes: Record<string, string | number | boolean | undefined>,\n): Record<string, string | number | boolean> {\n return Object.fromEntries(\n Object.entries(attributes).filter((entry): entry is [string, string | number | boolean] => {\n const [, value] = entry;\n return value !== undefined;\n }),\n );\n}\n\nexport function addLifecycleBreadcrumb(\n message: string,\n data?: Record<string, string | number | boolean | undefined>,\n): void {\n Sentry.addBreadcrumb({\n category: \"agent.lifecycle\",\n message,\n level: \"info\",\n data: data ? metricAttributes(data) : undefined,\n });\n}\n\nexport function sanitizeEvent<T extends Event>(event: T, _hint?: EventHint): T | null {\n const sanitized: T = {\n ...event,\n breadcrumbs: event.breadcrumbs\n ?.map((breadcrumb) => sanitizeBreadcrumb(breadcrumb))\n .filter((breadcrumb): breadcrumb is Breadcrumb => breadcrumb !== null),\n extra: sanitizeValue(event.extra) as T[\"extra\"],\n contexts: sanitizeValue(event.contexts) as T[\"contexts\"],\n request: sanitizeRequest(event.request),\n user: undefined,\n server_name: undefined,\n };\n\n if (sanitized.message) {\n sanitized.message = sanitizeString(sanitized.message);\n }\n\n if (sanitized.logentry) {\n sanitized.logentry = {\n ...sanitized.logentry,\n message: sanitized.logentry.message ? sanitizeString(sanitized.logentry.message) : undefined,\n };\n }\n\n if (sanitized.exception?.values) {\n sanitized.exception.values = sanitized.exception.values.map((value) => ({\n ...value,\n value: value.value ? sanitizeString(value.value) : value.value,\n stacktrace: value.stacktrace\n ? {\n ...value.stacktrace,\n frames: value.stacktrace.frames?.map((frame) => ({\n ...frame,\n filename: frame.filename ? sanitizeString(frame.filename) : frame.filename,\n abs_path: frame.abs_path ? sanitizeString(frame.abs_path) : frame.abs_path,\n vars: undefined,\n })),\n }\n : value.stacktrace,\n }));\n }\n\n return sanitized;\n}\n\nexport function applySpanAttribution<T extends SentrySpanPayload>(span: T): T {\n const attributes = getTraceAttribution(span.trace_id);\n if (!attributes) return span;\n return {\n ...span,\n data: {\n ...span.data,\n ...attributes,\n },\n };\n}\n\nfunction sanitizeTransactionEvent<T extends SentryTransactionPayload>(event: T): T | null {\n const sanitized = sanitizeEvent(event);\n if (!sanitized) return null;\n\n const traceContext = sanitized.contexts?.trace;\n const traceId = traceContext?.trace_id;\n if (typeof traceId !== \"string\") return sanitized;\n const attributes = getTraceAttribution(traceId);\n if (!attributes) return sanitized;\n\n const entries = (sanitized as { entries?: Array<{ type?: string; data?: unknown }> }).entries;\n for (const entry of entries ?? []) {\n if (entry.type !== \"spans\" || !Array.isArray(entry.data)) continue;\n entry.data = entry.data.map((span: SentrySpanPayload) => applySpanAttribution(span));\n }\n\n traceAttribution.delete(traceId);\n return sanitized;\n}\n\nexport function sanitizeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {\n if (breadcrumb.category === \"console\") {\n return null;\n }\n\n return {\n ...breadcrumb,\n message: breadcrumb.message ? sanitizeString(breadcrumb.message) : breadcrumb.message,\n data: sanitizeValue(breadcrumb.data) as Breadcrumb[\"data\"],\n };\n}\n\nexport function sanitizeValue(value: unknown, key?: string, depth = 0): unknown {\n if (value == null) return value;\n if (depth > MAX_DEPTH) return \"[Truncated]\";\n\n if (isSensitiveKey(key)) {\n return summarizeValue(value, key);\n }\n\n if (typeof value === \"string\") {\n return sanitizeString(value);\n }\n\n if (Array.isArray(value)) {\n return value.slice(0, 20).map((entry) => sanitizeValue(entry, key, depth + 1));\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>).map(\n ([entryKey, entryValue]) => [entryKey, sanitizeValue(entryValue, entryKey, depth + 1)],\n );\n return Object.fromEntries(entries);\n }\n\n return value;\n}\n\nfunction sanitizeRequest(request: Event[\"request\"]): Event[\"request\"] {\n if (!request) return request;\n\n return {\n ...request,\n data: request.data ? summarizeValue(request.data, \"body\") : undefined,\n headers: undefined,\n cookies: undefined,\n };\n}\n\nfunction getTraceAttribution(traceId: string): SentryAttributionAttributes | undefined {\n const entry = traceAttribution.get(traceId);\n if (!entry) return undefined;\n if (entry.expiresAt > Date.now()) return entry.attributes;\n traceAttribution.delete(traceId);\n return undefined;\n}\n\nfunction pruneExpiredTraceAttributions(now: number): void {\n for (const [traceId, entry] of traceAttribution) {\n if (entry.expiresAt <= now) traceAttribution.delete(traceId);\n }\n}\n\nfunction isSensitiveKey(key?: string): boolean {\n if (!key) return false;\n return SENSITIVE_KEYS.has(key.toLowerCase().replace(/[^a-z0-9]/g, \"\"));\n}\n\nfunction summarizeValue(value: unknown, key?: string): string {\n const label = key ?? \"field\";\n if (typeof value === \"string\") {\n return `[Redacted ${label}; length=${value.length}]`;\n }\n if (Array.isArray(value)) {\n return `[Redacted ${label}; items=${value.length}]`;\n }\n if (value && typeof value === \"object\") {\n return `[Redacted ${label}; keys=${Object.keys(value as Record<string, unknown>).length}]`;\n }\n return `[Redacted ${label}]`;\n}\n\nfunction sanitizeString(value: string): string {\n let sanitized = value.replace(new RegExp(ABSOLUTE_PATH_PATTERN, \"g\"), REDACTED_PATH);\n for (const pattern of TOKEN_PATTERNS) {\n sanitized = sanitized.replace(new RegExp(pattern, \"g\"), REDACTED);\n }\n if (sanitized.length > MAX_STRING_LENGTH) {\n return `${sanitized.slice(0, MAX_STRING_LENGTH)}… [truncated ${sanitized.length - MAX_STRING_LENGTH} chars]`;\n }\n return sanitized;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sentry.js","sourceRoot":"","sources":["../../src/observability/sentry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Breadcrumb, ErrorEvent, Event, EventHint, Scope } from \"@sentry/node\";\nimport * as Sentry from \"@sentry/node\";\nimport { readEnv } from \"../env-manifest.js\";\n\nconst REDACTED = \"[REDACTED]\";\nconst REDACTED_PATH = \"[REDACTED_PATH]\";\nconst MAX_STRING_LENGTH = 256;\nconst MAX_DEPTH = 4;\nconst MAX_FINGERPRINT_CLASS_LENGTH = 80;\nconst TRACE_ATTRIBUTION_TTL_MS = 5 * 60 * 1000;\n\nconst SENSITIVE_KEYS = new Set([\n \"accesstoken\",\n \"apikey\",\n \"args\",\n \"attachment\",\n \"attachments\",\n \"authorization\",\n \"body\",\n \"clientsecret\",\n \"code\",\n \"content\",\n \"contents\",\n \"cookie\",\n \"cookies\",\n \"credential\",\n \"filepath\",\n \"headers\",\n \"image\",\n \"imageattachments\",\n \"images\",\n \"localpath\",\n \"messages\",\n \"newusermessage\",\n \"password\",\n \"path\",\n \"paths\",\n \"prompt\",\n \"refreshtoken\",\n \"response\",\n \"result\",\n \"secret\",\n \"systemprompt\",\n \"text\",\n \"thinking\",\n \"token\",\n \"url\",\n \"uri\",\n \"workspacepath\",\n]);\n\nconst ABSOLUTE_PATH_PATTERN =\n /(?:\\/Users\\/[^\\s\"'`]+|\\/workspace\\/[^\\s\"'`]+|\\/tmp\\/[^\\s\"'`]+|\\/var\\/folders\\/[^\\s\"'`]+|[A-Za-z]:\\\\[^\\s\"'`]+)/;\nconst TOKEN_PATTERNS = [\n /\\bsk-[A-Za-z0-9_-]{12,}\\b/,\n /\\bxox[a-z]-[A-Za-z0-9-]{10,}\\b/,\n /\\bAIza[0-9A-Za-z_-]{20,}\\b/,\n /\\bgh[pousr]_[A-Za-z0-9]{20,}\\b/,\n];\n\nexport type {\n ReportUserFacingErrorOptions,\n SentryAttributionAttributes,\n SubagentOutcomeReport,\n SentryRunScopeContext,\n SentrySpanPayload,\n SentryTransactionPayload,\n} from \"./types.js\";\nimport type {\n ReportUserFacingErrorOptions,\n SentryAttributionAttributes,\n SubagentOutcomeReport,\n SubagentOutcomeStatus,\n SentryRunScopeContext,\n SentrySpanPayload,\n SentryTransactionPayload,\n} from \"./types.js\";\n\ntype TraceAttributionEntry = {\n attributes: SentryAttributionAttributes;\n expiresAt: number;\n};\n\nconst traceAttribution = new Map<string, TraceAttributionEntry>();\n\nexport function createSentryInitOptions(dsn?: string) {\n return {\n dsn,\n environment: readEnv(\"SENTRY_ENVIRONMENT\") ?? \"production\",\n enabled: Boolean(dsn) && readEnv(\"SENTRY_ENABLED\") !== \"false\",\n // Also keeps gen_ai inputs/outputs off. Do not add a `dataCollection`\n // block here: its mere presence switches the SDK base to all-true, and\n // prompts and completions start shipping unless every key is set false.\n sendDefaultPii: false,\n tracesSampleRate: 1.0,\n includeLocalVariables: false,\n enableLogs: true,\n // Sentry's OpenAI APIPromise wrapper leaks a second rejection when an\n // in-flight request is aborted (for example by an agent budget limit).\n // Keep all other default integrations until the upstream wrapper handles\n // both withResponse() branches without an unhandled rejection.\n integrations(defaultIntegrations: ReturnType<typeof Sentry.getDefaultIntegrations>) {\n return defaultIntegrations.filter((integration) => integration.name !== \"OpenAI\");\n },\n beforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null {\n return sanitizeEvent(event, hint);\n },\n beforeSendSpan(span: SentrySpanPayload): SentrySpanPayload {\n return applySpanAttribution(span);\n },\n beforeSendTransaction(event: SentryTransactionPayload): SentryTransactionPayload | null {\n return sanitizeTransactionEvent(event);\n },\n beforeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {\n return sanitizeBreadcrumb(breadcrumb);\n },\n };\n}\n\nexport function reportUserFacingError(\n error: unknown,\n options: ReportUserFacingErrorOptions,\n): string | undefined {\n if (options.expected) return undefined;\n\n const exception = error instanceof Error ? error : new Error(String(error));\n return Sentry.withScope((scope) => {\n scope.setLevel(options.severity ?? \"error\");\n scope.setTag(\"user_facing\", \"true\");\n scope.setTag(\"expected\", \"false\");\n scope.setTag(\"error_domain\", options.domain);\n scope.setTag(\"error_surface\", options.surface);\n scope.setTag(\"operation\", options.operation);\n setOptionalTag(scope, \"platform\", options.platform);\n setOptionalTag(scope, \"provider\", options.provider);\n setOptionalTag(scope, \"model\", options.model);\n setOptionalTag(scope, \"tool\", options.toolName);\n setOptionalTag(scope, \"stop_reason\", options.stopReason);\n for (const [key, value] of Object.entries(options.tags ?? {})) {\n if (value !== undefined) scope.setTag(key, String(value));\n }\n if (options.fingerprint) scope.setFingerprint(options.fingerprint);\n scope.setContext(\"user_facing_error\", {\n domain: options.domain,\n surface: options.surface,\n operation: options.operation,\n severity: options.severity ?? \"error\",\n platform: options.platform,\n provider: options.provider,\n model: options.model,\n toolName: options.toolName,\n stopReason: options.stopReason,\n ...(sanitizeValue(options.context ?? {}) as Record<string, unknown>),\n });\n return Sentry.captureException(exception);\n });\n}\n\nfunction setOptionalTag(scope: Scope, key: string, value: string | undefined): void {\n if (value !== undefined) scope.setTag(key, value);\n}\n\nexport function createRunAttributionAttributes(\n context: SentryRunScopeContext,\n): SentryAttributionAttributes {\n return metricAttributes({\n conversation_id: context.conversationId,\n channel_id: context.conversationId,\n session_key: context.sessionKey,\n message_id: context.messageId,\n platform: context.platform,\n user_id: context.userId,\n thread_ts: context.threadTs,\n provider: context.provider,\n model: context.model,\n });\n}\n\nexport function registerTraceAttribution(\n span: { setAttributes(attributes: SentryAttributionAttributes): unknown },\n attributes: SentryAttributionAttributes,\n): void {\n span.setAttributes(attributes);\n const traceId = Sentry.spanToJSON(span as Parameters<typeof Sentry.spanToJSON>[0]).trace_id;\n if (!traceId) return;\n\n const now = Date.now();\n pruneExpiredTraceAttributions(now);\n traceAttribution.set(traceId, {\n attributes: { ...traceAttribution.get(traceId)?.attributes, ...attributes },\n expiresAt: now + TRACE_ATTRIBUTION_TTL_MS,\n });\n}\n\nexport function updateActiveSpanAttribution(attributes: SentryAttributionAttributes): void {\n const span = Sentry.getActiveSpan();\n if (!span) return;\n registerTraceAttribution(span, attributes);\n}\n\nexport function applyRunScope(scope: Scope, context: SentryRunScopeContext): void {\n const attributes = createRunAttributionAttributes(context);\n\n for (const [key, value] of Object.entries(attributes)) {\n scope.setTag(key, value);\n }\n scope.setAttributes(attributes);\n // Agent Monitoring groups gen_ai spans by this id. The session key is the\n // thread-level unit (a shared channel has one conversationId across many\n // threads) and is already emitted as the session_key tag.\n scope.setConversationId(context.sessionKey);\n scope.setUser({\n id: context.userId,\n username: context.userName,\n });\n scope.setContext(\"agent_run\", {\n conversationId: context.conversationId,\n channelId: context.conversationId,\n sessionKey: context.sessionKey,\n messageId: context.messageId,\n threadTs: context.threadTs,\n platform: context.platform,\n provider: context.provider,\n model: context.model,\n });\n}\n\nexport function metricAttributes(\n attributes: Record<string, string | number | boolean | undefined>,\n): Record<string, string | number | boolean> {\n return Object.fromEntries(\n Object.entries(attributes).filter((entry): entry is [string, string | number | boolean] => {\n const [, value] = entry;\n return value !== undefined;\n }),\n );\n}\n\nexport function addLifecycleBreadcrumb(\n message: string,\n data?: Record<string, string | number | boolean | undefined>,\n): void {\n Sentry.addBreadcrumb({\n category: \"agent.lifecycle\",\n message,\n level: \"info\",\n data: data ? metricAttributes(data) : undefined,\n });\n}\n\nexport function sanitizeEvent<T extends Event>(event: T, _hint?: EventHint): T | null {\n const sanitized: T = {\n ...event,\n breadcrumbs: event.breadcrumbs\n ?.map((breadcrumb) => sanitizeBreadcrumb(breadcrumb))\n .filter((breadcrumb): breadcrumb is Breadcrumb => breadcrumb !== null),\n extra: sanitizeValue(event.extra) as T[\"extra\"],\n contexts: sanitizeValue(event.contexts) as T[\"contexts\"],\n request: sanitizeRequest(event.request),\n // Keep the identity applyRunScope set so Conversations show who sent each\n // message; drop anything else the SDK may have attached (email, IP).\n user: event.user ? { id: event.user.id, username: event.user.username } : undefined,\n server_name: undefined,\n };\n\n if (sanitized.message) {\n sanitized.message = sanitizeString(sanitized.message);\n }\n\n if (sanitized.logentry) {\n sanitized.logentry = {\n ...sanitized.logentry,\n message: sanitized.logentry.message ? sanitizeString(sanitized.logentry.message) : undefined,\n };\n }\n\n if (sanitized.exception?.values) {\n sanitized.exception.values = sanitized.exception.values.map((value) => ({\n ...value,\n value: value.value ? sanitizeString(value.value) : value.value,\n stacktrace: value.stacktrace\n ? {\n ...value.stacktrace,\n frames: value.stacktrace.frames?.map((frame) => ({\n ...frame,\n filename: frame.filename ? sanitizeString(frame.filename) : frame.filename,\n abs_path: frame.abs_path ? sanitizeString(frame.abs_path) : frame.abs_path,\n vars: undefined,\n })),\n }\n : value.stacktrace,\n }));\n }\n\n return sanitized;\n}\n\nexport function applySpanAttribution<T extends SentrySpanPayload>(span: T): T {\n const attributes = getTraceAttribution(span.trace_id);\n if (!attributes) return span;\n return {\n ...span,\n data: {\n ...span.data,\n ...attributes,\n },\n };\n}\n\nfunction sanitizeTransactionEvent<T extends SentryTransactionPayload>(event: T): T | null {\n const sanitized = sanitizeEvent(event);\n if (!sanitized) return null;\n\n const traceContext = sanitized.contexts?.trace;\n const traceId = traceContext?.trace_id;\n if (typeof traceId !== \"string\") return sanitized;\n const attributes = getTraceAttribution(traceId);\n if (!attributes) return sanitized;\n\n const entries = (sanitized as { entries?: Array<{ type?: string; data?: unknown }> }).entries;\n for (const entry of entries ?? []) {\n if (entry.type !== \"spans\" || !Array.isArray(entry.data)) continue;\n entry.data = entry.data.map((span: SentrySpanPayload) => applySpanAttribution(span));\n }\n\n traceAttribution.delete(traceId);\n return sanitized;\n}\n\nexport function sanitizeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {\n if (breadcrumb.category === \"console\") {\n return null;\n }\n\n return {\n ...breadcrumb,\n message: breadcrumb.message ? sanitizeString(breadcrumb.message) : breadcrumb.message,\n data: sanitizeValue(breadcrumb.data) as Breadcrumb[\"data\"],\n };\n}\n\nexport function sanitizeValue(value: unknown, key?: string, depth = 0): unknown {\n if (value == null) return value;\n if (depth > MAX_DEPTH) return \"[Truncated]\";\n\n if (isSensitiveKey(key)) {\n return summarizeValue(value, key);\n }\n\n if (typeof value === \"string\") {\n return sanitizeString(value);\n }\n\n if (Array.isArray(value)) {\n return value.slice(0, 20).map((entry) => sanitizeValue(entry, key, depth + 1));\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>).map(\n ([entryKey, entryValue]) => [entryKey, sanitizeValue(entryValue, entryKey, depth + 1)],\n );\n return Object.fromEntries(entries);\n }\n\n return value;\n}\n\nfunction sanitizeRequest(request: Event[\"request\"]): Event[\"request\"] {\n if (!request) return request;\n\n return {\n ...request,\n data: request.data ? summarizeValue(request.data, \"body\") : undefined,\n headers: undefined,\n cookies: undefined,\n };\n}\n\nfunction getTraceAttribution(traceId: string): SentryAttributionAttributes | undefined {\n const entry = traceAttribution.get(traceId);\n if (!entry) return undefined;\n if (entry.expiresAt > Date.now()) return entry.attributes;\n traceAttribution.delete(traceId);\n return undefined;\n}\n\nfunction pruneExpiredTraceAttributions(now: number): void {\n for (const [traceId, entry] of traceAttribution) {\n if (entry.expiresAt <= now) traceAttribution.delete(traceId);\n }\n}\n\nfunction isSensitiveKey(key?: string): boolean {\n if (!key) return false;\n return SENSITIVE_KEYS.has(key.toLowerCase().replace(/[^a-z0-9]/g, \"\"));\n}\n\nfunction summarizeValue(value: unknown, key?: string): string {\n const label = key ?? \"field\";\n if (typeof value === \"string\") {\n return `[Redacted ${label}; length=${value.length}]`;\n }\n if (Array.isArray(value)) {\n return `[Redacted ${label}; items=${value.length}]`;\n }\n if (value && typeof value === \"object\") {\n return `[Redacted ${label}; keys=${Object.keys(value as Record<string, unknown>).length}]`;\n }\n return `[Redacted ${label}]`;\n}\n\nfunction sanitizeString(value: string): string {\n let sanitized = value.replace(new RegExp(ABSOLUTE_PATH_PATTERN, \"g\"), REDACTED_PATH);\n for (const pattern of TOKEN_PATTERNS) {\n sanitized = sanitized.replace(new RegExp(pattern, \"g\"), REDACTED);\n }\n if (sanitized.length > MAX_STRING_LENGTH) {\n return `${sanitized.slice(0, MAX_STRING_LENGTH)}… [truncated ${sanitized.length - MAX_STRING_LENGTH} chars]`;\n }\n return sanitized;\n}\n\n/**\n * Subagent outcomes that page. Everything else is a bounded, expected end\n * state the parent model already sees in the tool result: a budget or clock\n * ran out, the caller aborted, or a dependency failed upstream.\n */\nconst UNEXPECTED_SUBAGENT_STATUSES: ReadonlySet<SubagentOutcomeStatus> = new Set([\n \"failed\",\n \"invalid_output\",\n]);\n\n/**\n * Record one subagent outcome: a run counter and duration for every status,\n * a lifecycle breadcrumb, and a Sentry error only for statuses in\n * `UNEXPECTED_SUBAGENT_STATUSES`. Fingerprinted on the error's prefix before\n * the first colon so one failure class is one issue regardless of which\n * tool, file, or model message follows it.\n */\nexport function recordSubagentOutcome(report: SubagentOutcomeReport): string | undefined {\n const attributes = metricAttributes({\n status: report.status,\n profile: report.profile,\n mode: report.mode,\n });\n Sentry.metrics.count(\"agent.subagent.runs\", 1, { attributes });\n if (report.durationMs !== undefined) {\n Sentry.metrics.distribution(\"agent.subagent.duration\", report.durationMs, {\n unit: \"millisecond\",\n attributes,\n });\n }\n addLifecycleBreadcrumb(\"agent.subagent.completed\", {\n item_id: report.itemId,\n status: report.status,\n profile: report.profile,\n mode: report.mode,\n turns: report.turns,\n tool_calls: report.toolCalls,\n tokens: report.tokens,\n cost_usd: report.costUsd,\n duration_ms: report.durationMs,\n cleanup_pending: report.cleanupPending,\n });\n if (!UNEXPECTED_SUBAGENT_STATUSES.has(report.status)) return undefined;\n\n const errorClass = sanitizeString((report.error ?? report.status).split(\":\")[0]!.trim()).slice(\n 0,\n MAX_FINGERPRINT_CLASS_LENGTH,\n );\n return reportUserFacingError(\n new Error(`Subagent ${report.status}: ${report.error ?? \"no error detail\"}`),\n {\n domain: \"subagent\",\n surface: \"subagent_tool\",\n operation: \"run\",\n severity: \"error\",\n toolName: \"subagent\",\n fingerprint: [\"subagent\", report.status, errorClass],\n tags: {\n subagent_status: report.status,\n subagent_profile: report.profile,\n subagent_mode: report.mode,\n cleanup_pending: report.cleanupPending,\n },\n context: {\n itemId: report.itemId,\n error: report.error,\n turns: report.turns,\n toolCalls: report.toolCalls,\n tokens: report.tokens,\n costUsd: report.costUsd,\n durationMs: report.durationMs,\n },\n },\n );\n}\n\n/**\n * A subagent that never started: unknown profile, ungranted tool, or a\n * harness rejection. The throw still reaches the parent model as a tool\n * error; this only makes sure it also reaches Sentry.\n */\nexport function reportSubagentLaunchError(\n error: unknown,\n report: Pick<SubagentOutcomeReport, \"itemId\" | \"mode\" | \"profile\">,\n): string | undefined {\n return reportUserFacingError(error, {\n domain: \"subagent\",\n surface: \"subagent_tool\",\n operation: \"launch\",\n severity: \"error\",\n toolName: \"subagent\",\n tags: { subagent_profile: report.profile, subagent_mode: report.mode },\n context: { itemId: report.itemId },\n });\n}\n"]}
|
|
@@ -26,7 +26,7 @@ export interface SentryTransactionPayload extends Event {
|
|
|
26
26
|
data?: unknown;
|
|
27
27
|
}>;
|
|
28
28
|
}
|
|
29
|
-
type UserFacingErrorDomain = "llm" | "chat_platform" | "mikan" | "sandbox" | "login" | "events" | "session_view";
|
|
29
|
+
type UserFacingErrorDomain = "llm" | "chat_platform" | "mikan" | "sandbox" | "login" | "events" | "session_view" | "subagent";
|
|
30
30
|
type UserFacingErrorSeverity = "warning" | "error" | "fatal";
|
|
31
31
|
export interface ReportUserFacingErrorOptions {
|
|
32
32
|
domain: UserFacingErrorDomain;
|
|
@@ -43,5 +43,21 @@ export interface ReportUserFacingErrorOptions {
|
|
|
43
43
|
tags?: Record<string, SentryPrimitive | undefined>;
|
|
44
44
|
context?: Record<string, unknown>;
|
|
45
45
|
}
|
|
46
|
+
/** Terminal states of one subagent run as seen by the parent tool. */
|
|
47
|
+
export type SubagentOutcomeStatus = "completed" | "failed" | "cancelled" | "timeout" | "budget_exceeded" | "invalid_output" | "skipped";
|
|
48
|
+
/** Metrics-only view of a subagent outcome; never carries task text or labels. */
|
|
49
|
+
export interface SubagentOutcomeReport {
|
|
50
|
+
itemId: string;
|
|
51
|
+
mode: "single" | "parallel" | "dag";
|
|
52
|
+
status: SubagentOutcomeStatus;
|
|
53
|
+
profile?: string;
|
|
54
|
+
error?: string;
|
|
55
|
+
turns?: number;
|
|
56
|
+
toolCalls?: number;
|
|
57
|
+
tokens?: number;
|
|
58
|
+
costUsd?: number;
|
|
59
|
+
durationMs?: number;
|
|
60
|
+
cleanupPending?: boolean;
|
|
61
|
+
}
|
|
46
62
|
export {};
|
|
47
63
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/observability/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,KAAK,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AACjD,KAAK,wBAAwB,GACzB,eAAe,GACf,KAAK,CAAC,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC,GAChC,KAAK,CAAC,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC,GAChC,KAAK,CAAC,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;AAEtC,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,2BAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE1E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,wBAAyB,SAAQ,KAAK;IACrD,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,KAAK,qBAAqB,GACtB,KAAK,GACL,eAAe,GACf,OAAO,GACP,SAAS,GACT,OAAO,GACP,QAAQ,GACR,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/observability/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/observability/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Event } from \"@sentry/node\";\n\ntype SentryPrimitive = string | number | boolean;\ntype SentrySpanAttributeValue =\n | SentryPrimitive\n | Array<null | undefined | string>\n | Array<null | undefined | number>\n | Array<null | undefined | boolean>;\n\nexport interface SentryRunScopeContext {\n conversationId: string;\n sessionKey: string;\n messageId: string;\n platform: string;\n userId: string;\n userName?: string;\n threadTs?: string;\n provider?: string;\n model?: string;\n}\n\nexport type SentryAttributionAttributes = Record<string, SentryPrimitive>;\n\nexport interface SentrySpanPayload {\n trace_id: string;\n span_id: string;\n start_timestamp: number;\n data: Record<string, SentrySpanAttributeValue | undefined>;\n}\n\nexport interface SentryTransactionPayload extends Event {\n type: \"transaction\";\n entries?: Array<{ type?: string; data?: unknown }>;\n}\n\ntype UserFacingErrorDomain =\n | \"llm\"\n | \"chat_platform\"\n | \"mikan\"\n | \"sandbox\"\n | \"login\"\n | \"events\"\n | \"session_view\";\n\ntype UserFacingErrorSeverity = \"warning\" | \"error\" | \"fatal\";\n\nexport interface ReportUserFacingErrorOptions {\n domain: UserFacingErrorDomain;\n surface: string;\n operation: string;\n severity?: UserFacingErrorSeverity;\n platform?: string;\n provider?: string;\n model?: string;\n toolName?: string;\n stopReason?: string;\n expected?: boolean;\n fingerprint?: string[];\n tags?: Record<string, SentryPrimitive | undefined>;\n context?: Record<string, unknown>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/observability/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Event } from \"@sentry/node\";\n\ntype SentryPrimitive = string | number | boolean;\ntype SentrySpanAttributeValue =\n | SentryPrimitive\n | Array<null | undefined | string>\n | Array<null | undefined | number>\n | Array<null | undefined | boolean>;\n\nexport interface SentryRunScopeContext {\n conversationId: string;\n sessionKey: string;\n messageId: string;\n platform: string;\n userId: string;\n userName?: string;\n threadTs?: string;\n provider?: string;\n model?: string;\n}\n\nexport type SentryAttributionAttributes = Record<string, SentryPrimitive>;\n\nexport interface SentrySpanPayload {\n trace_id: string;\n span_id: string;\n start_timestamp: number;\n data: Record<string, SentrySpanAttributeValue | undefined>;\n}\n\nexport interface SentryTransactionPayload extends Event {\n type: \"transaction\";\n entries?: Array<{ type?: string; data?: unknown }>;\n}\n\ntype UserFacingErrorDomain =\n | \"llm\"\n | \"chat_platform\"\n | \"mikan\"\n | \"sandbox\"\n | \"login\"\n | \"events\"\n | \"session_view\"\n | \"subagent\";\n\ntype UserFacingErrorSeverity = \"warning\" | \"error\" | \"fatal\";\n\nexport interface ReportUserFacingErrorOptions {\n domain: UserFacingErrorDomain;\n surface: string;\n operation: string;\n severity?: UserFacingErrorSeverity;\n platform?: string;\n provider?: string;\n model?: string;\n toolName?: string;\n stopReason?: string;\n expected?: boolean;\n fingerprint?: string[];\n tags?: Record<string, SentryPrimitive | undefined>;\n context?: Record<string, unknown>;\n}\n\n/** Terminal states of one subagent run as seen by the parent tool. */\nexport type SubagentOutcomeStatus =\n | \"completed\"\n | \"failed\"\n | \"cancelled\"\n | \"timeout\"\n | \"budget_exceeded\"\n | \"invalid_output\"\n | \"skipped\";\n\n/** Metrics-only view of a subagent outcome; never carries task text or labels. */\nexport interface SubagentOutcomeReport {\n itemId: string;\n mode: \"single\" | \"parallel\" | \"dag\";\n status: SubagentOutcomeStatus;\n profile?: string;\n error?: string;\n turns?: number;\n toolCalls?: number;\n tokens?: number;\n costUsd?: number;\n durationMs?: number;\n cleanupPending?: boolean;\n}\n"]}
|
|
@@ -4,6 +4,7 @@ type PlatformSource = MessagingBot | MessagingInfo | string;
|
|
|
4
4
|
export declare function formatNothingRunning(source: PlatformSource): string;
|
|
5
5
|
export declare function formatStopping(source: PlatformSource): string;
|
|
6
6
|
export declare function formatStopped(source: PlatformSource): string;
|
|
7
|
+
export declare function formatRestarting(source: PlatformSource): string;
|
|
7
8
|
export declare function formatAlreadyWorking(source: PlatformSource, stopCommand: string, options?: {
|
|
8
9
|
scope?: "thread";
|
|
9
10
|
}): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-messages.d.ts","sourceRoot":"","sources":["../src/platform-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEhE,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,KAAK,cAAc,GAAG,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC;AAoB5D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAE7D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAE5D;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,QAAQ,CAAA;CAAE,GAC7B,MAAM,CAMR;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAErF"}
|
|
1
|
+
{"version":3,"file":"platform-messages.d.ts","sourceRoot":"","sources":["../src/platform-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEhE,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,KAAK,cAAc,GAAG,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC;AAoB5D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAE7D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAK/D;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,QAAQ,CAAA;CAAE,GAC7B,MAAM,CAMR;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAErF"}
|
|
@@ -24,6 +24,9 @@ export function formatStopping(source) {
|
|
|
24
24
|
export function formatStopped(source) {
|
|
25
25
|
return formatItalic(resolvePlatformName(source), "Stopped.");
|
|
26
26
|
}
|
|
27
|
+
export function formatRestarting(source) {
|
|
28
|
+
return formatItalic(resolvePlatformName(source), "Restarting for an update; this reply was interrupted. Please send your message again.");
|
|
29
|
+
}
|
|
27
30
|
export function formatAlreadyWorking(source, stopCommand, options) {
|
|
28
31
|
const platformName = resolvePlatformName(source);
|
|
29
32
|
const command = formatCode(platformName, stopCommand);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-messages.js","sourceRoot":"","sources":["../src/platform-messages.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC;AAIpC,SAAS,mBAAmB,CAAC,MAAsB;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,kBAAkB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC;IACxE,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAoB;IAClD,OAAO,YAAY,KAAK,UAAU,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,YAAoB,EAAE,IAAY;IACtD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,YAAoB,EAAE,IAAY;IACpD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAsB;IAClD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,WAAmB,EACnB,OAA8B;IAE9B,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,MAAM,GACV,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACvF,OAAO,YAAY,CAAC,YAAY,EAAE,GAAG,MAAM,SAAS,OAAO,aAAa,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB,EAAE,UAAkB;IAC3E,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,oBAAoB,UAAU,GAAG,CAAC,CAAC;AACtF,CAAC","sourcesContent":["import type { MessagingBot, MessagingInfo } from \"./adapter.js\";\n\nexport const PRODUCT_NAME = \"mikan\";\n\ntype PlatformSource = MessagingBot | MessagingInfo | string;\n\nfunction resolvePlatformName(source: PlatformSource): string {\n if (typeof source === \"string\") return source;\n if (\"getMessagingInfo\" in source) return source.getMessagingInfo().name;\n return source.name;\n}\n\nfunction supportsHtmlFormatting(platformName: string): boolean {\n return platformName === \"telegram\";\n}\n\nfunction formatItalic(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? text : `_${text}_`;\n}\n\nfunction formatCode(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? `<code>${text}</code>` : `\\`${text}\\``;\n}\n\nexport function formatNothingRunning(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Nothing running.\");\n}\n\nexport function formatStopping(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Stopping…\");\n}\n\nexport function formatStopped(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Stopped.\");\n}\n\nexport function formatAlreadyWorking(\n source: PlatformSource,\n stopCommand: string,\n options?: { scope?: \"thread\" },\n): string {\n const platformName = resolvePlatformName(source);\n const command = formatCode(platformName, stopCommand);\n const prefix =\n options?.scope === \"thread\" ? \"Already working in this thread.\" : \"Already working.\";\n return formatItalic(platformName, `${prefix} Send ${command} to cancel.`);\n}\n\nexport function formatForceStopped(source: PlatformSource, actorLabel: string): string {\n return formatItalic(resolvePlatformName(source), `Force stopped by ${actorLabel}.`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"platform-messages.js","sourceRoot":"","sources":["../src/platform-messages.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC;AAIpC,SAAS,mBAAmB,CAAC,MAAsB;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,kBAAkB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC;IACxE,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAoB;IAClD,OAAO,YAAY,KAAK,UAAU,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,YAAoB,EAAE,IAAY;IACtD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,YAAoB,EAAE,IAAY;IACpD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAsB;IAClD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,OAAO,YAAY,CACjB,mBAAmB,CAAC,MAAM,CAAC,EAC3B,uFAAuF,CACxF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,WAAmB,EACnB,OAA8B;IAE9B,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,MAAM,GACV,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACvF,OAAO,YAAY,CAAC,YAAY,EAAE,GAAG,MAAM,SAAS,OAAO,aAAa,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB,EAAE,UAAkB;IAC3E,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,oBAAoB,UAAU,GAAG,CAAC,CAAC;AACtF,CAAC","sourcesContent":["import type { MessagingBot, MessagingInfo } from \"./adapter.js\";\n\nexport const PRODUCT_NAME = \"mikan\";\n\ntype PlatformSource = MessagingBot | MessagingInfo | string;\n\nfunction resolvePlatformName(source: PlatformSource): string {\n if (typeof source === \"string\") return source;\n if (\"getMessagingInfo\" in source) return source.getMessagingInfo().name;\n return source.name;\n}\n\nfunction supportsHtmlFormatting(platformName: string): boolean {\n return platformName === \"telegram\";\n}\n\nfunction formatItalic(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? text : `_${text}_`;\n}\n\nfunction formatCode(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? `<code>${text}</code>` : `\\`${text}\\``;\n}\n\nexport function formatNothingRunning(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Nothing running.\");\n}\n\nexport function formatStopping(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Stopping…\");\n}\n\nexport function formatStopped(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Stopped.\");\n}\n\nexport function formatRestarting(source: PlatformSource): string {\n return formatItalic(\n resolvePlatformName(source),\n \"Restarting for an update; this reply was interrupted. Please send your message again.\",\n );\n}\n\nexport function formatAlreadyWorking(\n source: PlatformSource,\n stopCommand: string,\n options?: { scope?: \"thread\" },\n): string {\n const platformName = resolvePlatformName(source);\n const command = formatCode(platformName, stopCommand);\n const prefix =\n options?.scope === \"thread\" ? \"Already working in this thread.\" : \"Already working.\";\n return formatItalic(platformName, `${prefix} Send ${command} to cancel.`);\n}\n\nexport function formatForceStopped(source: PlatformSource, actorLabel: string): string {\n return formatItalic(resolvePlatformName(source), `Force stopped by ${actorLabel}.`);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-lifecycle.d.ts","sourceRoot":"","sources":["../src/process-lifecycle.ts"],"names":[],"mappings":"AAAA,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACrC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;
|
|
1
|
+
{"version":3,"file":"process-lifecycle.d.ts","sourceRoot":"","sources":["../src/process-lifecycle.ts"],"names":[],"mappings":"AAAA,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACrC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAaD,mFAAmF;AACnF,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,EAAE,GAC3D,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,sBAAsB,GAC9B,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAqC3C"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
function asError(error) {
|
|
2
2
|
return error instanceof Error ? error : new Error(String(error));
|
|
3
3
|
}
|
|
4
|
+
/** Flatten AggregateError trees so the log names every failed step, not just the wrapper. */
|
|
5
|
+
function describeFailure(error) {
|
|
6
|
+
if (!(error instanceof AggregateError))
|
|
7
|
+
return error.message;
|
|
8
|
+
const inner = error.errors.map((entry) => describeFailure(asError(entry)));
|
|
9
|
+
return `${error.message}: ${inner.join("; ")}`;
|
|
10
|
+
}
|
|
4
11
|
/** Run every shutdown phase in order without letting one failure skip the rest. */
|
|
5
12
|
export async function runShutdownSteps(steps) {
|
|
6
13
|
const failures = [];
|
|
@@ -38,7 +45,7 @@ export function createProcessShutdownHandler(options) {
|
|
|
38
45
|
catch (error) {
|
|
39
46
|
const failure = asError(error);
|
|
40
47
|
exitCode = 1;
|
|
41
|
-
options.warn("Graceful shutdown failed", failure
|
|
48
|
+
options.warn("Graceful shutdown failed", describeFailure(failure));
|
|
42
49
|
options.captureError(failure);
|
|
43
50
|
}
|
|
44
51
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-lifecycle.js","sourceRoot":"","sources":["../src/process-lifecycle.ts"],"names":[],"mappings":"AAQA,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAA4D;IAE5D,MAAM,QAAQ,GAAY,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC;AAC1F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAA+B;IAE/B,IAAI,QAAmC,CAAC;IACxC,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,OAAO,SAAS,YAAY,CAAC,MAAsB;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,GAAG,IAAI,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,YAAY,MAAM,gCAAgC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,QAAQ,GAAG,CAAC,KAAK,IAAI,EAAE;YACrB,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACvB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC/B,QAAQ,GAAG,CAAC,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE,
|
|
1
|
+
{"version":3,"file":"process-lifecycle.js","sourceRoot":"","sources":["../src/process-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["interface ProcessShutdownOptions {\n stop: () => Promise<void>;\n flush: () => Promise<boolean>;\n captureError: (error: Error) => void;\n warn: (message: string, details?: string) => void;\n exit: (code: number) => void;\n}\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\n/** Flatten AggregateError trees so the log names every failed step, not just the wrapper. */\nfunction describeFailure(error: Error): string {\n if (!(error instanceof AggregateError)) return error.message;\n const inner = error.errors.map((entry) => describeFailure(asError(entry)));\n return `${error.message}: ${inner.join(\"; \")}`;\n}\n\n/** Run every shutdown phase in order without letting one failure skip the rest. */\nexport async function runShutdownSteps(\n steps: readonly { name: string; run: () => Promise<void> }[],\n): Promise<void> {\n const failures: Error[] = [];\n for (const step of steps) {\n try {\n await step.run();\n } catch (error) {\n const failure = asError(error);\n failures.push(new Error(`${step.name}: ${failure.message}`, { cause: failure }));\n }\n }\n if (failures.length > 0) throw new AggregateError(failures, \"Graceful shutdown failed\");\n}\n\n/**\n * Owns process-signal shutdown policy: one graceful attempt, then a forced\n * non-zero exit when another signal says the operator no longer wants to wait.\n */\nexport function createProcessShutdownHandler(\n options: ProcessShutdownOptions,\n): (signal: NodeJS.Signals) => Promise<void> {\n let shutdown: Promise<void> | undefined;\n let forced = false;\n\n return function handleSignal(signal: NodeJS.Signals): Promise<void> {\n if (shutdown) {\n forced = true;\n options.warn(`Received ${signal} during shutdown; forcing exit`);\n options.exit(1);\n return Promise.resolve();\n }\n\n shutdown = (async () => {\n let exitCode = 0;\n try {\n await options.stop();\n } catch (error) {\n const failure = asError(error);\n exitCode = 1;\n options.warn(\"Graceful shutdown failed\", describeFailure(failure));\n options.captureError(failure);\n }\n\n try {\n if (!(await options.flush())) {\n exitCode = 1;\n options.warn(\"Sentry flush timed out during shutdown\");\n }\n } catch (error) {\n exitCode = 1;\n options.warn(\"Sentry flush failed during shutdown\", asError(error).message);\n }\n\n if (!forced) options.exit(exitCode);\n })();\n return shutdown;\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/conversation-runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conversation-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/conversation-runtime.ts"],"names":[],"mappings":"AAsDA,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAEV,mBAAmB,EACnB,0BAA0B,EAE3B,MAAM,YAAY,CAAC;AAmDpB,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,0BAA0B,GAClC,mBAAmB,CAErB"}
|
|
@@ -9,7 +9,7 @@ import { ChatHistorySync, hasMaterializedChatSession, waitForThreadSessionBootst
|
|
|
9
9
|
import { shouldRotateTopLevelSession } from "../sessions/store.js";
|
|
10
10
|
import { getThreadSessionFile, resolveChannelSessionFile, tryResolveThreadSession, } from "../sessions/store.js";
|
|
11
11
|
import { assertSessionKeyBelongsToConversation, deriveSessionKey, } from "../sessions/session-key.js";
|
|
12
|
-
import { formatNothingRunning, formatStopped, formatStopping } from "../platform-messages.js";
|
|
12
|
+
import { formatNothingRunning, formatRestarting, formatStopped, formatStopping, } from "../platform-messages.js";
|
|
13
13
|
import * as Sentry from "@sentry/node";
|
|
14
14
|
import { getUnresolvedSandboxPathContext } from "../sandbox/index.js";
|
|
15
15
|
import { disabledVaultManager } from "../vault/index.js";
|
|
@@ -31,6 +31,24 @@ function runtimeCwdForSandbox(sandbox, workspace, address) {
|
|
|
31
31
|
// The office key names the same segment on the host and in the runtime.
|
|
32
32
|
return `${runtimeWorkspaceRoot.replace(/\/+$/, "")}/${workspace.office(address).key}`;
|
|
33
33
|
}
|
|
34
|
+
/** Tell the conversation why its reply stopped: an operator stop, or a shutdown deadline. */
|
|
35
|
+
async function postAbortNotice(state, bot, conversationId, platformName) {
|
|
36
|
+
if (state.shutdownAborted) {
|
|
37
|
+
Sentry.metrics.count("agent.run.shutdown_aborted", 1, {
|
|
38
|
+
attributes: { platform: platformName },
|
|
39
|
+
});
|
|
40
|
+
await bot.postMessage(conversationId, formatRestarting(bot));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!state.stopRequested)
|
|
44
|
+
return;
|
|
45
|
+
if (state.stopMessageTs) {
|
|
46
|
+
await bot.updateMessage(conversationId, state.stopMessageTs, formatStopped(bot));
|
|
47
|
+
state.stopMessageTs = undefined;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await bot.postMessage(conversationId, formatStopped(bot));
|
|
51
|
+
}
|
|
34
52
|
export function createConversationRuntime(options) {
|
|
35
53
|
return new ConversationRuntimeImpl(options);
|
|
36
54
|
}
|
|
@@ -239,14 +257,8 @@ class ConversationRuntimeImpl {
|
|
|
239
257
|
await context.responder.setWorking(false);
|
|
240
258
|
}
|
|
241
259
|
});
|
|
242
|
-
if (result?.stopReason === "aborted"
|
|
243
|
-
|
|
244
|
-
await bot.updateMessage(conversationId, state.stopMessageTs, formatStopped(bot));
|
|
245
|
-
state.stopMessageTs = undefined;
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
await bot.postMessage(conversationId, formatStopped(bot));
|
|
249
|
-
}
|
|
260
|
+
if (result?.stopReason === "aborted") {
|
|
261
|
+
await postAbortNotice(state, bot, conversationId, context.platform.name);
|
|
250
262
|
}
|
|
251
263
|
}
|
|
252
264
|
finally {
|