@geminixiang/mama 0.2.0-beta.19 → 0.2.0-beta.20
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/README.md +11 -17
- package/dist/adapter.d.ts +1 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +5 -5
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts +1 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +27 -2
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/shared.d.ts +20 -0
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +29 -0
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +3 -3
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +99 -64
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/branch-manager.d.ts +6 -0
- package/dist/adapters/slack/branch-manager.d.ts.map +1 -1
- package/dist/adapters/slack/branch-manager.js +15 -5
- package/dist/adapters/slack/branch-manager.js.map +1 -1
- package/dist/adapters/slack/context.d.ts +4 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +36 -29
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/session.d.ts +35 -0
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +51 -1
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +6 -6
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts +1 -1
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +27 -6
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +56 -10
- package/dist/agent.js.map +1 -1
- package/dist/commands/auto-reply.d.ts.map +1 -1
- package/dist/commands/auto-reply.js +4 -1
- package/dist/commands/auto-reply.js.map +1 -1
- package/dist/config.d.ts +0 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -39
- package/dist/config.js.map +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +37 -2
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +40 -6
- package/dist/execution-resolver.js.map +1 -1
- package/dist/log.d.ts +0 -7
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +0 -106
- package/dist/log.js.map +1 -1
- package/dist/login/portal.d.ts.map +1 -1
- package/dist/login/portal.js +64 -0
- package/dist/login/portal.js.map +1 -1
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +14 -0
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-orchestrator.d.ts +1 -2
- package/dist/runtime/conversation-orchestrator.d.ts.map +1 -1
- package/dist/runtime/conversation-orchestrator.js +44 -12
- package/dist/runtime/conversation-orchestrator.js.map +1 -1
- package/dist/runtime/session-runtime.d.ts +0 -1
- package/dist/runtime/session-runtime.d.ts.map +1 -1
- package/dist/runtime/session-runtime.js +12 -11
- package/dist/runtime/session-runtime.js.map +1 -1
- package/dist/sentry.d.ts +20 -1
- package/dist/sentry.d.ts.map +1 -1
- package/dist/sentry.js +58 -8
- package/dist/sentry.js.map +1 -1
- package/dist/session-view/portal.d.ts.map +1 -1
- package/dist/session-view/portal.js +83 -3
- package/dist/session-view/portal.js.map +1 -1
- package/dist/vault.d.ts.map +1 -1
- package/dist/vault.js +8 -0
- package/dist/vault.js.map +1 -1
- package/package.json +2 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-runtime.js","sourceRoot":"","sources":["../../src/runtime/session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bot, BotAdapters, BotEvent, BotHandler, RunningSession } from \"../adapter.js\";\nimport { resolveSlackSessionScope } from \"../adapters/slack/branch-manager.js\";\nimport { type AgentRunner, createRunner } from \"../agent.js\";\nimport { defaultCommandHandlers } from \"../commands/index.js\";\nimport type { CommandHandler, CommandServices } from \"../commands/index.js\";\nimport * as log from \"../log.js\";\nimport {\n createManagedSessionFile,\n createManagedSessionFileAtPath,\n getChannelSessionDir,\n getThreadSessionFile,\n resolveGenericSessionScope,\n type ResolvedSessionScope,\n} from \"../session-store.js\";\nimport { formatNothingRunning, formatStopping } from \"../ui-copy.js\";\nimport {\n ConversationOrchestrator,\n type ConversationRuntimeState,\n} from \"./conversation-orchestrator.js\";\nimport * as Sentry from \"@sentry/node\";\nimport { join } from \"path\";\nimport { getUnresolvedSandboxPathContext } from \"../agent.js\";\n\ntype ConversationState = ConversationRuntimeState;\n\nexport interface RunSessionOptions {\n event: BotEvent;\n bot: Bot;\n adapters: BotAdapters;\n isSyntheticEvent?: boolean;\n}\n\nexport interface CreateSessionSandboxOptions {\n conversationId: string;\n platformName: string;\n sessionKey: string;\n}\n\nexport interface SessionRuntimeOptions extends Omit<CommandServices, \"runtime\"> {\n /** Override the default command handlers (e.g., to add /help, /status). */\n commandHandlers?: readonly CommandHandler[];\n}\n\nexport interface SessionRuntime extends BotHandler {\n runSession(options: RunSessionOptions): Promise<void>;\n createSessionSandbox(options: CreateSessionSandboxOptions): Promise<AgentRunner>;\n switchConversationModel(conversationId: string, provider: string, model: string): boolean;\n refreshConversationEnvironment(conversationId: string): boolean;\n shutdown(timeoutMs?: number): Promise<void>;\n}\n\nconst MAX_SESSIONS = 500;\nconst IDLE_TIMEOUT_MS = 3_600_000;\n\nfunction runtimeCwdForSandbox(\n sandbox: SessionRuntimeOptions[\"sandbox\"],\n hostWorkspaceRoot: string,\n conversationId: string,\n): string {\n const runtimeWorkspaceRoot = getUnresolvedSandboxPathContext(\n sandbox,\n hostWorkspaceRoot,\n ).runtimeWorkspaceRoot;\n return `${runtimeWorkspaceRoot.replace(/\\/+$/, \"\")}/${conversationId}`;\n}\n\nexport function createSessionRuntime(options: SessionRuntimeOptions): SessionRuntime {\n return new MamaSessionRuntime(options);\n}\n\nclass MamaSessionRuntime implements SessionRuntime {\n private readonly conversationStates = new Map<string, ConversationState>();\n private readonly sessionQueues = new Map<string, Promise<void>>();\n private readonly inFlightRuns = new Set<Promise<void>>();\n private readonly orchestrator: ConversationOrchestrator;\n private isShuttingDown = false;\n\n constructor(private readonly options: SessionRuntimeOptions) {\n const commandServices: CommandServices = { ...options, runtime: this };\n const commandHandlers = options.commandHandlers ?? defaultCommandHandlers();\n this.orchestrator = new ConversationOrchestrator({\n workingDir: options.workingDir,\n commandHandlers,\n commandServices,\n isShuttingDown: () => this.isShuttingDown,\n getState: (sessionKey) => this.conversationStates.get(sessionKey),\n getOrCreateState: (createOptions) => this.getOrCreateState(createOptions),\n beforeRunTracked: (runPromise) => {\n this.inFlightRuns.add(runPromise);\n Sentry.metrics.gauge(\"agent.sessions.active\", this.inFlightRuns.size);\n },\n afterRunTracked: (runPromise) => {\n this.inFlightRuns.delete(runPromise);\n },\n onRunFinished: () => {\n Sentry.metrics.gauge(\"agent.sessions.active\", this.inFlightRuns.size - 1);\n this.evictIdleSessions();\n },\n });\n }\n\n isRunning(sessionKey: string): boolean {\n const state = this.conversationStates.get(sessionKey);\n return !!state?.running;\n }\n\n getRunningSessions(): RunningSession[] {\n const sessions: RunningSession[] = [];\n for (const [sessionKey, state] of this.conversationStates) {\n if (state.running && state.startedAt) {\n const currentStep = state.runner.getCurrentStep();\n sessions.push({\n sessionKey,\n startedAt: state.startedAt,\n lastActivityAt: state.lastActivityAt,\n currentTool: currentStep?.label || currentStep?.toolName,\n });\n }\n }\n return sessions;\n }\n\n async handleStop(sessionKey: string, conversationId: string, bot: Bot): Promise<void> {\n const state = this.conversationStates.get(sessionKey);\n if (state?.running) {\n state.stopRequested = true;\n state.runner.abort();\n const ts = await bot.postMessage(conversationId, formatStopping(bot));\n state.stopMessageTs = ts;\n } else {\n await bot.postMessage(conversationId, formatNothingRunning(bot));\n }\n }\n\n forceStop(sessionKey: string): void {\n const state = this.conversationStates.get(sessionKey);\n if (state?.running) {\n log.logInfo(`[Force Stop] Force stopping session: ${sessionKey}`);\n state.stopRequested = true;\n state.runner.abort();\n state.running = false;\n }\n }\n\n async handleNewCommand(sessionKey: string, conversationId: string, bot: Bot): Promise<void> {\n const state = this.conversationStates.get(sessionKey);\n if (state?.running) {\n state.stopRequested = true;\n state.runner.abort();\n }\n\n const conversationDir = join(this.options.workingDir, conversationId);\n const runtimeCwd = runtimeCwdForSandbox(\n this.options.sandbox,\n this.options.workingDir,\n conversationId,\n );\n if (sessionKey.includes(\":\")) {\n createManagedSessionFileAtPath(getThreadSessionFile(conversationDir, sessionKey), runtimeCwd);\n } else {\n createManagedSessionFile(getChannelSessionDir(conversationDir), runtimeCwd);\n }\n\n this.conversationStates.delete(sessionKey);\n\n log.logInfo(`[${conversationId}] Session reset: ${sessionKey}`);\n await bot.postMessage(conversationId, \"Conversation reset. Send a new message to start fresh.\");\n }\n\n async handleEvent(\n event: BotEvent,\n bot: Bot,\n adapters: BotAdapters,\n isSyntheticEvent?: boolean,\n ): Promise<void> {\n const sessionKey = event.sessionKey ?? `${event.conversationId}:${event.thread_ts ?? event.ts}`;\n const previous = this.sessionQueues.get(sessionKey) ?? Promise.resolve();\n const next = previous\n .catch(() => {})\n .then(() => this.runSession({ event, bot, adapters, isSyntheticEvent }));\n this.sessionQueues.set(sessionKey, next);\n try {\n await next;\n } finally {\n if (this.sessionQueues.get(sessionKey) === next) {\n this.sessionQueues.delete(sessionKey);\n }\n }\n }\n\n async runSession({ event, bot, adapters, isSyntheticEvent }: RunSessionOptions): Promise<void> {\n await this.orchestrator.runSession({ event, bot, adapters, isSyntheticEvent });\n }\n\n async createSessionSandbox(options: CreateSessionSandboxOptions): Promise<AgentRunner> {\n const state = await this.getOrCreateState(options);\n return state.runner;\n }\n\n switchConversationModel(conversationId: string, _provider: string, _model: string): boolean {\n return this.clearConversationStates(\n conversationId,\n `[${conversationId}] Model switched; cleared cached session runners`,\n );\n }\n\n refreshConversationEnvironment(conversationId: string): boolean {\n return this.clearConversationStates(\n conversationId,\n `[${conversationId}] Environment refreshed; cleared cached session runners`,\n );\n }\n\n private isConversationSession(sessionKey: string, conversationId: string): boolean {\n return sessionKey === conversationId || sessionKey.startsWith(`${conversationId}:`);\n }\n\n private clearConversationStates(conversationId: string, message: string): boolean {\n for (const [sessionKey, state] of this.conversationStates) {\n if (this.isConversationSession(sessionKey, conversationId) && state.running) {\n return false;\n }\n }\n\n for (const sessionKey of Array.from(this.conversationStates.keys())) {\n if (this.isConversationSession(sessionKey, conversationId)) {\n this.conversationStates.delete(sessionKey);\n }\n }\n log.logInfo(message);\n return true;\n }\n\n private async getOrCreateState({\n conversationId,\n platformName,\n sessionKey,\n }: CreateSessionSandboxOptions): Promise<ConversationState> {\n const existing = this.conversationStates.get(sessionKey);\n if (existing) {\n existing.lastAccessedAt = Date.now();\n return existing;\n }\n\n const conversationDir = join(this.options.workingDir, conversationId);\n const runtimeCwd = runtimeCwdForSandbox(\n this.options.sandbox,\n this.options.workingDir,\n conversationId,\n );\n const sessionScope = await this.resolveSessionScope(\n platformName,\n conversationDir,\n sessionKey,\n runtimeCwd,\n );\n const state: ConversationState = {\n running: false,\n runner: await createRunner(\n this.options.sandbox,\n sessionKey,\n conversationId,\n conversationDir,\n this.options.workingDir,\n sessionScope,\n this.options.vaultManager,\n this.options.provisioner,\n {\n tokenStore: this.options.sessionViewTokenStore,\n portalBaseUrl: this.options.portalBaseUrl,\n },\n ),\n stopRequested: false,\n lastAccessedAt: Date.now(),\n };\n this.conversationStates.set(sessionKey, state);\n return state;\n }\n\n async shutdown(timeoutMs = 30_000): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n log.logInfo(\"Shutting down gracefully...\");\n\n const timeout = Date.now() + timeoutMs;\n while (this.inFlightRuns.size > 0 && Date.now() < timeout) {\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n\n if (this.inFlightRuns.size > 0) {\n log.logWarning(`Forcing exit with ${this.inFlightRuns.size} runs still in progress`);\n }\n }\n\n private async resolveSessionScope(\n platformName: string,\n conversationDir: string,\n sessionKey: string,\n cwd: string,\n ): Promise<ResolvedSessionScope> {\n if (sessionKey.includes(\":event:\")) {\n const sessionDir = getChannelSessionDir(conversationDir);\n const contextFile = createManagedSessionFileAtPath(\n getThreadSessionFile(conversationDir, sessionKey),\n cwd,\n );\n return { sessionDir, contextFile, threadRootMessage: null };\n }\n\n if (platformName === \"slack\") {\n return resolveSlackSessionScope({ conversationDir, sessionKey, cwd });\n }\n return resolveGenericSessionScope({ conversationDir, sessionKey, cwd });\n }\n\n private evictIdleSessions(): void {\n const now = Date.now();\n\n for (const [key, state] of this.conversationStates) {\n if (!state.running && now - state.lastAccessedAt > IDLE_TIMEOUT_MS) {\n this.conversationStates.delete(key);\n }\n }\n\n if (this.conversationStates.size > MAX_SESSIONS) {\n const idleSessions: Array<{ key: string; lastAccessedAt: number }> = [];\n for (const [key, state] of this.conversationStates) {\n if (!state.running) {\n idleSessions.push({ key, lastAccessedAt: state.lastAccessedAt });\n }\n }\n\n idleSessions.sort((a, b) => a.lastAccessedAt - b.lastAccessedAt);\n\n const toEvict = this.conversationStates.size - MAX_SESSIONS;\n for (let i = 0; i < toEvict && i < idleSessions.length; i++) {\n this.conversationStates.delete(idleSessions[i].key);\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-runtime.js","sourceRoot":"","sources":["../../src/runtime/session-runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,GAE3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EACL,wBAAwB,GAEzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AA6B9D,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,eAAe,GAAG,SAAS,CAAC;AAElC,SAAS,oBAAoB,CAC3B,OAAyC,EACzC,iBAAyB,EACzB,cAAsB;IAEtB,MAAM,oBAAoB,GAAG,+BAA+B,CAC1D,OAAO,EACP,iBAAiB,CAClB,CAAC,oBAAoB,CAAC;IACvB,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,cAAc,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAA8B;IACjE,OAAO,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,kBAAkB;IAOtB,YAA6B,OAA8B;QAA9B,YAAO,GAAP,OAAO,CAAuB;QAN1C,uBAAkB,GAAG,IAAI,GAAG,EAA6B,CAAC;QAC1D,kBAAa,GAAG,IAAI,GAAG,EAAyB,CAAC;QACjD,iBAAY,GAAG,IAAI,GAAG,EAAiB,CAAC;QAEjD,mBAAc,GAAG,KAAK,CAAC;QAG7B,MAAM,eAAe,GAAoB,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACvE,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,sBAAsB,EAAE,CAAC;QAC5E,IAAI,CAAC,YAAY,GAAG,IAAI,wBAAwB,CAAC;YAC/C,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,eAAe;YACf,eAAe;YACf,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc;YACzC,QAAQ,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;YACjE,gBAAgB,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC;YACzE,gBAAgB,EAAE,CAAC,UAAU,EAAE,EAAE;gBAC/B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAClC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YACxE,CAAC;YACD,eAAe,EAAE,CAAC,UAAU,EAAE,EAAE;gBAC9B,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACvC,CAAC;YACD,aAAa,EAAE,GAAG,EAAE;gBAClB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;gBAC1E,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,UAAkB;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtD,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC;IAC1B,CAAC;IAED,kBAAkB;QAChB,MAAM,QAAQ,GAAqB,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1D,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACrC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBAClD,QAAQ,CAAC,IAAI,CAAC;oBACZ,UAAU;oBACV,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;oBACpC,WAAW,EAAE,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,QAAQ;iBACzD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAkB,EAAE,cAAsB,EAAE,GAAQ;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,KAAK,EAAE,OAAO,EAAE,CAAC;YACnB,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC3B,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;YACtE,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,SAAS,CAAC,UAAkB;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,KAAK,EAAE,OAAO,EAAE,CAAC;YACnB,GAAG,CAAC,OAAO,CAAC,wCAAwC,UAAU,EAAE,CAAC,CAAC;YAClE,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC3B,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,cAAsB,EAAE,GAAQ;QACzE,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,KAAK,EAAE,OAAO,EAAE,CAAC;YACnB,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC3B,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACtE,MAAM,UAAU,GAAG,oBAAoB,CACrC,IAAI,CAAC,OAAO,CAAC,OAAO,EACpB,IAAI,CAAC,OAAO,CAAC,UAAU,EACvB,cAAc,CACf,CAAC;QACF,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,8BAA8B,CAAC,oBAAoB,CAAC,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC;QAChG,CAAC;aAAM,CAAC;YACN,wBAAwB,CAAC,oBAAoB,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAE3C,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,oBAAoB,UAAU,EAAE,CAAC,CAAC;QAChE,MAAM,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,wDAAwD,CAAC,CAAC;IAClG,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAe,EAAE,GAAQ,EAAE,QAAqB;QAChE,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;QAChG,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACzE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC5F,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC;QACb,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAqB;QAC1D,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,OAAoC;QAC7D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAED,uBAAuB,CAAC,cAAsB,EAAE,SAAiB,EAAE,MAAc;QAC/E,OAAO,IAAI,CAAC,uBAAuB,CACjC,cAAc,EACd,IAAI,cAAc,kDAAkD,CACrE,CAAC;IACJ,CAAC;IAED,8BAA8B,CAAC,cAAsB;QACnD,OAAO,IAAI,CAAC,uBAAuB,CACjC,cAAc,EACd,IAAI,cAAc,yDAAyD,CAC5E,CAAC;IACJ,CAAC;IAEO,qBAAqB,CAAC,UAAkB,EAAE,cAAsB;QACtE,OAAO,UAAU,KAAK,cAAc,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC;IACtF,CAAC;IAEO,uBAAuB,CAAC,cAAsB,EAAE,OAAe;QACrE,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1D,IAAI,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,cAAc,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC5E,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACpE,IAAI,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC3D,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,EAC7B,cAAc,EACd,YAAY,EACZ,UAAU,GACkB;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACrC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACtE,MAAM,UAAU,GAAG,oBAAoB,CACrC,IAAI,CAAC,OAAO,CAAC,OAAO,EACpB,IAAI,CAAC,OAAO,CAAC,UAAU,EACvB,cAAc,CACf,CAAC;QACF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mBAAmB,CACjD,YAAY,EACZ,eAAe,EACf,UAAU,EACV,UAAU,CACX,CAAC;QACF,MAAM,KAAK,GAAsB;YAC/B,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,MAAM,YAAY,CACxB,IAAI,CAAC,OAAO,CAAC,OAAO,EACpB,UAAU,EACV,cAAc,EACd,eAAe,EACf,IAAI,CAAC,OAAO,CAAC,UAAU,EACvB,YAAY,EACZ,IAAI,CAAC,OAAO,CAAC,YAAY,EACzB,IAAI,CAAC,OAAO,CAAC,WAAW,EACxB;gBACE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB;gBAC9C,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa;aAC1C,CACF;YACD,aAAa,EAAE,KAAK;YACpB,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE;SAC3B,CAAC;QACF,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,SAAS,GAAG,MAAM;QAC/B,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,GAAG,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QAE3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACvC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;YAC1D,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,UAAU,CAAC,qBAAqB,IAAI,CAAC,YAAY,CAAC,IAAI,yBAAyB,CAAC,CAAC;YACrF,qBAAqB,CAAC,IAAI,KAAK,CAAC,2CAA2C,CAAC,EAAE;gBAC5E,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,UAAU;gBACnB,SAAS,EAAE,+BAA+B;gBAC1C,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE;aAC7D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAC/B,YAAoB,EACpB,eAAuB,EACvB,UAAkB,EAClB,GAAW;QAEX,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;YAC7B,OAAO,wBAAwB,CAAC,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,0BAA0B,CAAC,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1E,CAAC;IAEO,iBAAiB;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,GAAG,KAAK,CAAC,cAAc,GAAG,eAAe,EAAE,CAAC;gBACnE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,GAAG,YAAY,EAAE,CAAC;YAChD,MAAM,YAAY,GAAmD,EAAE,CAAC;YACxE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACnD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;oBACnB,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;YAED,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;YAEjE,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,GAAG,YAAY,CAAC;YAC5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5D,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;CACF","sourcesContent":["import type { Bot, BotAdapters, BotEvent, BotHandler, RunningSession } from \"../adapter.js\";\nimport { resolveSlackSessionScope } from \"../adapters/slack/branch-manager.js\";\nimport { type AgentRunner, createRunner } from \"../agent.js\";\nimport { defaultCommandHandlers } from \"../commands/index.js\";\nimport type { CommandHandler, CommandServices } from \"../commands/index.js\";\nimport * as log from \"../log.js\";\nimport { reportUserFacingError } from \"../sentry.js\";\nimport {\n createManagedSessionFile,\n createManagedSessionFileAtPath,\n getChannelSessionDir,\n getThreadSessionFile,\n resolveGenericSessionScope,\n type ResolvedSessionScope,\n} from \"../session-store.js\";\nimport { formatNothingRunning, formatStopping } from \"../ui-copy.js\";\nimport {\n ConversationOrchestrator,\n type ConversationRuntimeState,\n} from \"./conversation-orchestrator.js\";\nimport * as Sentry from \"@sentry/node\";\nimport { join } from \"path\";\nimport { getUnresolvedSandboxPathContext } from \"../agent.js\";\n\ntype ConversationState = ConversationRuntimeState;\n\nexport interface RunSessionOptions {\n event: BotEvent;\n bot: Bot;\n adapters: BotAdapters;\n}\n\nexport interface CreateSessionSandboxOptions {\n conversationId: string;\n platformName: string;\n sessionKey: string;\n}\n\nexport interface SessionRuntimeOptions extends Omit<CommandServices, \"runtime\"> {\n /** Override the default command handlers (e.g., to add /help, /status). */\n commandHandlers?: readonly CommandHandler[];\n}\n\nexport interface SessionRuntime extends BotHandler {\n runSession(options: RunSessionOptions): Promise<void>;\n createSessionSandbox(options: CreateSessionSandboxOptions): Promise<AgentRunner>;\n switchConversationModel(conversationId: string, provider: string, model: string): boolean;\n refreshConversationEnvironment(conversationId: string): boolean;\n shutdown(timeoutMs?: number): Promise<void>;\n}\n\nconst MAX_SESSIONS = 500;\nconst IDLE_TIMEOUT_MS = 3_600_000;\n\nfunction runtimeCwdForSandbox(\n sandbox: SessionRuntimeOptions[\"sandbox\"],\n hostWorkspaceRoot: string,\n conversationId: string,\n): string {\n const runtimeWorkspaceRoot = getUnresolvedSandboxPathContext(\n sandbox,\n hostWorkspaceRoot,\n ).runtimeWorkspaceRoot;\n return `${runtimeWorkspaceRoot.replace(/\\/+$/, \"\")}/${conversationId}`;\n}\n\nexport function createSessionRuntime(options: SessionRuntimeOptions): SessionRuntime {\n return new MamaSessionRuntime(options);\n}\n\nclass MamaSessionRuntime implements SessionRuntime {\n private readonly conversationStates = new Map<string, ConversationState>();\n private readonly sessionQueues = new Map<string, Promise<void>>();\n private readonly inFlightRuns = new Set<Promise<void>>();\n private readonly orchestrator: ConversationOrchestrator;\n private isShuttingDown = false;\n\n constructor(private readonly options: SessionRuntimeOptions) {\n const commandServices: CommandServices = { ...options, runtime: this };\n const commandHandlers = options.commandHandlers ?? defaultCommandHandlers();\n this.orchestrator = new ConversationOrchestrator({\n workingDir: options.workingDir,\n commandHandlers,\n commandServices,\n isShuttingDown: () => this.isShuttingDown,\n getState: (sessionKey) => this.conversationStates.get(sessionKey),\n getOrCreateState: (createOptions) => this.getOrCreateState(createOptions),\n beforeRunTracked: (runPromise) => {\n this.inFlightRuns.add(runPromise);\n Sentry.metrics.gauge(\"agent.sessions.active\", this.inFlightRuns.size);\n },\n afterRunTracked: (runPromise) => {\n this.inFlightRuns.delete(runPromise);\n },\n onRunFinished: () => {\n Sentry.metrics.gauge(\"agent.sessions.active\", this.inFlightRuns.size - 1);\n this.evictIdleSessions();\n },\n });\n }\n\n isRunning(sessionKey: string): boolean {\n const state = this.conversationStates.get(sessionKey);\n return !!state?.running;\n }\n\n getRunningSessions(): RunningSession[] {\n const sessions: RunningSession[] = [];\n for (const [sessionKey, state] of this.conversationStates) {\n if (state.running && state.startedAt) {\n const currentStep = state.runner.getCurrentStep();\n sessions.push({\n sessionKey,\n startedAt: state.startedAt,\n lastActivityAt: state.lastActivityAt,\n currentTool: currentStep?.label || currentStep?.toolName,\n });\n }\n }\n return sessions;\n }\n\n async handleStop(sessionKey: string, conversationId: string, bot: Bot): Promise<void> {\n const state = this.conversationStates.get(sessionKey);\n if (state?.running) {\n state.stopRequested = true;\n state.runner.abort();\n const ts = await bot.postMessage(conversationId, formatStopping(bot));\n state.stopMessageTs = ts;\n } else {\n await bot.postMessage(conversationId, formatNothingRunning(bot));\n }\n }\n\n forceStop(sessionKey: string): void {\n const state = this.conversationStates.get(sessionKey);\n if (state?.running) {\n log.logInfo(`[Force Stop] Force stopping session: ${sessionKey}`);\n state.stopRequested = true;\n state.runner.abort();\n state.running = false;\n }\n }\n\n async handleNewCommand(sessionKey: string, conversationId: string, bot: Bot): Promise<void> {\n const state = this.conversationStates.get(sessionKey);\n if (state?.running) {\n state.stopRequested = true;\n state.runner.abort();\n }\n\n const conversationDir = join(this.options.workingDir, conversationId);\n const runtimeCwd = runtimeCwdForSandbox(\n this.options.sandbox,\n this.options.workingDir,\n conversationId,\n );\n if (sessionKey.includes(\":\")) {\n createManagedSessionFileAtPath(getThreadSessionFile(conversationDir, sessionKey), runtimeCwd);\n } else {\n createManagedSessionFile(getChannelSessionDir(conversationDir), runtimeCwd);\n }\n\n this.conversationStates.delete(sessionKey);\n\n log.logInfo(`[${conversationId}] Session reset: ${sessionKey}`);\n await bot.postMessage(conversationId, \"Conversation reset. Send a new message to start fresh.\");\n }\n\n async handleEvent(event: BotEvent, bot: Bot, adapters: BotAdapters): Promise<void> {\n const sessionKey = event.sessionKey ?? `${event.conversationId}:${event.thread_ts ?? event.ts}`;\n const previous = this.sessionQueues.get(sessionKey) ?? Promise.resolve();\n const next = previous.catch(() => {}).then(() => this.runSession({ event, bot, adapters }));\n this.sessionQueues.set(sessionKey, next);\n try {\n await next;\n } finally {\n if (this.sessionQueues.get(sessionKey) === next) {\n this.sessionQueues.delete(sessionKey);\n }\n }\n }\n\n async runSession({ event, bot, adapters }: RunSessionOptions): Promise<void> {\n await this.orchestrator.runSession({ event, bot, adapters });\n }\n\n async createSessionSandbox(options: CreateSessionSandboxOptions): Promise<AgentRunner> {\n const state = await this.getOrCreateState(options);\n return state.runner;\n }\n\n switchConversationModel(conversationId: string, _provider: string, _model: string): boolean {\n return this.clearConversationStates(\n conversationId,\n `[${conversationId}] Model switched; cleared cached session runners`,\n );\n }\n\n refreshConversationEnvironment(conversationId: string): boolean {\n return this.clearConversationStates(\n conversationId,\n `[${conversationId}] Environment refreshed; cleared cached session runners`,\n );\n }\n\n private isConversationSession(sessionKey: string, conversationId: string): boolean {\n return sessionKey === conversationId || sessionKey.startsWith(`${conversationId}:`);\n }\n\n private clearConversationStates(conversationId: string, message: string): boolean {\n for (const [sessionKey, state] of this.conversationStates) {\n if (this.isConversationSession(sessionKey, conversationId) && state.running) {\n return false;\n }\n }\n\n for (const sessionKey of Array.from(this.conversationStates.keys())) {\n if (this.isConversationSession(sessionKey, conversationId)) {\n this.conversationStates.delete(sessionKey);\n }\n }\n log.logInfo(message);\n return true;\n }\n\n private async getOrCreateState({\n conversationId,\n platformName,\n sessionKey,\n }: CreateSessionSandboxOptions): Promise<ConversationState> {\n const existing = this.conversationStates.get(sessionKey);\n if (existing) {\n existing.lastAccessedAt = Date.now();\n return existing;\n }\n\n const conversationDir = join(this.options.workingDir, conversationId);\n const runtimeCwd = runtimeCwdForSandbox(\n this.options.sandbox,\n this.options.workingDir,\n conversationId,\n );\n const sessionScope = await this.resolveSessionScope(\n platformName,\n conversationDir,\n sessionKey,\n runtimeCwd,\n );\n const state: ConversationState = {\n running: false,\n runner: await createRunner(\n this.options.sandbox,\n sessionKey,\n conversationId,\n conversationDir,\n this.options.workingDir,\n sessionScope,\n this.options.vaultManager,\n this.options.provisioner,\n {\n tokenStore: this.options.sessionViewTokenStore,\n portalBaseUrl: this.options.portalBaseUrl,\n },\n ),\n stopRequested: false,\n lastAccessedAt: Date.now(),\n };\n this.conversationStates.set(sessionKey, state);\n return state;\n }\n\n async shutdown(timeoutMs = 30_000): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n log.logInfo(\"Shutting down gracefully...\");\n\n const timeout = Date.now() + timeoutMs;\n while (this.inFlightRuns.size > 0 && Date.now() < timeout) {\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n\n if (this.inFlightRuns.size > 0) {\n log.logWarning(`Forcing exit with ${this.inFlightRuns.size} runs still in progress`);\n reportUserFacingError(new Error(\"Shutdown forced with in-flight agent runs\"), {\n domain: \"mama\",\n surface: \"shutdown\",\n operation: \"force_exit_with_inflight_runs\",\n severity: \"warning\",\n context: { inFlightRuns: this.inFlightRuns.size, timeoutMs },\n });\n }\n }\n\n private async resolveSessionScope(\n platformName: string,\n conversationDir: string,\n sessionKey: string,\n cwd: string,\n ): Promise<ResolvedSessionScope> {\n if (platformName === \"slack\") {\n return resolveSlackSessionScope({ conversationDir, sessionKey, cwd });\n }\n return resolveGenericSessionScope({ conversationDir, sessionKey, cwd });\n }\n\n private evictIdleSessions(): void {\n const now = Date.now();\n\n for (const [key, state] of this.conversationStates) {\n if (!state.running && now - state.lastAccessedAt > IDLE_TIMEOUT_MS) {\n this.conversationStates.delete(key);\n }\n }\n\n if (this.conversationStates.size > MAX_SESSIONS) {\n const idleSessions: Array<{ key: string; lastAccessedAt: number }> = [];\n for (const [key, state] of this.conversationStates) {\n if (!state.running) {\n idleSessions.push({ key, lastAccessedAt: state.lastAccessedAt });\n }\n }\n\n idleSessions.sort((a, b) => a.lastAccessedAt - b.lastAccessedAt);\n\n const toEvict = this.conversationStates.size - MAX_SESSIONS;\n for (let i = 0; i < toEvict && i < idleSessions.length; i++) {\n this.conversationStates.delete(idleSessions[i].key);\n }\n }\n }\n}\n"]}
|
package/dist/sentry.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Breadcrumb, ErrorEvent, Event, EventHint, Scope } from "@sentry/node";
|
|
2
|
+
type SentryPrimitive = string | number | boolean;
|
|
2
3
|
export interface SentryRunScopeContext {
|
|
3
4
|
conversationId: string;
|
|
4
5
|
sessionKey: string;
|
|
@@ -9,7 +10,23 @@ export interface SentryRunScopeContext {
|
|
|
9
10
|
threadTs?: string;
|
|
10
11
|
provider?: string;
|
|
11
12
|
model?: string;
|
|
12
|
-
|
|
13
|
+
}
|
|
14
|
+
export type UserFacingErrorDomain = "llm" | "chat_platform" | "mama" | "sandbox" | "login" | "events" | "session_view";
|
|
15
|
+
export type UserFacingErrorSeverity = "warning" | "error" | "fatal";
|
|
16
|
+
export interface ReportUserFacingErrorOptions {
|
|
17
|
+
domain: UserFacingErrorDomain;
|
|
18
|
+
surface: string;
|
|
19
|
+
operation: string;
|
|
20
|
+
severity?: UserFacingErrorSeverity;
|
|
21
|
+
platform?: string;
|
|
22
|
+
provider?: string;
|
|
23
|
+
model?: string;
|
|
24
|
+
toolName?: string;
|
|
25
|
+
stopReason?: string;
|
|
26
|
+
expected?: boolean;
|
|
27
|
+
fingerprint?: string[];
|
|
28
|
+
tags?: Record<string, SentryPrimitive | undefined>;
|
|
29
|
+
context?: Record<string, unknown>;
|
|
13
30
|
}
|
|
14
31
|
export declare function createSentryInitOptions(dsn?: string): {
|
|
15
32
|
dsn: string | undefined;
|
|
@@ -22,10 +39,12 @@ export declare function createSentryInitOptions(dsn?: string): {
|
|
|
22
39
|
beforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null;
|
|
23
40
|
beforeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null;
|
|
24
41
|
};
|
|
42
|
+
export declare function reportUserFacingError(error: unknown, options: ReportUserFacingErrorOptions): string | undefined;
|
|
25
43
|
export declare function applyRunScope(scope: Scope, context: SentryRunScopeContext): void;
|
|
26
44
|
export declare function metricAttributes(attributes: Record<string, string | number | boolean | undefined>): Record<string, string | number | boolean>;
|
|
27
45
|
export declare function addLifecycleBreadcrumb(message: string, data?: Record<string, string | number | boolean | undefined>): void;
|
|
28
46
|
export declare function sanitizeEvent<T extends Event>(event: T, _hint?: EventHint): T | null;
|
|
29
47
|
export declare function sanitizeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null;
|
|
30
48
|
export declare function sanitizeValue(value: unknown, key?: string, depth?: number): unknown;
|
|
49
|
+
export {};
|
|
31
50
|
//# sourceMappingURL=sentry.d.ts.map
|
package/dist/sentry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentry.d.ts","sourceRoot":"","sources":["../src/sentry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AA6CpF,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;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,uBAAuB,CAAC,GAAG,CAAC,EAAE,MAAM;;;;;;;;sBAS9B,UAAU,QAAQ,SAAS,GAAG,UAAU,GAAG,IAAI;iCAGpC,UAAU,GAAG,UAAU,GAAG,IAAI;EAI9D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAyBhF;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GAChE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAO3C;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GAC3D,IAAI,CAON;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,IAAI,CA2CpF;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAU5E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAwB9E","sourcesContent":["import type { Breadcrumb, ErrorEvent, Event, EventHint, Scope } from \"@sentry/node\";\nimport * as Sentry from \"@sentry/node\";\n\nconst REDACTED = \"[REDACTED]\";\nconst REDACTED_PATH = \"[REDACTED_PATH]\";\nconst MAX_STRING_LENGTH = 256;\nconst MAX_DEPTH = 4;\n\nconst SENSITIVE_KEYS = new Set([\n \"args\",\n \"attachment\",\n \"attachments\",\n \"authorization\",\n \"body\",\n \"content\",\n \"contents\",\n \"cookie\",\n \"cookies\",\n \"filePath\",\n \"headers\",\n \"image\",\n \"imageAttachments\",\n \"images\",\n \"localPath\",\n \"messages\",\n \"newUserMessage\",\n \"path\",\n \"paths\",\n \"prompt\",\n \"response\",\n \"result\",\n \"systemPrompt\",\n \"text\",\n \"thinking\",\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 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 isSyntheticEvent?: boolean;\n}\n\nexport function createSentryInitOptions(dsn?: string) {\n return {\n dsn,\n environment: process.env.SENTRY_ENVIRONMENT ?? \"production\",\n enabled: Boolean(dsn) && process.env.SENTRY_ENABLED !== \"false\",\n sendDefaultPii: false,\n tracesSampleRate: process.env.NODE_ENV === \"development\" ? 1.0 : 1.0,\n includeLocalVariables: false,\n enableLogs: true,\n beforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null {\n return sanitizeEvent(event, hint);\n },\n beforeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {\n return sanitizeBreadcrumb(breadcrumb);\n },\n };\n}\n\nexport function applyRunScope(scope: Scope, context: SentryRunScopeContext): void {\n scope.setTag(\"conversation_id\", context.conversationId);\n scope.setTag(\"channel_id\", context.conversationId);\n scope.setTag(\"session_key\", context.sessionKey);\n scope.setTag(\"platform\", context.platform);\n scope.setTag(\"is_synthetic_event\", String(Boolean(context.isSyntheticEvent)));\n if (context.threadTs) scope.setTag(\"thread_ts\", context.threadTs);\n if (context.provider) scope.setTag(\"provider\", context.provider);\n if (context.model) scope.setTag(\"model\", context.model);\n\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 isSyntheticEvent: Boolean(context.isSyntheticEvent),\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 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 isSensitiveKey(key?: string): boolean {\n if (!key) return false;\n return SENSITIVE_KEYS.has(key);\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.d.ts","sourceRoot":"","sources":["../src/sentry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAQpF,KAAK,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAkDjD,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,qBAAqB,GAC7B,KAAK,GACL,eAAe,GACf,MAAM,GACN,SAAS,GACT,OAAO,GACP,QAAQ,GACR,cAAc,CAAC;AAEnB,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEpE,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,qBAAqB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,wBAAgB,uBAAuB,CAAC,GAAG,CAAC,EAAE,MAAM;;;;;;;;sBAS9B,UAAU,QAAQ,SAAS,GAAG,UAAU,GAAG,IAAI;iCAGpC,UAAU,GAAG,UAAU,GAAG,IAAI;EAI9D;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,4BAA4B,GACpC,MAAM,GAAG,SAAS,CAkCpB;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAuBhF;AAED,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GAChE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAO3C;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GAC3D,IAAI,CAON;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,CAAC,GAAG,IAAI,CA2CpF;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAU5E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAwB9E","sourcesContent":["import type { Breadcrumb, ErrorEvent, Event, EventHint, Scope } from \"@sentry/node\";\nimport * as Sentry from \"@sentry/node\";\n\nconst REDACTED = \"[REDACTED]\";\nconst REDACTED_PATH = \"[REDACTED_PATH]\";\nconst MAX_STRING_LENGTH = 256;\nconst MAX_DEPTH = 4;\n\ntype SentryPrimitive = string | number | boolean;\n\nconst SENSITIVE_KEYS = new Set([\n \"accesstoken\",\n \"apikey\",\n \"args\",\n \"attachment\",\n \"attachments\",\n \"authorization\",\n \"body\",\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 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 UserFacingErrorDomain =\n | \"llm\"\n | \"chat_platform\"\n | \"mama\"\n | \"sandbox\"\n | \"login\"\n | \"events\"\n | \"session_view\";\n\nexport type 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\nexport function createSentryInitOptions(dsn?: string) {\n return {\n dsn,\n environment: process.env.SENTRY_ENVIRONMENT ?? \"production\",\n enabled: Boolean(dsn) && process.env.SENTRY_ENABLED !== \"false\",\n sendDefaultPii: false,\n tracesSampleRate: process.env.NODE_ENV === \"development\" ? 1.0 : 1.0,\n includeLocalVariables: false,\n enableLogs: true,\n beforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null {\n return sanitizeEvent(event, hint);\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 applyRunScope(scope: Scope, context: SentryRunScopeContext): void {\n scope.setTag(\"conversation_id\", context.conversationId);\n scope.setTag(\"channel_id\", context.conversationId);\n scope.setTag(\"session_key\", context.sessionKey);\n scope.setTag(\"platform\", context.platform);\n if (context.threadTs) scope.setTag(\"thread_ts\", context.threadTs);\n if (context.provider) scope.setTag(\"provider\", context.provider);\n if (context.model) scope.setTag(\"model\", context.model);\n\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 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 isSensitiveKey(key?: string): boolean {\n if (!key) return false;\n return SENSITIVE_KEYS.has(key.toLowerCase());\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"]}
|
package/dist/sentry.js
CHANGED
|
@@ -4,31 +4,42 @@ const REDACTED_PATH = "[REDACTED_PATH]";
|
|
|
4
4
|
const MAX_STRING_LENGTH = 256;
|
|
5
5
|
const MAX_DEPTH = 4;
|
|
6
6
|
const SENSITIVE_KEYS = new Set([
|
|
7
|
+
"accesstoken",
|
|
8
|
+
"apikey",
|
|
7
9
|
"args",
|
|
8
10
|
"attachment",
|
|
9
11
|
"attachments",
|
|
10
12
|
"authorization",
|
|
11
13
|
"body",
|
|
14
|
+
"code",
|
|
12
15
|
"content",
|
|
13
16
|
"contents",
|
|
14
17
|
"cookie",
|
|
15
18
|
"cookies",
|
|
16
|
-
"
|
|
19
|
+
"credential",
|
|
20
|
+
"filepath",
|
|
17
21
|
"headers",
|
|
18
22
|
"image",
|
|
19
|
-
"
|
|
23
|
+
"imageattachments",
|
|
20
24
|
"images",
|
|
21
|
-
"
|
|
25
|
+
"localpath",
|
|
22
26
|
"messages",
|
|
23
|
-
"
|
|
27
|
+
"newusermessage",
|
|
28
|
+
"password",
|
|
24
29
|
"path",
|
|
25
30
|
"paths",
|
|
26
31
|
"prompt",
|
|
32
|
+
"refreshtoken",
|
|
27
33
|
"response",
|
|
28
34
|
"result",
|
|
29
|
-
"
|
|
35
|
+
"secret",
|
|
36
|
+
"systemprompt",
|
|
30
37
|
"text",
|
|
31
38
|
"thinking",
|
|
39
|
+
"token",
|
|
40
|
+
"url",
|
|
41
|
+
"uri",
|
|
42
|
+
"workspacepath",
|
|
32
43
|
]);
|
|
33
44
|
const ABSOLUTE_PATH_PATTERN = /(?:\/Users\/[^\s"'`]+|\/workspace\/[^\s"'`]+|\/tmp\/[^\s"'`]+|\/var\/folders\/[^\s"'`]+|[A-Za-z]:\\[^\s"'`]+)/;
|
|
34
45
|
const TOKEN_PATTERNS = [
|
|
@@ -54,12 +65,52 @@ export function createSentryInitOptions(dsn) {
|
|
|
54
65
|
},
|
|
55
66
|
};
|
|
56
67
|
}
|
|
68
|
+
export function reportUserFacingError(error, options) {
|
|
69
|
+
if (options.expected)
|
|
70
|
+
return undefined;
|
|
71
|
+
const exception = error instanceof Error ? error : new Error(String(error));
|
|
72
|
+
return Sentry.withScope((scope) => {
|
|
73
|
+
scope.setLevel(options.severity ?? "error");
|
|
74
|
+
scope.setTag("user_facing", "true");
|
|
75
|
+
scope.setTag("expected", "false");
|
|
76
|
+
scope.setTag("error_domain", options.domain);
|
|
77
|
+
scope.setTag("error_surface", options.surface);
|
|
78
|
+
scope.setTag("operation", options.operation);
|
|
79
|
+
setOptionalTag(scope, "platform", options.platform);
|
|
80
|
+
setOptionalTag(scope, "provider", options.provider);
|
|
81
|
+
setOptionalTag(scope, "model", options.model);
|
|
82
|
+
setOptionalTag(scope, "tool", options.toolName);
|
|
83
|
+
setOptionalTag(scope, "stop_reason", options.stopReason);
|
|
84
|
+
for (const [key, value] of Object.entries(options.tags ?? {})) {
|
|
85
|
+
if (value !== undefined)
|
|
86
|
+
scope.setTag(key, String(value));
|
|
87
|
+
}
|
|
88
|
+
if (options.fingerprint)
|
|
89
|
+
scope.setFingerprint(options.fingerprint);
|
|
90
|
+
scope.setContext("user_facing_error", {
|
|
91
|
+
domain: options.domain,
|
|
92
|
+
surface: options.surface,
|
|
93
|
+
operation: options.operation,
|
|
94
|
+
severity: options.severity ?? "error",
|
|
95
|
+
platform: options.platform,
|
|
96
|
+
provider: options.provider,
|
|
97
|
+
model: options.model,
|
|
98
|
+
toolName: options.toolName,
|
|
99
|
+
stopReason: options.stopReason,
|
|
100
|
+
...sanitizeValue(options.context ?? {}),
|
|
101
|
+
});
|
|
102
|
+
return Sentry.captureException(exception);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function setOptionalTag(scope, key, value) {
|
|
106
|
+
if (value !== undefined)
|
|
107
|
+
scope.setTag(key, value);
|
|
108
|
+
}
|
|
57
109
|
export function applyRunScope(scope, context) {
|
|
58
110
|
scope.setTag("conversation_id", context.conversationId);
|
|
59
111
|
scope.setTag("channel_id", context.conversationId);
|
|
60
112
|
scope.setTag("session_key", context.sessionKey);
|
|
61
113
|
scope.setTag("platform", context.platform);
|
|
62
|
-
scope.setTag("is_synthetic_event", String(Boolean(context.isSyntheticEvent)));
|
|
63
114
|
if (context.threadTs)
|
|
64
115
|
scope.setTag("thread_ts", context.threadTs);
|
|
65
116
|
if (context.provider)
|
|
@@ -79,7 +130,6 @@ export function applyRunScope(scope, context) {
|
|
|
79
130
|
platform: context.platform,
|
|
80
131
|
provider: context.provider,
|
|
81
132
|
model: context.model,
|
|
82
|
-
isSyntheticEvent: Boolean(context.isSyntheticEvent),
|
|
83
133
|
});
|
|
84
134
|
}
|
|
85
135
|
export function metricAttributes(attributes) {
|
|
@@ -179,7 +229,7 @@ function sanitizeRequest(request) {
|
|
|
179
229
|
function isSensitiveKey(key) {
|
|
180
230
|
if (!key)
|
|
181
231
|
return false;
|
|
182
|
-
return SENSITIVE_KEYS.has(key);
|
|
232
|
+
return SENSITIVE_KEYS.has(key.toLowerCase());
|
|
183
233
|
}
|
|
184
234
|
function summarizeValue(value, key) {
|
|
185
235
|
const label = key ?? "field";
|
package/dist/sentry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sentry.js","sourceRoot":"","sources":["../src/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\";\n\nconst REDACTED = \"[REDACTED]\";\nconst REDACTED_PATH = \"[REDACTED_PATH]\";\nconst MAX_STRING_LENGTH = 256;\nconst MAX_DEPTH = 4;\n\nconst SENSITIVE_KEYS = new Set([\n \"args\",\n \"attachment\",\n \"attachments\",\n \"authorization\",\n \"body\",\n \"content\",\n \"contents\",\n \"cookie\",\n \"cookies\",\n \"filePath\",\n \"headers\",\n \"image\",\n \"imageAttachments\",\n \"images\",\n \"localPath\",\n \"messages\",\n \"newUserMessage\",\n \"path\",\n \"paths\",\n \"prompt\",\n \"response\",\n \"result\",\n \"systemPrompt\",\n \"text\",\n \"thinking\",\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 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 isSyntheticEvent?: boolean;\n}\n\nexport function createSentryInitOptions(dsn?: string) {\n return {\n dsn,\n environment: process.env.SENTRY_ENVIRONMENT ?? \"production\",\n enabled: Boolean(dsn) && process.env.SENTRY_ENABLED !== \"false\",\n sendDefaultPii: false,\n tracesSampleRate: process.env.NODE_ENV === \"development\" ? 1.0 : 1.0,\n includeLocalVariables: false,\n enableLogs: true,\n beforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null {\n return sanitizeEvent(event, hint);\n },\n beforeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {\n return sanitizeBreadcrumb(breadcrumb);\n },\n };\n}\n\nexport function applyRunScope(scope: Scope, context: SentryRunScopeContext): void {\n scope.setTag(\"conversation_id\", context.conversationId);\n scope.setTag(\"channel_id\", context.conversationId);\n scope.setTag(\"session_key\", context.sessionKey);\n scope.setTag(\"platform\", context.platform);\n scope.setTag(\"is_synthetic_event\", String(Boolean(context.isSyntheticEvent)));\n if (context.threadTs) scope.setTag(\"thread_ts\", context.threadTs);\n if (context.provider) scope.setTag(\"provider\", context.provider);\n if (context.model) scope.setTag(\"model\", context.model);\n\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 isSyntheticEvent: Boolean(context.isSyntheticEvent),\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 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 isSensitiveKey(key?: string): boolean {\n if (!key) return false;\n return SENSITIVE_KEYS.has(key);\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/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\";\n\nconst REDACTED = \"[REDACTED]\";\nconst REDACTED_PATH = \"[REDACTED_PATH]\";\nconst MAX_STRING_LENGTH = 256;\nconst MAX_DEPTH = 4;\n\ntype SentryPrimitive = string | number | boolean;\n\nconst SENSITIVE_KEYS = new Set([\n \"accesstoken\",\n \"apikey\",\n \"args\",\n \"attachment\",\n \"attachments\",\n \"authorization\",\n \"body\",\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 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 UserFacingErrorDomain =\n | \"llm\"\n | \"chat_platform\"\n | \"mama\"\n | \"sandbox\"\n | \"login\"\n | \"events\"\n | \"session_view\";\n\nexport type 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\nexport function createSentryInitOptions(dsn?: string) {\n return {\n dsn,\n environment: process.env.SENTRY_ENVIRONMENT ?? \"production\",\n enabled: Boolean(dsn) && process.env.SENTRY_ENABLED !== \"false\",\n sendDefaultPii: false,\n tracesSampleRate: process.env.NODE_ENV === \"development\" ? 1.0 : 1.0,\n includeLocalVariables: false,\n enableLogs: true,\n beforeSend(event: ErrorEvent, hint: EventHint): ErrorEvent | null {\n return sanitizeEvent(event, hint);\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 applyRunScope(scope: Scope, context: SentryRunScopeContext): void {\n scope.setTag(\"conversation_id\", context.conversationId);\n scope.setTag(\"channel_id\", context.conversationId);\n scope.setTag(\"session_key\", context.sessionKey);\n scope.setTag(\"platform\", context.platform);\n if (context.threadTs) scope.setTag(\"thread_ts\", context.threadTs);\n if (context.provider) scope.setTag(\"provider\", context.provider);\n if (context.model) scope.setTag(\"model\", context.model);\n\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 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 isSensitiveKey(key?: string): boolean {\n if (!key) return false;\n return SENSITIVE_KEYS.has(key.toLowerCase());\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"]}
|