@nextclaw/kernel 0.1.14 → 0.1.15-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["readString","resolveAutoSessionLabel","isRecord","isTextLikePart","readRequestedAgentId","isRecord","isRecord","isRecord","readOptionalString","readString","readString","readRecord","readString","readRecord","readString","readRecord","readRequiredString","readString","mergeLoadPaths","isRecord","readOptionalString","isRecord","readOptionalString","readString","parseYaml","isRecord","readEventSessionId","readString","isRecord","isRecord","readString","fsConstants","isRecord","readOptionalString","readRequiredString","readOptionalString","readString","readOptionalString","ChannelManager","normalizeOptionalString","normalizeOptionalString"],"sources":["../src/managers/agent.manager.ts","../src/utils/session-run.utils.ts","../src/types/llm-usage.types.ts","../src/stores/llm-usage.store.ts","../src/managers/llm-usage.manager.ts","../src/utils/ncp-message-bridge.utils.ts","../src/features/native-runtime/utils/nextclaw-ncp-session-preferences.utils.ts","../src/features/native-runtime/utils/nextclaw-ncp-current-turn.utils.ts","../src/features/context-compaction/utils/context-compaction-timeline-message.utils.ts","../src/features/context-compaction/utils/context-compaction-projection.utils.ts","../src/features/context-compaction/managers/context-compaction.manager.ts","../src/managers/tool.manager.ts","../src/features/native-runtime/services/nextclaw-ncp-context-builder.service.ts","../src/features/native-runtime/services/provider-manager-ncp-llm-api.service.ts","../src/features/native-runtime/services/native-agent-runtime-factory.service.ts","../src/features/native-runtime/tools/ncp-asset.tools.ts","../src/managers/agent-run-request.manager.ts","../src/features/runtime-registry/services/agent-runtime-registry.service.ts","../src/managers/agent-runtime.manager.ts","../src/managers/automation.manager.ts","../src/managers/config.manager.ts","../src/features/extension-runtime/services/extension-lifecycle.service.ts","../src/features/extension-runtime/services/extension-manifest-discovery.service.ts","../src/features/extension-runtime/utils/extension-channel-catalog.utils.ts","../src/services/extension-runtime.service.ts","../src/features/extension-development-source/utils/first-party-plugin-load-paths.utils.ts","../src/features/extension-development-source/utils/dev-plugin-overrides.utils.ts","../src/services/extension-plugin-registry.service.ts","../src/managers/extension.manager.ts","../src/managers/llm-provider.manager.ts","../src/managers/mcp.manager.ts","../src/utils/ncp-agent-session-journal.utils.ts","../src/managers/ncp-session.manager.ts","../src/utils/skill-frontmatter.utils.ts","../src/managers/skill.manager.ts","../src/managers/session-run.manager.ts","../src/stores/ncp-agent-session-metadata.store.ts","../src/stores/ncp-agent-session-summary-index.store.ts","../src/stores/ncp-agent-session-journal.store.ts","../src/features/session-request/managers/session-request.manager.ts","../src/features/session-request/utils/agent-runtime-session-request-dispatcher.utils.ts","../src/features/narp-runtime/services/builtin-narp-runtime-provider.service.ts","../src/contributions/agent-runtime/index.ts","../src/contributions/learning-loop/config.ts","../src/contributions/learning-loop/utils/learning-loop-prompt.utils.ts","../src/contributions/learning-loop/index.ts","../src/contributions/session-context-window/index.ts","../src/contributions/session-activity-preview/utils/session-activity-preview-ncp-event.utils.ts","../src/contributions/session-activity-preview/utils/session-activity-preview-metadata.utils.ts","../src/contributions/session-activity-preview/index.ts","../src/tools/session-request.tools.ts","../src/tools/session-history.tools.ts","../src/tools/session-search.tools.ts","../src/tools/session-spawn.tools.ts","../src/contributions/tool-contribution/index.ts","../src/app/nextclaw-kernel.ts","../src/features/ncp-dispatch/utils/nextclaw-ncp-runner.utils.ts","../src/features/ncp-dispatch/utils/channel-reply.utils.ts","../src/features/ncp-dispatch/utils/ncp-run-metadata.utils.ts","../src/features/ncp-dispatch/services/gateway-inbound-processor.service.ts","../src/features/ncp-dispatch/utils/nextclaw-ncp-dispatch.utils.ts","../src/utils/ncp-session-message-adapter.utils.ts"],"sourcesContent":["import type { AgentRecord } from \"@kernel/types/agent.types.js\";\nimport type { AgentId, SkillId, ToolId } from \"@kernel/types/entity-ids.types.js\";\n\nexport class AgentManager {\n listAgents = () => {\n throw new Error(\"AgentManager.listAgents is not implemented.\");\n };\n\n getAgent = (agentId: AgentId) => {\n void agentId;\n throw new Error(\"AgentManager.getAgent is not implemented.\");\n };\n\n requireAgent = (agentId: AgentId) => {\n void agentId;\n throw new Error(\"AgentManager.requireAgent is not implemented.\");\n };\n\n saveAgent = (agent: AgentRecord) => {\n void agent;\n throw new Error(\"AgentManager.saveAgent is not implemented.\");\n };\n\n removeAgent = (agentId: AgentId) => {\n void agentId;\n throw new Error(\"AgentManager.removeAgent is not implemented.\");\n };\n\n attachSkill = (agentId: AgentId, skillId: SkillId) => {\n void agentId;\n void skillId;\n throw new Error(\"AgentManager.attachSkill is not implemented.\");\n };\n\n detachSkill = (agentId: AgentId, skillId: SkillId) => {\n void agentId;\n void skillId;\n throw new Error(\"AgentManager.detachSkill is not implemented.\");\n };\n\n attachTool = (agentId: AgentId, toolId: ToolId) => {\n void agentId;\n void toolId;\n throw new Error(\"AgentManager.attachTool is not implemented.\");\n };\n\n detachTool = (agentId: AgentId, toolId: ToolId) => {\n void agentId;\n void toolId;\n throw new Error(\"AgentManager.detachTool is not implemented.\");\n };\n}\n","import {\n NcpEventType,\n type NcpAgentConversationStateManager,\n type NcpAgentRuntime,\n type NcpAgentSendEnvelope,\n type NcpEndpointEvent,\n type NcpMessage,\n type NcpRequestEnvelope,\n type NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport type {\n AgentSessionRecord,\n} from \"@nextclaw/ncp-toolkit\";\n\nexport type LiveSessionExecution = {\n runId: string;\n controller: AbortController;\n requestEnvelope: MaterializedAgentRunRequest;\n abortHandled: boolean;\n closed: boolean;\n};\n\nexport type MaterializedAgentRunRequest = NcpRequestEnvelope & {\n runId: string;\n};\n\nexport type LiveSession = {\n sessionId: string;\n agentId?: string;\n stateManager: NcpAgentConversationStateManager;\n runtime: NcpAgentRuntime;\n activeExecution: LiveSessionExecution | null;\n};\n\nexport type PublishSessionEventOptions = {\n dispatchToStateManager?: boolean;\n persistSession?: boolean;\n};\n\nexport class AsyncEventQueue<T> {\n private readonly items: T[] = [];\n private readonly waiters: Array<(value: IteratorResult<T>) => void> = [];\n private closed = false;\n\n push = (item: T): void => {\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter({ value: item, done: false });\n return;\n }\n this.items.push(item);\n };\n\n close = (): void => {\n if (this.closed) {\n return;\n }\n this.closed = true;\n while (this.waiters.length > 0) {\n this.waiters.shift()?.({ value: undefined, done: true });\n }\n };\n\n iterate = (): AsyncGenerator<T> => {\n const nextItem = this.next;\n return (async function* iterateQueuedEvents() {\n while (true) {\n const next = await nextItem();\n if (next.done) {\n return;\n }\n yield next.value;\n }\n })();\n };\n\n private next = async (): Promise<IteratorResult<T>> => {\n const item = this.items.shift();\n if (item) {\n return { value: item, done: false };\n }\n if (this.closed) {\n return { value: undefined, done: true };\n }\n return new Promise((resolve) => {\n this.waiters.push(resolve);\n });\n };\n}\n\nexport function readString(value: unknown): string | undefined {\n const trimmed = typeof value === \"string\" ? value.trim() : \"\";\n return trimmed || undefined;\n}\n\nexport function readAgentId(metadata: Record<string, unknown> | null | undefined): string | undefined {\n return readString(metadata?.agent_id)?.toLowerCase() ?? readString(metadata?.agentId)?.toLowerCase();\n}\n\nexport function readMessageTask(message: NcpAgentSendEnvelope[\"message\"]): string {\n return message.parts.flatMap((part) => (\n (part.type === \"text\" || part.type === \"rich-text\" || part.type === \"reasoning\") &&\n part.text.trim() ? [part.text.trim()] : []\n ))[0] ?? \"Session\";\n}\n\nexport function readMetadataString(\n metadata: Record<string, unknown> | undefined,\n ...keys: string[]\n): string | undefined {\n return keys.map((key) => readString(metadata?.[key])).find(Boolean);\n}\n\nexport function withSession(envelope: NcpAgentSendEnvelope, sessionId: string): NcpRequestEnvelope {\n return { ...envelope, sessionId, message: { ...envelope.message, sessionId } };\n}\n\nexport function isTerminalRunEvent(event: NcpEndpointEvent): boolean {\n return event.type === NcpEventType.MessageCompleted || event.type === NcpEventType.MessageFailed || event.type === NcpEventType.RunError;\n}\n\nfunction readMessages(session: LiveSession): NcpMessage[] {\n const snapshot = session.stateManager.getSnapshot();\n const messages = snapshot.messages.map((message) => structuredClone(message));\n if (snapshot.streamingMessage && !messages.some((message) => message.id === snapshot.streamingMessage?.id)) {\n messages.push(structuredClone(snapshot.streamingMessage));\n }\n return messages;\n}\n\nfunction resolveAutoSessionLabel(messages: readonly NcpMessage[]): string | null {\n for (const message of messages) {\n if (message.role !== \"user\") {\n continue;\n }\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"rich-text\") {\n const text = readString(part.text);\n if (text) {\n return text.length > 64 ? `${text.slice(0, 64)}...` : text;\n }\n }\n }\n }\n return null;\n}\n\nfunction withAutoSessionLabel(params: {\n metadata: Record<string, unknown>;\n messages: readonly NcpMessage[];\n}): Record<string, unknown> {\n const { metadata, messages } = params;\n if (readString(metadata.label)) {\n return metadata;\n }\n const label = resolveAutoSessionLabel(messages);\n return label ? { ...metadata, label } : metadata;\n}\n\nexport function buildSessionRecord(session: LiveSession, updatedAt: string): AgentSessionRecord {\n const messages = readMessages(session);\n const requestMetadata = session.activeExecution?.requestEnvelope.metadata;\n const metadata = withAutoSessionLabel({\n metadata: {\n ...(requestMetadata ? structuredClone(requestMetadata) : {}),\n },\n messages,\n });\n const agentId = readString(session.agentId) ?? readAgentId(metadata);\n return {\n sessionId: session.sessionId,\n ...(agentId ? { agentId } : {}),\n messages,\n createdAt: updatedAt,\n updatedAt,\n metadata,\n };\n}\n\nexport function normalizeRunEvent(\n event: NcpEndpointEvent,\n envelope: NcpRequestEnvelope & { runId?: string },\n): NcpEndpointEvent {\n if (!(\"payload\" in event) || !event.payload || typeof event.payload !== \"object\") {\n return structuredClone(event);\n }\n const shouldAddRunId = Boolean(envelope.runId) &&\n (event.type === NcpEventType.RunStarted ||\n event.type === NcpEventType.RunFinished ||\n event.type === NcpEventType.RunError ||\n event.type === NcpEventType.RunMetadata);\n return structuredClone({\n ...event,\n payload: {\n ...event.payload,\n sessionId:\n \"sessionId\" in event.payload && typeof event.payload.sessionId === \"string\"\n ? event.payload.sessionId\n : envelope.sessionId,\n ...(envelope.correlationId &&\n (!(\"correlationId\" in event.payload) || typeof event.payload.correlationId !== \"string\")\n ? { correlationId: envelope.correlationId }\n : {}),\n ...(shouldAddRunId ? { runId: envelope.runId } : {}),\n },\n } as NcpEndpointEvent);\n}\n\nfunction findFinalAssistantMessage(session: LiveSession, messageId: string): NcpMessage | null {\n const normalizedMessageId = messageId.trim();\n if (!normalizedMessageId) {\n return null;\n }\n const messages = session.stateManager.getSnapshot().messages;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message?.id === normalizedMessageId && message.role === \"assistant\" && message.status === \"final\") {\n return structuredClone(message);\n }\n }\n return null;\n}\n\nexport function normalizeSendRunEvent(params: {\n session: LiveSession;\n event: NcpEndpointEvent;\n completedMessageSeen: boolean;\n}): {\n eventsToPublish: NcpEndpointEvent[];\n completedMessageSeen: boolean;\n} {\n const { event, session } = params;\n if (event.type === NcpEventType.MessageCompleted) {\n if (params.completedMessageSeen) {\n throw new Error(`Multiple final assistant messages were emitted for session \"${session.sessionId}\".`);\n }\n return { eventsToPublish: [event], completedMessageSeen: true };\n }\n if (event.type === NcpEventType.RunFinished) {\n if (params.completedMessageSeen) {\n return { eventsToPublish: [event], completedMessageSeen: true };\n }\n const messageId = event.payload.messageId?.trim();\n const message = messageId ? findFinalAssistantMessage(session, messageId) : null;\n if (!message) {\n throw new Error(`Run finished without a final assistant message for session \"${session.sessionId}\".`);\n }\n const correlationId = (event.payload as typeof event.payload & { correlationId?: string }).correlationId;\n return {\n eventsToPublish: [\n {\n type: NcpEventType.MessageCompleted,\n payload: {\n sessionId: session.sessionId,\n message,\n ...(correlationId ? { correlationId } : {}),\n },\n },\n event,\n ],\n completedMessageSeen: true,\n };\n }\n return {\n eventsToPublish: [event],\n completedMessageSeen: params.completedMessageSeen,\n };\n}\n\nexport function disposeRuntime(runtime: NcpAgentRuntime): Promise<void> | void {\n return (runtime as { dispose?: () => Promise<void> | void }).dispose?.();\n}\n\nexport function consumeRunHandle(\n events: AsyncIterable<NcpEndpointEvent>,\n fallback: NcpRunHandle,\n): Promise<NcpRunHandle> {\n let resolved = false;\n let handle = fallback;\n return new Promise<NcpRunHandle>((resolve, reject) => {\n const resolveOnce = (): void => {\n if (resolved) {\n return;\n }\n resolved = true;\n resolve(handle);\n };\n void (async () => {\n try {\n for await (const event of events) {\n if (event.type === NcpEventType.RunStarted) {\n handle = {\n ...handle,\n assistantMessageId: event.payload.messageId ?? null,\n runId: event.payload.runId ?? null,\n };\n resolveOnce();\n }\n }\n resolveOnce();\n } catch (error) {\n if (!resolved) {\n reject(error);\n }\n }\n })();\n });\n}\n","export type LlmUsageSummary = {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n cachedTokens: number;\n cacheHit: boolean;\n cacheMetricKeys: string[];\n};\n\nexport type LlmUsageRecord = {\n version: 1;\n observedAt: string;\n source: string;\n model: string | null;\n usage: Record<string, number>;\n summary: LlmUsageSummary;\n};\n\nexport type LlmUsageSnapshot = LlmUsageRecord;\n\nexport function createLlmUsageRecord(params: {\n observedAt?: string;\n source: string;\n model?: string | null;\n usage: Record<string, number>;\n}): LlmUsageRecord {\n const { observedAt, source, model, usage: rawUsage } = params;\n const usage = sanitizeLlmUsage(rawUsage);\n return {\n version: 1,\n observedAt: observedAt ?? new Date().toISOString(),\n source,\n model: normalizeLlmUsageModel(model),\n usage,\n summary: buildLlmUsageSummary(usage),\n };\n}\n\nexport function sanitizeLlmUsage(\n usage: Record<string, number>,\n): Record<string, number> {\n const next: Record<string, number> = {};\n for (const [key, value] of Object.entries(usage)) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n continue;\n }\n next[key] = Math.floor(value);\n }\n return next;\n}\n\nexport function hasLlmUsageTelemetry(usage: Record<string, number>): boolean {\n return Object.keys(usage).length > 0;\n}\n\nexport function buildLlmUsageSummary(\n usage: Record<string, number>,\n): LlmUsageSummary {\n const promptTokens = usage.prompt_tokens ?? usage.input_tokens ?? 0;\n const completionTokens = usage.completion_tokens ?? usage.output_tokens ?? 0;\n const totalTokens = usage.total_tokens ?? (promptTokens + completionTokens);\n const cacheMetricKeys = Object.keys(usage).filter((key) =>\n key.endsWith(\"cached_tokens\")\n );\n const cachedTokens = cacheMetricKeys.reduce(\n (max, key) => Math.max(max, usage[key] ?? 0),\n 0,\n );\n return {\n promptTokens,\n completionTokens,\n totalTokens,\n cachedTokens,\n cacheHit: cachedTokens > 0,\n cacheMetricKeys,\n };\n}\n\nexport function normalizeLlmUsageModel(\n value: string | null | undefined,\n): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n","import { appendFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { getDataDir } from \"@nextclaw/core\";\nimport type { LlmUsageRecord } from \"@kernel/types/llm-usage.types.js\";\n\nexport type LlmUsageStoreOptions = {\n snapshotPath?: string;\n historyPath?: string;\n};\n\nexport class LlmUsageStore {\n constructor(private readonly options: LlmUsageStoreOptions = {}) {}\n\n get snapshotPath(): string {\n return this.options.snapshotPath ?? resolve(getDataDir(), \"run\", \"llm-usage.json\");\n }\n\n get historyPath(): string {\n return this.options.historyPath ?? resolve(getDataDir(), \"logs\", \"llm-usage.jsonl\");\n }\n\n readSnapshot = (): LlmUsageRecord | null => {\n if (!existsSync(this.snapshotPath)) {\n return null;\n }\n try {\n const raw = readFileSync(this.snapshotPath, \"utf-8\");\n return JSON.parse(raw) as LlmUsageRecord;\n } catch {\n return null;\n }\n };\n\n writeSnapshot = (snapshot: LlmUsageRecord): void => {\n mkdirSync(dirname(this.snapshotPath), { recursive: true });\n writeFileSync(this.snapshotPath, JSON.stringify(snapshot, null, 2));\n };\n\n clearSnapshot = (): void => {\n if (existsSync(this.snapshotPath)) {\n rmSync(this.snapshotPath, { force: true });\n }\n };\n\n listHistory = (): LlmUsageRecord[] => {\n if (!existsSync(this.historyPath)) {\n return [];\n }\n try {\n const raw = readFileSync(this.historyPath, \"utf-8\");\n return raw\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .flatMap((line) => {\n try {\n return [JSON.parse(line) as LlmUsageRecord];\n } catch {\n return [];\n }\n });\n } catch {\n return [];\n }\n };\n\n appendHistory = (record: LlmUsageRecord): void => {\n mkdirSync(dirname(this.historyPath), { recursive: true });\n appendFileSync(this.historyPath, `${JSON.stringify(record)}\\n`);\n };\n\n clearHistory = (): void => {\n if (existsSync(this.historyPath)) {\n rmSync(this.historyPath, { force: true });\n }\n };\n}\n","import type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport {\n createLlmUsageRecord,\n hasLlmUsageTelemetry,\n type LlmUsageRecord,\n} from \"@kernel/types/llm-usage.types.js\";\nimport { LlmUsageStore } from \"@kernel/stores/llm-usage.store.js\";\n\ntype ProviderChatParams = Parameters<LlmProviderRuntime[\"chat\"]>[0];\n\nexport type LlmUsageStats = {\n totalRecords: number;\n usageRecordCount: number;\n emptyUsageRecordCount: number;\n promptTokenRecordCount: number;\n oldestObservedAt: string | null;\n latestObservedAt: string | null;\n totalPromptTokens: number;\n totalCompletionTokens: number;\n totalTokens: number;\n totalCachedTokens: number;\n cacheHitRecords: number;\n cacheHitRate: number;\n tokenCacheRate: number;\n sources: Array<{ value: string; count: number }>;\n models: Array<{ value: string; count: number }>;\n};\n\nexport type LlmUsageManagerOptions = {\n store?: LlmUsageStore;\n};\n\nclass ObservedLlmProviderRuntime implements LlmProviderRuntime {\n constructor(\n private readonly delegate: LlmProviderRuntime,\n private readonly manager: LlmUsageManager,\n private readonly source: string,\n ) {}\n\n get = (model?: string | null) => {\n return this.delegate.get(model);\n };\n\n chat = async (params: ProviderChatParams) => {\n const response = await this.delegate.chat(params);\n this.manager.record({\n source: this.source,\n model: params.model ?? null,\n usage: response.usage,\n });\n return response;\n };\n\n chatStream = async function* (\n this: ObservedLlmProviderRuntime,\n params: ProviderChatParams,\n ) {\n for await (const event of this.delegate.chatStream(params)) {\n if (event.type === \"done\") {\n this.manager.record({\n source: this.source,\n model: params.model ?? null,\n usage: event.response.usage,\n });\n }\n yield event;\n }\n };\n}\n\nexport class LlmUsageManager {\n private readonly store: LlmUsageStore;\n\n constructor(options: LlmUsageManagerOptions = {}) {\n this.store = options.store ?? new LlmUsageStore();\n }\n\n get snapshotPath(): string {\n return this.store.snapshotPath;\n }\n\n get historyPath(): string {\n return this.store.historyPath;\n }\n\n observeProviderManager = (\n providerManager: LlmProviderRuntime,\n source: string,\n ): LlmProviderRuntime => {\n return new ObservedLlmProviderRuntime(providerManager, this, source);\n };\n\n record = (params: {\n observedAt?: string;\n source: string;\n model?: string | null;\n usage: Record<string, number>;\n }): LlmUsageRecord | null => {\n const record = createLlmUsageRecord(params);\n if (!hasLlmUsageTelemetry(record.usage)) {\n return null;\n }\n this.store.writeSnapshot(record);\n this.store.appendHistory(record);\n return record;\n };\n\n getSnapshot = (): LlmUsageRecord | null => {\n return this.store.readSnapshot();\n };\n\n getHistory = (limit?: string | number): LlmUsageRecord[] => {\n const records = this.store.listHistory();\n const resolvedLimit = this.resolveHistoryLimit(limit);\n return records.slice(-resolvedLimit).reverse();\n };\n\n resolveHistoryLimit = (value?: string | number): number => {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return Math.floor(value);\n }\n if (typeof value === \"string\" && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed) && parsed > 0) {\n return Math.floor(parsed);\n }\n }\n return 10;\n };\n\n getStats = (): LlmUsageStats => {\n const records = this.store.listHistory();\n const sources = new Map<string, number>();\n const models = new Map<string, number>();\n let totalPromptTokens = 0;\n let totalCompletionTokens = 0;\n let totalTokens = 0;\n let totalCachedTokens = 0;\n let cacheHitRecords = 0;\n let usageRecordCount = 0;\n let promptTokenRecordCount = 0;\n\n for (const record of records) {\n const hasUsage = Object.keys(record.usage).length > 0;\n if (hasUsage) {\n usageRecordCount += 1;\n }\n totalPromptTokens += record.summary.promptTokens;\n totalCompletionTokens += record.summary.completionTokens;\n totalTokens += record.summary.totalTokens;\n totalCachedTokens += record.summary.cachedTokens;\n if (record.summary.promptTokens > 0) {\n promptTokenRecordCount += 1;\n }\n if (record.summary.cacheHit) {\n cacheHitRecords += 1;\n }\n this.bumpCounter(sources, record.source);\n this.bumpCounter(models, record.model ?? \"unknown\");\n }\n\n return {\n totalRecords: records.length,\n usageRecordCount,\n emptyUsageRecordCount: records.length - usageRecordCount,\n promptTokenRecordCount,\n oldestObservedAt: records[0]?.observedAt ?? null,\n latestObservedAt: records.at(-1)?.observedAt ?? null,\n totalPromptTokens,\n totalCompletionTokens,\n totalTokens,\n totalCachedTokens,\n cacheHitRecords,\n cacheHitRate: promptTokenRecordCount > 0 ? cacheHitRecords / promptTokenRecordCount : 0,\n tokenCacheRate: totalPromptTokens > 0 ? totalCachedTokens / totalPromptTokens : 0,\n sources: this.toSortedCounts(sources),\n models: this.toSortedCounts(models),\n };\n };\n\n private readonly bumpCounter = (map: Map<string, number>, value: string): void => {\n map.set(value, (map.get(value) ?? 0) + 1);\n };\n\n private readonly toSortedCounts = (map: Map<string, number>): Array<{ value: string; count: number }> => {\n return [...map.entries()]\n .map(([value, count]) => ({ value, count }))\n .sort((left, right) => {\n if (right.count !== left.count) {\n return right.count - left.count;\n }\n return left.value.localeCompare(right.value);\n });\n };\n}\n","import type { InboundAttachment, SessionMessage } from \"@nextclaw/core\";\nimport { buildNcpUserContent, type LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n type NcpMessage,\n type NcpMessagePart,\n type NcpToolInvocationPart,\n sanitizeAssistantReplyTags,\n} from \"@nextclaw/ncp\";\n\nexport function normalizeString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function cloneMetadata(value: unknown): Record<string, unknown> | undefined {\n return isRecord(value) ? structuredClone(value) : undefined;\n}\n\nexport function readStringArray(value: unknown): string[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n const deduped = new Set<string>();\n for (const item of value) {\n const normalized = normalizeString(item);\n if (normalized) {\n deduped.add(normalized);\n }\n }\n return [...deduped];\n}\n\nexport function mergeSessionMetadata(\n currentMetadata: Record<string, unknown>,\n inputMetadata?: Record<string, unknown>,\n): Record<string, unknown> {\n if (!inputMetadata) {\n return currentMetadata;\n }\n\n const nextMetadata = {\n ...currentMetadata,\n ...structuredClone(inputMetadata),\n };\n const model =\n normalizeString(inputMetadata.model) ??\n normalizeString(inputMetadata.preferred_model) ??\n normalizeString(inputMetadata.preferredModel);\n if (model) {\n nextMetadata.model = model;\n nextMetadata.preferred_model = model;\n }\n\n const thinking =\n normalizeString(inputMetadata.thinking) ??\n normalizeString(inputMetadata.preferred_thinking) ??\n normalizeString(inputMetadata.thinking_level) ??\n normalizeString(inputMetadata.thinkingLevel);\n if (thinking) {\n nextMetadata.thinking = thinking;\n nextMetadata.preferred_thinking = thinking;\n }\n\n const sessionType =\n normalizeString(inputMetadata.session_type) ?? normalizeString(inputMetadata.sessionType);\n if (sessionType) {\n nextMetadata.session_type = sessionType;\n }\n\n const label =\n normalizeString(inputMetadata.label) ?? normalizeString(inputMetadata.session_label);\n if (label) {\n nextMetadata.label = label;\n }\n\n const requestedSkills =\n readStringArray(inputMetadata.requested_skills) ??\n readStringArray(inputMetadata.requestedSkills);\n if (requestedSkills) {\n nextMetadata.requested_skills = requestedSkills;\n }\n\n return nextMetadata;\n}\n\nexport function extractMessageMetadata(messages: NcpMessage[]): Record<string, unknown> | undefined {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message?.role !== \"user\") {\n continue;\n }\n const metadata = cloneMetadata(message.metadata);\n if (metadata) {\n return metadata;\n }\n }\n return undefined;\n}\n\nexport function ensureIsoTimestamp(value: unknown, fallback: string): string {\n if (typeof value !== \"string\") {\n return fallback;\n }\n const timestamp = Date.parse(value);\n if (!Number.isFinite(timestamp)) {\n return fallback;\n }\n return new Date(timestamp).toISOString();\n}\n\nfunction serializeToolArgs(args: unknown): string {\n if (typeof args === \"string\") {\n return args;\n }\n return JSON.stringify(args ?? {});\n}\n\nfunction serializeLegacyContent(parts: NcpMessagePart[]): unknown {\n const text = parts\n .filter(isTextLikePart)\n .map((part) => part.text)\n .join(\"\");\n if (text.length > 0) {\n return text;\n }\n if (parts.length === 0) {\n return \"\";\n }\n return structuredClone(parts);\n}\n\nexport function extractTextFromNcpMessage(message: NcpMessage | undefined): string {\n if (!message) {\n return \"\";\n }\n const normalizedMessage = message.role === \"assistant\" ? sanitizeAssistantReplyTags(message) : message;\n return normalizedMessage.parts\n .filter(isTextLikePart)\n .map((part) => part.text)\n .join(\"\");\n}\n\nfunction isTextLikePart(part: NcpMessagePart): part is Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }> {\n return part.type === \"text\" || part.type === \"rich-text\";\n}\n\nfunction guessImageMime(pathOrUrl: string | null): string | null {\n if (!pathOrUrl) {\n return null;\n }\n const normalized = pathOrUrl.trim().toLowerCase();\n if (normalized.endsWith(\".png\")) return \"image/png\";\n if (normalized.endsWith(\".jpg\") || normalized.endsWith(\".jpeg\")) return \"image/jpeg\";\n if (normalized.endsWith(\".gif\")) return \"image/gif\";\n if (normalized.endsWith(\".webp\")) return \"image/webp\";\n if (normalized.endsWith(\".bmp\")) return \"image/bmp\";\n if (normalized.endsWith(\".tif\") || normalized.endsWith(\".tiff\")) return \"image/tiff\";\n return null;\n}\n\nfunction isRenderableImageFilePart(part: NcpMessagePart): part is Extract<NcpMessagePart, { type: \"file\" }> {\n if (part.type !== \"file\") {\n return false;\n }\n const mimeType = normalizeString(part.mimeType);\n if (mimeType?.startsWith(\"image/\")) {\n return true;\n }\n return Boolean(guessImageMime(normalizeString(part.url) ?? normalizeString(part.name)));\n}\n\nfunction resolveImageUrl(part: Extract<NcpMessagePart, { type: \"file\" }>): string | null {\n const url = normalizeString(part.url);\n if (url) {\n return url;\n }\n const mimeType = normalizeString(part.mimeType);\n const contentBase64 = normalizeString(part.contentBase64);\n if (!mimeType || !contentBase64) {\n return null;\n }\n return `data:${mimeType};base64,${contentBase64}`;\n}\n\ntype LegacyContentBuildOptions = {\n assetStore?: LocalAssetStore | null;\n serviceRole?: \"service\" | \"system\";\n};\n\nexport function buildLegacyUserContent(\n parts: NcpMessagePart[],\n options: LegacyContentBuildOptions = {},\n): unknown {\n const content = buildNcpUserContent(parts, {\n assetStore: options.assetStore,\n });\n if (content === \"\") {\n return serializeLegacyContent(parts);\n }\n return content;\n}\n\nexport function extractAttachmentsFromNcpMessage(message: NcpMessage | undefined): InboundAttachment[] {\n if (!message) {\n return [];\n }\n\n const attachments: InboundAttachment[] = [];\n for (const part of message.parts) {\n if (!isRenderableImageFilePart(part)) {\n continue;\n }\n const imageUrl = resolveImageUrl(part);\n if (!imageUrl) {\n continue;\n }\n attachments.push({\n name: normalizeString(part.name) ?? undefined,\n url: imageUrl,\n mimeType: normalizeString(part.mimeType) ?? guessImageMime(normalizeString(part.url) ?? normalizeString(part.name)) ?? undefined,\n size: typeof part.sizeBytes === \"number\" ? part.sizeBytes : undefined,\n source: \"ncp\",\n status: \"remote-only\",\n });\n }\n return attachments;\n}\n\nfunction buildLegacyAssistantMessages(message: NcpMessage, timestamp: string): SessionMessage[] {\n const textContent = extractTextFromNcpMessage(message);\n const reasoningParts = message.parts.filter(\n (part): part is Extract<NcpMessagePart, { type: \"reasoning\" }> => part.type === \"reasoning\"\n );\n const reasoningContent = reasoningParts.map((part) => part.text).join(\"\");\n const toolInvocations = message.parts.filter(\n (part): part is NcpToolInvocationPart => part.type === \"tool-invocation\"\n );\n\n const assistantMessage: SessionMessage = {\n role: \"assistant\",\n content: textContent,\n timestamp,\n ncp_message_id: message.id,\n ncp_parts: structuredClone(message.parts),\n };\n if (typeof message.metadata?.reply_to === \"string\" && message.metadata.reply_to.trim().length > 0) {\n assistantMessage.reply_to = message.metadata.reply_to.trim();\n }\n if (reasoningParts.length > 0) {\n assistantMessage.reasoning_content = reasoningContent;\n }\n if (toolInvocations.length > 0) {\n assistantMessage.tool_calls = toolInvocations.map((toolInvocation, index) => ({\n id: toolInvocation.toolCallId ?? `${message.id}:tool:${index}`,\n type: \"function\",\n function: {\n name: toolInvocation.toolName,\n arguments: serializeToolArgs(toolInvocation.args),\n },\n }));\n }\n\n const messages: SessionMessage[] = [assistantMessage];\n for (const toolInvocation of toolInvocations) {\n if (toolInvocation.state !== \"result\") {\n continue;\n }\n messages.push({\n role: \"tool\",\n name: toolInvocation.toolName,\n tool_call_id: toolInvocation.toolCallId,\n content:\n typeof toolInvocation.result === \"string\"\n ? toolInvocation.result\n : JSON.stringify(toolInvocation.result ?? null),\n ...(toolInvocation.resultContentItems\n ? { ncp_tool_result_content_items: structuredClone(toolInvocation.resultContentItems) }\n : {}),\n timestamp,\n ncp_message_id: message.id,\n });\n }\n return messages;\n}\n\nfunction buildLegacyNonAssistantMessage(\n message: NcpMessage,\n timestamp: string,\n options: LegacyContentBuildOptions,\n): SessionMessage {\n const role = message.role === \"service\" && options.serviceRole === \"system\" ? \"system\" : message.role;\n return {\n role,\n content: buildLegacyUserContent(message.parts, options),\n timestamp,\n ncp_message_id: message.id,\n ncp_parts: structuredClone(message.parts),\n ...(message.metadata ? { ncp_metadata: structuredClone(message.metadata) } : {}),\n };\n}\n\nexport function toLegacyMessages(\n messages: NcpMessage[],\n options: LegacyContentBuildOptions = {},\n): SessionMessage[] {\n const legacyMessages: SessionMessage[] = [];\n\n for (const rawMessage of messages) {\n const message = rawMessage.role === \"assistant\" ? sanitizeAssistantReplyTags(rawMessage) : rawMessage;\n const timestamp = ensureIsoTimestamp(message.timestamp, new Date().toISOString());\n\n if (message.role === \"assistant\") {\n legacyMessages.push(...buildLegacyAssistantMessages(message, timestamp));\n continue;\n }\n\n legacyMessages.push(buildLegacyNonAssistantMessage(message, timestamp, options));\n }\n\n return legacyMessages;\n}\n","import { parseThinkingLevel, type ThinkingLevel } from \"@nextclaw/core\";\n\nexport function normalizeOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function readMetadataModel(metadata: Record<string, unknown>): string | null {\n const candidates = [metadata.model, metadata.llm_model, metadata.agent_model, metadata.session_model];\n for (const candidate of candidates) {\n const normalized = normalizeOptionalString(candidate);\n if (normalized) {\n return normalized;\n }\n }\n return null;\n}\n\nexport function readMetadataThinking(metadata: Record<string, unknown>): ThinkingLevel | \"__clear__\" | null {\n const candidates = [\n metadata.thinking,\n metadata.thinking_level,\n metadata.thinkingLevel,\n metadata.thinking_effort,\n metadata.thinkingEffort,\n ];\n for (const candidate of candidates) {\n if (typeof candidate !== \"string\") {\n continue;\n }\n const normalized = candidate.trim().toLowerCase();\n if (!normalized) {\n continue;\n }\n if (normalized === \"clear\" || normalized === \"reset\" || normalized === \"off!\") {\n return \"__clear__\";\n }\n const level = parseThinkingLevel(normalized);\n if (level) {\n return level;\n }\n }\n return null;\n}\n\nexport function resolveEffectiveModel(params: {\n sessionMetadata: Record<string, unknown>;\n requestMetadata: Record<string, unknown>;\n fallbackModel: string;\n}): { metadata: Record<string, unknown>; model: string } {\n const { fallbackModel, requestMetadata } = params;\n const metadata = structuredClone(params.sessionMetadata);\n const clearModel =\n requestMetadata.clear_model === true ||\n requestMetadata.reset_model === true;\n if (clearModel) {\n delete metadata.preferred_model;\n }\n\n const inboundModel = readMetadataModel(requestMetadata);\n if (inboundModel) {\n metadata.preferred_model = inboundModel;\n }\n\n return {\n metadata,\n model: normalizeOptionalString(metadata.preferred_model) ?? fallbackModel,\n };\n}\n\nexport function syncSessionThinkingPreference(params: {\n sessionMetadata: Record<string, unknown>;\n requestMetadata: Record<string, unknown>;\n}): Record<string, unknown> {\n const { requestMetadata } = params;\n const metadata = structuredClone(params.sessionMetadata);\n const clearThinking =\n requestMetadata.clear_thinking === true ||\n requestMetadata.reset_thinking === true;\n if (clearThinking) {\n delete metadata.preferred_thinking;\n }\n\n const inboundThinking = readMetadataThinking(requestMetadata);\n if (inboundThinking === \"__clear__\") {\n delete metadata.preferred_thinking;\n return metadata;\n }\n if (inboundThinking) {\n metadata.preferred_thinking = inboundThinking;\n }\n return metadata;\n}\n\nexport function resolveSessionChannelContext(params: {\n sessionMetadata: Record<string, unknown>;\n requestMetadata: Record<string, unknown>;\n}): { channel: string; chatId: string; metadata: Record<string, unknown> } {\n const { requestMetadata } = params;\n const metadata = structuredClone(params.sessionMetadata);\n const channel =\n normalizeOptionalString(requestMetadata.channel) ??\n normalizeOptionalString(metadata.last_channel) ??\n \"ui\";\n const chatId =\n normalizeOptionalString(requestMetadata.chatId) ??\n normalizeOptionalString(requestMetadata.chat_id) ??\n normalizeOptionalString(metadata.last_to) ??\n \"web-ui\";\n\n metadata.last_channel = channel;\n metadata.last_to = chatId;\n return { channel, chatId, metadata };\n}\n","import type { NcpAgentRunInput, NcpMessage, NcpMessagePart } from \"@nextclaw/ncp\";\nimport type { LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n buildLegacyUserContent,\n ensureIsoTimestamp,\n extractTextFromNcpMessage,\n} from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nfunction isTextLikePart(part: NcpMessagePart): part is Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }> {\n return part.type === \"text\" || part.type === \"rich-text\";\n}\n\nfunction collectTextPartIndexes(parts: NcpMessagePart[]): number[] {\n return parts\n .map((part, index) => (isTextLikePart(part) ? index : -1))\n .filter((index) => index >= 0);\n}\n\nfunction replaceTextPartsWithSingleFormattedText(\n parts: NcpMessagePart[],\n textPartIndexes: number[],\n formattedText: string,\n): NcpMessagePart[] {\n const nextParts = structuredClone(parts);\n const firstTextIndex = textPartIndexes[0];\n const firstTextPart = nextParts[firstTextIndex];\n if (firstTextPart && isTextLikePart(firstTextPart)) {\n firstTextPart.text = formattedText;\n }\n\n return nextParts.filter((part, index) => {\n if (!isTextLikePart(part)) {\n return true;\n }\n return index === firstTextIndex && part.text.length > 0;\n });\n}\n\nfunction wrapTextPartsWithFormattedEdges(params: {\n parts: NcpMessagePart[];\n textPartIndexes: number[];\n prefix: string;\n suffix: string;\n}): NcpMessagePart[] {\n const { parts, prefix, suffix, textPartIndexes } = params;\n const nextParts = structuredClone(parts);\n const firstTextIndex = textPartIndexes[0];\n const lastTextIndex = textPartIndexes[textPartIndexes.length - 1];\n\n for (const index of textPartIndexes) {\n const part = nextParts[index];\n if (!part || !isTextLikePart(part)) {\n continue;\n }\n if (index === firstTextIndex) {\n part.text = `${prefix}${part.text}`;\n }\n if (index === lastTextIndex) {\n part.text = `${part.text}${suffix}`;\n }\n }\n\n return nextParts;\n}\n\nfunction buildFormattedCurrentParts(params: {\n message: NcpMessage | undefined;\n formattedText: string;\n originalText: string;\n}): NcpMessagePart[] {\n const { formattedText, message, originalText } = params;\n const parts = message?.parts ?? [];\n if (parts.length === 0) {\n return formattedText.length > 0 ? [{ type: \"text\", text: formattedText }] : [];\n }\n\n const textPartIndexes = collectTextPartIndexes(parts);\n if (textPartIndexes.length === 0) {\n return formattedText.length > 0\n ? [{ type: \"text\", text: formattedText }, ...structuredClone(parts)]\n : structuredClone(parts);\n }\n\n if (formattedText === originalText) {\n return structuredClone(parts);\n }\n\n const originalTextIndex = formattedText.indexOf(originalText);\n if (originalText.length === 0 || originalTextIndex < 0) {\n return replaceTextPartsWithSingleFormattedText(parts, textPartIndexes, formattedText);\n }\n\n return wrapTextPartsWithFormattedEdges({\n parts,\n textPartIndexes,\n prefix: formattedText.slice(0, originalTextIndex),\n suffix: formattedText.slice(originalTextIndex + originalText.length),\n });\n}\n\nexport function findLatestUserMessage(input: NcpAgentRunInput): NcpMessage | undefined {\n return (\n input.messages\n .slice()\n .reverse()\n .find((message) => message.role === \"user\") ??\n input.messages[input.messages.length - 1]\n );\n}\n\nexport function buildCurrentTurnState(params: {\n input: NcpAgentRunInput;\n currentModel: string;\n formatPrompt: (params: { text: string; timestamp: Date }) => string;\n assetStore?: LocalAssetStore | null;\n}): {\n currentRole: \"user\" | \"system\";\n currentUserContent: unknown;\n effectiveModel: string;\n} {\n const { assetStore, currentModel, formatPrompt, input } = params;\n const latestUserMessage = findLatestUserMessage(input);\n const originalText = extractTextFromNcpMessage(latestUserMessage);\n const formattedText = formatPrompt({\n text: originalText,\n timestamp: new Date(\n ensureIsoTimestamp(\n latestUserMessage?.timestamp,\n new Date().toISOString(),\n ),\n ),\n });\n const currentParts = buildFormattedCurrentParts({\n message: latestUserMessage,\n formattedText,\n originalText,\n });\n\n return {\n currentRole: latestUserMessage?.role === \"system\" ? \"system\" : \"user\",\n currentUserContent: buildLegacyUserContent(currentParts, {\n assetStore,\n }),\n effectiveModel: currentModel,\n };\n}\n","import type { Session, SessionEvent, SessionMessage } from \"@nextclaw/core\";\nimport type { NcpMessage } from \"@nextclaw/ncp\";\n\nexport const NEXTCLAW_TIMELINE_KIND_METADATA_KEY = \"nextclaw_timeline_kind\";\nexport const CONTEXT_COMPACTION_TIMELINE_KIND = \"context_compaction\";\n\nexport type ContextCompactionTimelineCheckpoint = {\n version: 1;\n id: string;\n status: \"compressing\" | \"compressed\";\n summary: string;\n coveredMessageCount: number;\n coveredSessionMessageCount: number;\n originalEstimatedTokens: number;\n projectedEstimatedTokens: number;\n createdAt: string;\n updatedAt: string;\n};\n\ntype ContextCompactionTimelineMetadata = {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: typeof CONTEXT_COMPACTION_TIMELINE_KIND;\n checkpoint: ContextCompactionTimelineCheckpoint;\n};\n\nfunction readTimelineMetadata(message: SessionMessage | null | undefined): ContextCompactionTimelineMetadata | null {\n const rawMetadata = message?.ncp_metadata;\n if (!rawMetadata || typeof rawMetadata !== \"object\" || Array.isArray(rawMetadata)) {\n return null;\n }\n const metadata = rawMetadata as Record<string, unknown>;\n if (metadata[NEXTCLAW_TIMELINE_KIND_METADATA_KEY] !== CONTEXT_COMPACTION_TIMELINE_KIND) {\n return null;\n }\n const checkpoint =\n metadata.checkpoint && typeof metadata.checkpoint === \"object\" && !Array.isArray(metadata.checkpoint)\n ? (metadata.checkpoint as ContextCompactionTimelineCheckpoint)\n : null;\n if (!checkpoint) {\n return null;\n }\n return {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: CONTEXT_COMPACTION_TIMELINE_KIND,\n checkpoint,\n };\n}\n\nfunction buildTimelineMessage(checkpoint: ContextCompactionTimelineCheckpoint): SessionMessage {\n return {\n role: \"service\",\n content:\n checkpoint.status === \"compressing\"\n ? \"正在压缩较早上下文\"\n : \"较早上下文已自动压缩\",\n timestamp: checkpoint.updatedAt,\n ncp_parts: [\n {\n type: \"text\",\n text:\n checkpoint.status === \"compressing\"\n ? \"正在压缩较早上下文\"\n : \"较早上下文已自动压缩\",\n },\n ],\n ncp_metadata: {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: CONTEXT_COMPACTION_TIMELINE_KIND,\n checkpoint,\n },\n };\n}\n\nexport function buildContextCompactionTimelineNcpMessage(params: {\n sessionId: string;\n checkpoint: ContextCompactionTimelineCheckpoint;\n}): NcpMessage {\n const { checkpoint, sessionId } = params;\n const text =\n checkpoint.status === \"compressing\"\n ? \"正在压缩较早上下文\"\n : \"较早上下文已自动压缩\";\n return {\n id: `${sessionId}:service:context-compaction:${checkpoint.id}`,\n sessionId,\n role: \"service\",\n status: \"final\",\n timestamp: checkpoint.updatedAt,\n parts: [{ type: \"text\", text }],\n metadata: {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: CONTEXT_COMPACTION_TIMELINE_KIND,\n checkpoint,\n },\n };\n}\n\nexport function upsertContextCompactionTimelineMessage(params: {\n session: Session;\n checkpoint: ContextCompactionTimelineCheckpoint;\n insertBeforeMessageIds?: readonly string[];\n}): void {\n const { checkpoint, insertBeforeMessageIds = [], session } = params;\n const nextMessage = buildTimelineMessage(checkpoint);\n for (let index = session.events.length - 1; index >= 0; index -= 1) {\n const event = session.events[index];\n const message =\n event?.data?.message && typeof event.data.message === \"object\" && !Array.isArray(event.data.message)\n ? (event.data.message as SessionMessage)\n : null;\n const metadata = readTimelineMetadata(message);\n if (!metadata) {\n continue;\n }\n event.timestamp = checkpoint.updatedAt;\n event.data.message = nextMessage;\n session.messages = session.messages.map((item) => {\n const itemMetadata = readTimelineMetadata(item);\n return itemMetadata?.checkpoint.id === metadata.checkpoint.id ? nextMessage : item;\n });\n session.updatedAt = new Date(checkpoint.updatedAt);\n return;\n }\n\n const event: SessionEvent = {\n seq: session.nextSeq,\n type: \"message.service\",\n timestamp: checkpoint.updatedAt,\n data: {\n message: nextMessage,\n },\n };\n session.nextSeq += 1;\n const insertionIds = new Set(insertBeforeMessageIds);\n const messageIndex = session.messages.findIndex(\n (message) => typeof message.ncp_message_id === \"string\" && insertionIds.has(message.ncp_message_id),\n );\n if (messageIndex >= 0) {\n session.messages.splice(messageIndex, 0, nextMessage);\n } else {\n session.messages.push(nextMessage);\n }\n const eventIndex = session.events.findIndex((candidateEvent) => {\n const message =\n candidateEvent?.data?.message && typeof candidateEvent.data.message === \"object\" && !Array.isArray(candidateEvent.data.message)\n ? (candidateEvent.data.message as SessionMessage)\n : null;\n return typeof message?.ncp_message_id === \"string\" && insertionIds.has(message.ncp_message_id);\n });\n if (eventIndex >= 0) {\n session.events.splice(eventIndex, 0, event);\n } else {\n session.events.push(event);\n }\n session.updatedAt = new Date(checkpoint.updatedAt);\n}\n\nexport function isContextCompactionTimelineMessage(message: { metadata?: Record<string, unknown> | undefined } | null | undefined): boolean {\n return message?.metadata?.[NEXTCLAW_TIMELINE_KIND_METADATA_KEY] === CONTEXT_COMPACTION_TIMELINE_KIND;\n}\n","import type { NcpMessage } from \"@nextclaw/ncp\";\nimport { readCompressedContextCompactionCheckpoint } from \"@nextclaw/core\";\nimport { CONTEXT_COMPACTION_TIMELINE_KIND, NEXTCLAW_TIMELINE_KIND_METADATA_KEY } from \"./context-compaction-timeline-message.utils.js\";\n\nfunction readCompactionSummary(message: NcpMessage): string | null {\n const metadata = message.metadata;\n if (metadata?.[NEXTCLAW_TIMELINE_KIND_METADATA_KEY] !== CONTEXT_COMPACTION_TIMELINE_KIND) {\n return null;\n }\n const checkpoint = readCompressedContextCompactionCheckpoint(metadata.checkpoint);\n return checkpoint?.summary ?? null;\n}\n\nexport function projectNcpMessagesWithContextCompaction(params: {\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n}): NcpMessage[] {\n const { sessionId, sessionMessages } = params;\n let checkpointIndex = -1;\n let summary = \"\";\n for (let index = sessionMessages.length - 1; index >= 0; index -= 1) {\n const candidateSummary = readCompactionSummary(sessionMessages[index] as NcpMessage);\n if (!candidateSummary) {\n continue;\n }\n checkpointIndex = index;\n summary = candidateSummary;\n break;\n }\n\n if (checkpointIndex < 0) {\n return sessionMessages\n .filter((message) => !readCompactionSummary(message))\n .map((message) => structuredClone(message));\n }\n\n return [\n {\n id: `${sessionId}:context-compaction-summary:${sessionMessages[checkpointIndex]?.id ?? \"latest\"}`,\n sessionId,\n role: \"user\",\n status: \"final\",\n timestamp: sessionMessages[checkpointIndex]?.timestamp ?? new Date().toISOString(),\n parts: [{ type: \"text\", text: summary }],\n },\n ...sessionMessages\n .slice(checkpointIndex + 1)\n .filter((message) => !readCompactionSummary(message))\n .map((message) => structuredClone(message)),\n ];\n}\n","import {\n findEffectiveAgentProfile,\n type ContextCompactionCheckpoint,\n type ContextCompactionPlan,\n ContextCompactionService,\n ContextWindowBudgetService,\n type ContextWindowBudgetEvaluation,\n buildContextWindowSnapshot,\n buildCompressingCompactionCheckpoint,\n CONTEXT_COMPACTION_METADATA_KEY,\n readCompressedContextCompactionCheckpoint,\n resolveDefaultAgentProfileId,\n type Config,\n type ContextWindowSnapshot,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport {\n type NcpAgentRunInput,\n type NcpEndpointEvent,\n type NcpMessage,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport type { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport type { LiveSession } from \"@kernel/utils/session-run.utils.js\";\nimport {\n normalizeString,\n toLegacyMessages,\n} from \"@kernel/utils/ncp-message-bridge.utils.js\";\nimport {\n buildContextCompactionTimelineNcpMessage,\n isContextCompactionTimelineMessage,\n} from \"@kernel/features/context-compaction/utils/context-compaction-timeline-message.utils.js\";\nimport { projectNcpMessagesWithContextCompaction } from \"@kernel/features/context-compaction/utils/context-compaction-projection.utils.js\";\n\ntype ContextCompactionResult = {\n contextWindow: ContextWindowSnapshot;\n metadataPatch: Record<string, unknown>;\n sessionMessages: NcpMessage[];\n timelineMessage: NcpMessage | null;\n};\n\ntype ContextCompactionBeginResult = ContextCompactionResult & {\n pendingCompaction: ContextCompactionPendingWork | null;\n};\n\ntype ContextCompactionPendingWork = {\n checkpoint: ReturnType<typeof buildCompressingCompactionCheckpoint>;\n contextTokens: number;\n inputMessageIds: string[];\n model: string;\n plan: ContextCompactionPlan;\n reservedContextTokens: number;\n sessionId: string;\n sessionMessages: NcpMessage[];\n};\n\nconst SUMMARY_MAX_TOKENS = 4000;\nconst SUMMARY_SOURCE_MAX_CHARS = 120_000;\n\ntype ResolvedCompactionProfile = {\n contextTokens: number;\n model: string;\n reservedContextTokens: number;\n};\n\nfunction readRequestedAgentId(metadata: Record<string, unknown>): string | null {\n return normalizeString(metadata.agent_id)?.toLowerCase() ?? normalizeString(metadata.agentId)?.toLowerCase() ?? null;\n}\n\nfunction resolveCompactionProfile(params: {\n config: Config;\n requestMetadata: Record<string, unknown>;\n storedAgentId?: string;\n}): ResolvedCompactionProfile {\n const { config, requestMetadata, storedAgentId } = params;\n const { defaults } = config.agents;\n const defaultAgentId = resolveDefaultAgentProfileId(config);\n const agentId =\n normalizeString(storedAgentId)?.toLowerCase() ??\n readRequestedAgentId(requestMetadata) ??\n defaultAgentId;\n const profile =\n findEffectiveAgentProfile(config, agentId) ??\n findEffectiveAgentProfile(config, defaultAgentId);\n return {\n contextTokens: profile?.contextTokens ?? defaults.contextTokens,\n model: profile?.model ?? defaults.model,\n reservedContextTokens: ContextWindowBudgetService.resolveReservedContextTokens({\n contextTokens: profile?.contextTokens ?? defaults.contextTokens,\n configuredReservedContextTokens: profile?.reservedContextTokens ?? defaults.reservedContextTokens,\n }),\n };\n}\n\nfunction mergeInputMessages(params: {\n inputMessages: readonly NcpMessage[];\n sessionMessages: readonly NcpMessage[];\n}): NcpMessage[] {\n const messages = params.sessionMessages.map((message) => structuredClone(message));\n const seen = new Set(messages.map((message) => message.id));\n for (const message of params.inputMessages) {\n if (seen.has(message.id)) {\n continue;\n }\n messages.push(structuredClone(message));\n }\n return messages;\n}\n\nfunction stringifyCompactionSource(messages: readonly Record<string, unknown>[]): string {\n const json = JSON.stringify(messages, null, 2);\n if (json.length <= SUMMARY_SOURCE_MAX_CHARS) {\n return json;\n }\n return `${json.slice(0, SUMMARY_SOURCE_MAX_CHARS).trimEnd()}\\n[truncated_source]`;\n}\n\nfunction buildContextWindowSnapshotFromBudget(params: {\n budget: ContextWindowBudgetEvaluation;\n checkpoint: ContextCompactionCheckpoint | null;\n totalContextTokens: number;\n}): ContextWindowSnapshot {\n const { budget, checkpoint, totalContextTokens } = params;\n return buildContextWindowSnapshot({\n usedContextTokens: budget.estimatedTokens,\n totalContextTokens,\n prunedUsedContextTokens: budget.estimatedTokens,\n droppedHistoryCount: budget.droppedHistoryCount,\n truncatedToolResultCount: budget.truncatedToolResultCount,\n truncatedSystemPrompt: budget.truncatedSystemPrompt,\n truncatedUserMessage: budget.truncatedUserMessage,\n checkpoint,\n compactedUsedContextTokens: checkpoint ? budget.estimatedTokens : undefined,\n });\n}\n\nfunction buildContextWindowSnapshotForMessages(\n contextWindowBudgetService: ContextWindowBudgetService,\n params: {\n checkpoint: ReturnType<typeof readCompressedContextCompactionCheckpoint>;\n contextTokens: number;\n reservedContextTokens: number;\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n },\n): ContextWindowSnapshot {\n const { checkpoint, contextTokens, reservedContextTokens, sessionId, sessionMessages } = params;\n const modelCandidateMessages = sessionMessages.filter(\n (message) => !isContextCompactionTimelineMessage(message),\n );\n const projectedMessages = checkpoint\n ? projectNcpMessagesWithContextCompaction({\n sessionId,\n sessionMessages,\n })\n : modelCandidateMessages;\n const messages = toLegacyMessages(projectedMessages) as Record<string, unknown>[];\n const budget = contextWindowBudgetService.evaluate({\n messages,\n contextTokens,\n reservedContextTokens,\n });\n return buildContextWindowSnapshotFromBudget({\n budget,\n checkpoint,\n totalContextTokens: contextTokens,\n });\n}\n\nexport class ContextWindowPreviewManager {\n private readonly contextWindowBudgetService = new ContextWindowBudgetService();\n\n constructor(\n private readonly options: {\n configManager: ConfigManager;\n },\n ) {}\n\n preview = (params: {\n requestMetadata: Record<string, unknown>;\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n storedAgentId?: string;\n storedMetadata: Record<string, unknown>;\n }): ContextWindowSnapshot | null => {\n const {\n requestMetadata,\n sessionId,\n sessionMessages,\n storedAgentId,\n storedMetadata,\n } = params;\n const metadata = storedMetadata;\n const profile = resolveCompactionProfile({\n config: this.options.configManager.loadConfig(),\n requestMetadata,\n storedAgentId,\n });\n const existingCheckpoint = readCompressedContextCompactionCheckpoint(\n metadata[CONTEXT_COMPACTION_METADATA_KEY],\n );\n return buildContextWindowSnapshotForMessages(this.contextWindowBudgetService, {\n checkpoint: existingCheckpoint,\n contextTokens: profile.contextTokens,\n reservedContextTokens: profile.reservedContextTokens,\n sessionId,\n sessionMessages,\n });\n };\n}\n\nexport class ContextCompactionManager {\n private readonly compactionService = new ContextCompactionService();\n private readonly contextWindowBudgetService = new ContextWindowBudgetService();\n\n constructor(\n private readonly options: {\n configManager: ConfigManager;\n providerManager?: LlmProviderRuntime;\n sessionRunManager: SessionRunManager;\n },\n ) {}\n\n runLivePreflight = async function* (\n this: ContextCompactionManager,\n params: {\n input: NcpAgentRunInput;\n session: LiveSession;\n },\n ): AsyncIterable<NcpEndpointEvent> {\n const sessionRunManager = this.options.sessionRunManager;\n const { input, session } = params;\n const beginResult = this.begin({\n inputMessages: input.messages,\n requestMetadata: input.metadata ?? {},\n sessionId: input.sessionId,\n sessionMessages: session.stateManager.getSnapshot().messages,\n ...(session.agentId ? { storedAgentId: session.agentId } : {}),\n storedMetadata: input.metadata ?? {},\n });\n yield* this.applyLivePreflightResult({ input, result: beginResult, session, sessionRunManager });\n if (!beginResult.pendingCompaction) {\n return;\n }\n const finishResult = await this.finish(beginResult.pendingCompaction);\n yield* this.applyLivePreflightResult({ input, result: finishResult, session, sessionRunManager });\n };\n\n private begin = (params: {\n inputMessages: readonly NcpMessage[];\n requestMetadata: Record<string, unknown>;\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n storedAgentId?: string;\n storedMetadata: Record<string, unknown>;\n }): ContextCompactionBeginResult => {\n const {\n inputMessages,\n requestMetadata,\n sessionId,\n sessionMessages,\n storedAgentId,\n storedMetadata,\n } = params;\n const profile = resolveCompactionProfile({\n config: this.options.configManager.loadConfig(),\n requestMetadata,\n storedAgentId,\n });\n const { contextTokens, reservedContextTokens } = profile;\n const ncpMessages = mergeInputMessages({\n inputMessages,\n sessionMessages,\n });\n const modelCandidateMessages = ncpMessages.filter(\n (message) => !isContextCompactionTimelineMessage(message),\n );\n const existingCheckpoint = readCompressedContextCompactionCheckpoint(\n storedMetadata[CONTEXT_COMPACTION_METADATA_KEY],\n );\n const projectedMessages = existingCheckpoint\n ? projectNcpMessagesWithContextCompaction({\n sessionId,\n sessionMessages: ncpMessages,\n })\n : modelCandidateMessages;\n const messages = toLegacyMessages(projectedMessages) as Record<string, unknown>[];\n const budget = this.contextWindowBudgetService.evaluate({\n messages,\n contextTokens,\n reservedContextTokens,\n });\n const plan = existingCheckpoint || !budget.shouldCompact\n ? null\n : this.compactionService.prepareForModelInput({\n messages: budget.messages,\n contextTokens,\n compactionThresholdTokens: budget.triggerTokens,\n });\n const checkpoint = plan\n ? {\n ...buildCompressingCompactionCheckpoint(\n storedMetadata[CONTEXT_COMPACTION_METADATA_KEY],\n ),\n coveredMessageCount: plan.coveredMessages.length,\n coveredSessionMessageCount: plan.coveredMessages.length,\n originalEstimatedTokens: plan.originalEstimatedTokens,\n projectedEstimatedTokens: budget.estimatedTokens,\n }\n : existingCheckpoint;\n\n const contextWindow = buildContextWindowSnapshotFromBudget({\n budget,\n checkpoint,\n totalContextTokens: contextTokens,\n });\n return {\n contextWindow,\n metadataPatch: plan && checkpoint\n ? { [CONTEXT_COMPACTION_METADATA_KEY]: checkpoint }\n : {},\n sessionMessages: ncpMessages,\n timelineMessage: plan && checkpoint\n ? buildContextCompactionTimelineNcpMessage({\n sessionId,\n checkpoint,\n })\n : null,\n pendingCompaction: plan && checkpoint\n ? {\n checkpoint,\n contextTokens,\n inputMessageIds: inputMessages.map((message) => message.id),\n model: profile.model,\n plan,\n reservedContextTokens,\n sessionId,\n sessionMessages: ncpMessages,\n }\n : null,\n };\n };\n\n private finish = async (\n pending: ContextCompactionPendingWork,\n ): Promise<ContextCompactionResult> => {\n const compacted = await this.compactionService.compactPreparedForModelInput({\n contextTokens: pending.contextTokens,\n plan: pending.plan,\n generateSummary: async ({ messages }) =>\n await this.generateSummary({\n messages,\n model: pending.model,\n }),\n });\n const generatedCheckpoint = compacted.checkpoint;\n if (!generatedCheckpoint) {\n throw new Error(\"context compaction pending work did not produce a checkpoint\");\n }\n const checkpoint = {\n ...generatedCheckpoint,\n id: pending.checkpoint.id,\n createdAt: pending.checkpoint.createdAt,\n status: \"compressed\" as const,\n };\n const budget = this.contextWindowBudgetService.evaluate({\n messages: compacted.messages,\n contextTokens: pending.contextTokens,\n reservedContextTokens: pending.reservedContextTokens,\n });\n const contextWindow = buildContextWindowSnapshotFromBudget({\n budget,\n checkpoint,\n totalContextTokens: pending.contextTokens,\n });\n return {\n contextWindow,\n metadataPatch: {\n [CONTEXT_COMPACTION_METADATA_KEY]: checkpoint,\n },\n sessionMessages: pending.sessionMessages,\n timelineMessage: buildContextCompactionTimelineNcpMessage({\n sessionId: pending.sessionId,\n checkpoint,\n }),\n };\n };\n\n private generateSummary = async (params: {\n messages: Record<string, unknown>[];\n model: string;\n }): Promise<string> => {\n if (!this.options.providerManager) {\n throw new Error(\"context compaction summary generation requires a provider manager\");\n }\n const { messages, model } = params;\n const response = await this.options.providerManager.chat({\n model,\n maxTokens: SUMMARY_MAX_TOKENS,\n messages: [\n {\n role: \"system\",\n content: [\n \"You are NextClaw's context compactor for a coding agent session.\",\n \"Create a dense, structured summary that will replace earlier conversation history in a future model request.\",\n \"Preserve user goals, explicit instructions, decisions, files touched or inspected, code changes, commands run, test results, failures, blockers, and exact next steps.\",\n \"Do not invent facts. If something is uncertain, mark it as uncertain.\",\n \"Return Markdown only. Start with '# Compressed Earlier Context'.\",\n ].join(\"\\n\"),\n },\n {\n role: \"user\",\n content: [\n \"Compress these earlier runtime messages into a reusable checkpoint summary.\",\n \"\",\n \"Messages JSON:\",\n stringifyCompactionSource(messages),\n ].join(\"\\n\"),\n },\n ],\n });\n const summary = response.content?.trim();\n if (!summary) {\n throw new Error(\"context compaction summary is empty\");\n }\n return summary;\n };\n\n private applyLivePreflightResult = async function* (\n this: ContextCompactionManager,\n params: {\n input: NcpAgentRunInput;\n result: ContextCompactionResult;\n session: LiveSession;\n sessionRunManager: SessionRunManager;\n },\n ): AsyncIterable<NcpEndpointEvent> {\n const { input, result, session, sessionRunManager } = params;\n if (Object.keys(result.metadataPatch).length > 0) {\n await sessionRunManager.updateSessionMetadata(session.sessionId, result.metadataPatch);\n }\n const contextWindowEvent = {\n type: NcpEventType.ContextWindowUpdated,\n payload: {\n sessionId: input.sessionId,\n contextWindow: result.contextWindow,\n },\n } as const;\n await sessionRunManager.appendSessionEvent(session.sessionId, contextWindowEvent);\n yield contextWindowEvent;\n if (!result.timelineMessage) {\n return;\n }\n const activeRun = session.stateManager.getSnapshot().activeRun;\n session.stateManager.hydrate({\n sessionId: input.sessionId,\n messages: result.sessionMessages,\n activeRun,\n contextWindow: result.contextWindow,\n });\n const timelineEvent = {\n type: NcpEventType.MessageSent,\n payload: {\n sessionId: input.sessionId,\n message: result.timelineMessage,\n },\n } as const;\n await sessionRunManager.appendSessionEvent(session.sessionId, timelineEvent);\n yield timelineEvent;\n };\n}\n","import {\n ToolRegistry,\n createToolExecutionContext,\n type Config,\n type ExtensionToolContext,\n type SearchConfig,\n type Tool,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpTool, NcpToolDefinition, NcpToolRegistry } from \"@nextclaw/ncp\";\nimport { isRecord } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nexport type UpdateToolCallResult = (params: {\n sessionId: string;\n toolCallId: string;\n result: unknown;\n}) => Promise<void>;\n\nexport type ToolRunContext = {\n agentId: string;\n channel: string;\n chatId: string;\n config: Config;\n execTimeoutSeconds: number;\n handoffDepth: number;\n metadata: Record<string, unknown>;\n restrictToWorkspace: boolean;\n searchConfig: SearchConfig;\n sessionId: string;\n workspace: string;\n};\n\nexport type ToolRegistrationContext = {\n registerTool: (tool: Tool) => void;\n registerNcpTool: (tool: NcpTool) => void;\n hasTool: (name: string) => boolean;\n getExtensionToolRunContext: () => ExtensionToolContext;\n};\n\nexport type ToolProvider = {\n id: string;\n registerTools: (context: ToolRunContext, registry: ToolRegistrationContext) => void;\n};\n\nexport type ToolRuntimeRegistryOptions = {\n updateToolCallResult: UpdateToolCallResult;\n};\n\nexport type ToolRuntimeRegistry = NcpToolRegistry & {\n prepareForRun: (context: ToolRunContext) => void;\n};\n\nfunction toToolParams(args: unknown): Record<string, unknown> {\n if (isRecord(args)) {\n return args;\n }\n if (typeof args === \"string\") {\n try {\n const parsed = JSON.parse(args) as unknown;\n return isRecord(parsed) ? parsed : {};\n } catch {\n return {};\n }\n }\n return {};\n}\n\nclass CoreToolNcpAdapter implements NcpTool {\n constructor(private readonly tool: Tool, private readonly executeTool: (toolName: string, args: unknown) => Promise<unknown>) {}\n\n get name(): string {\n return this.tool.name;\n }\n\n get description(): string {\n return this.tool.description;\n }\n\n get parameters(): Record<string, unknown> {\n return this.tool.parameters;\n }\n\n execute = async (args: unknown): Promise<unknown> => {\n return this.executeTool(this.tool.name, args);\n };\n}\n\nclass RuntimeToolRegistry implements ToolRuntimeRegistry {\n private registry = new ToolRegistry();\n private readonly tools = new Map<string, NcpTool>();\n private currentExtensionToolContext: ExtensionToolContext = {};\n\n constructor(\n private readonly getProviders: () => ToolProvider[],\n private readonly options: ToolRuntimeRegistryOptions,\n ) {}\n\n prepareForRun = (context: ToolRunContext): void => {\n const {\n channel,\n chatId,\n config,\n restrictToWorkspace,\n sessionId,\n workspace,\n } = context;\n this.currentExtensionToolContext = {\n config,\n workspaceDir: workspace,\n sessionKey: sessionId,\n channel,\n chatId,\n sandboxed: restrictToWorkspace,\n };\n\n this.registry = new ToolRegistry();\n this.tools.clear();\n\n const registrationContext = this.createRegistrationContext();\n for (const provider of this.getProviders()) {\n provider.registerTools(context, registrationContext);\n }\n };\n\n listTools = (): ReadonlyArray<NcpTool> => {\n return [...this.tools.values()].filter((tool) => this.isToolAvailable(tool.name));\n };\n\n getTool = (name: string): NcpTool | undefined => {\n if (!this.isToolAvailable(name)) {\n return undefined;\n }\n return this.tools.get(name);\n };\n\n getToolDefinitions = (): ReadonlyArray<NcpToolDefinition> => {\n return this.listTools().map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }));\n };\n\n execute = async (toolCallId: string, toolName: string, args: unknown): Promise<unknown> => {\n if (this.registry.has(toolName)) {\n return this.registry.executeRaw(\n toolName,\n toToolParams(args),\n this.buildToolExecutionContext(toolCallId),\n );\n }\n return this.tools.get(toolName)?.execute(args);\n };\n\n private buildToolExecutionContext = (toolCallId: string): ToolExecutionContext => {\n const sessionId = this.currentExtensionToolContext.sessionKey;\n return createToolExecutionContext({\n toolCallId,\n updateToolCallResult: async (result: unknown) => {\n if (!sessionId) {\n return;\n }\n await this.options.updateToolCallResult({\n sessionId,\n toolCallId,\n result,\n });\n },\n });\n };\n\n private createRegistrationContext = (): ToolRegistrationContext => ({\n registerTool: this.registerTool,\n registerNcpTool: this.registerNcpTool,\n hasTool: (name) => this.tools.has(name),\n getExtensionToolRunContext: () => this.currentExtensionToolContext,\n });\n\n private registerTool = (tool: Tool): void => {\n this.registry.register(tool);\n this.tools.set(\n tool.name,\n new CoreToolNcpAdapter(tool, async (toolName, args) =>\n this.registry.execute(toolName, toToolParams(args)),\n ),\n );\n };\n\n private registerNcpTool = (tool: NcpTool): void => {\n if (this.tools.has(tool.name)) {\n return;\n }\n this.tools.set(tool.name, tool);\n };\n\n private isToolAvailable = (name: string): boolean => {\n const coreTool = this.registry.get(name);\n return coreTool ? coreTool.isAvailable() : true;\n };\n}\n\nexport class ToolManager {\n private readonly providers = new Map<string, ToolProvider>();\n\n provideTools = (provider: ToolProvider): { dispose: () => void } => {\n if (this.providers.has(provider.id)) {\n throw new Error(`Tool provider is already registered: ${provider.id}`);\n }\n this.providers.set(provider.id, provider);\n return {\n dispose: () => {\n if (this.providers.get(provider.id) === provider) {\n this.providers.delete(provider.id);\n }\n },\n };\n };\n\n createRuntimeRegistry = (options: ToolRuntimeRegistryOptions): ToolRuntimeRegistry => {\n return new RuntimeToolRegistry(() => [...this.providers.values()], options);\n };\n\n}\n\nexport function resolveAgentHandoffDepth(metadata: Record<string, unknown>): number {\n const rawDepth = Number(metadata.agent_handoff_depth ?? 0);\n if (!Number.isFinite(rawDepth) || rawDepth < 0) {\n return 0;\n }\n return Math.trunc(rawDepth);\n}\n","import {\n buildToolCatalogEntries,\n buildMinimalSystemExecutionPrompt,\n ContextBuilder,\n ContextWindowBudgetService,\n findEffectiveAgentProfile,\n InputBudgetPruner,\n RequestedSkillsMetadataReader,\n getWorkspacePath,\n parseThinkingLevel,\n readSessionProjectRoot,\n resolveDefaultAgentProfileId,\n resolveSessionWorkspacePath,\n resolveThinkingLevel,\n type Config,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport {\n buildOpenAiFunctionTool,\n type LocalAssetStore,\n} from \"@nextclaw/ncp-agent-runtime\";\nimport type {\n NcpAgentRunInput,\n NcpContextBuilder,\n NcpContextPrepareOptions,\n NcpLLMApiInput,\n NcpToolDefinition,\n OpenAIChatMessage,\n OpenAITool,\n} from \"@nextclaw/ncp\";\nimport {\n normalizeString,\n toLegacyMessages,\n} from \"@kernel/utils/ncp-message-bridge.utils.js\";\nimport {\n resolveEffectiveModel,\n resolveSessionChannelContext,\n} from \"@kernel/features/native-runtime/utils/nextclaw-ncp-session-preferences.utils.js\";\nimport { buildCurrentTurnState } from \"@kernel/features/native-runtime/utils/nextclaw-ncp-current-turn.utils.js\";\nimport { projectNcpMessagesWithContextCompaction } from \"@kernel/features/context-compaction/index.js\";\nimport {\n resolveAgentHandoffDepth,\n type ToolRuntimeRegistry,\n} from \"@kernel/managers/tool.manager.js\";\n\ntype NextclawNcpContextBuilderOptions = {\n agentId?: string;\n toolRegistry: ToolRuntimeRegistry;\n configManager: ConfigManager;\n assetStore?: LocalAssetStore | null;\n};\n\ntype ResolvedAgentProfile = {\n agentId: string;\n contextTokens: number;\n execTimeoutSeconds: number;\n model: string;\n reservedContextTokens: number;\n restrictToWorkspace: boolean;\n searchConfig: Config[\"search\"];\n workspace: string;\n};\n\ntype PreparedRunContext = {\n channel: string;\n chatId: string;\n config: Config;\n currentTurn: ReturnType<typeof buildCurrentTurnState>;\n effectiveModel: string;\n effectiveWorkspace: string;\n profile: ResolvedAgentProfile;\n requestMetadata: Record<string, unknown>;\n requestedSkills: ReturnType<RequestedSkillsMetadataReader[\"readSelection\"]>;\n requestedToolNames: string[];\n runtimeThinking: ReturnType<typeof resolveThinkingLevel>;\n sessionMetadata: Record<string, unknown>;\n sessionKey: string;\n};\n\ntype BuiltNcpModelMessages = {\n messages: Record<string, unknown>[];\n toolDefinitions: readonly NcpToolDefinition[];\n};\n\nconst TIME_HINT_TRIGGER_PATTERNS = [\n /\\b(now|right now|current time|what time|today|tonight|tomorrow|yesterday|this morning|this afternoon|this evening|date)\\b/i,\n /(现在|此刻|当前时间|现在几点|几点了|今天|今晚|今早|今晨|明天|昨天|日期)/,\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction mergeInputMetadata(input: NcpAgentRunInput): Record<string, unknown> {\n const messageMetadata = input.messages\n .slice()\n .reverse()\n .find((message) => isRecord(message.metadata))?.metadata;\n return {\n ...(isRecord(messageMetadata) ? structuredClone(messageMetadata) : {}),\n ...(isRecord(input.metadata) ? structuredClone(input.metadata) : {}),\n };\n}\n\nconst REQUESTED_SKILLS_METADATA_READER = new RequestedSkillsMetadataReader();\n\nfunction resolveRequestedToolNames(metadata: Record<string, unknown>): string[] {\n const rawValue = metadata.requested_tools ?? metadata.requestedTools;\n if (!Array.isArray(rawValue)) {\n return [];\n }\n return Array.from(\n new Set(\n rawValue\n .map((item) => normalizeString(item))\n .filter((item): item is string => Boolean(item)),\n ),\n );\n}\n\nfunction readRequestedAgentId(metadata: Record<string, unknown>): string | null {\n return normalizeString(metadata.agent_id)?.toLowerCase() ?? normalizeString(metadata.agentId)?.toLowerCase() ?? null;\n}\n\nfunction resolveAgentProfile(params: {\n config: Config;\n storedAgentId?: string;\n requestMetadata: Record<string, unknown>;\n}): ResolvedAgentProfile {\n const { config, requestMetadata, storedAgentId } = params;\n const {\n agents: { defaults },\n search: searchConfig,\n tools: {\n restrictToWorkspace,\n exec: { timeout: execTimeoutSeconds },\n },\n } = config;\n const defaultAgentId = resolveDefaultAgentProfileId(config);\n const candidateAgentId =\n normalizeString(storedAgentId)?.toLowerCase() ??\n readRequestedAgentId(requestMetadata) ??\n defaultAgentId;\n const profile =\n findEffectiveAgentProfile(config, candidateAgentId) ??\n findEffectiveAgentProfile(config, defaultAgentId);\n if (!profile) {\n throw new Error(`default agent profile not found: ${defaultAgentId}`);\n }\n const contextTokens = profile.contextTokens ?? defaults.contextTokens;\n return {\n agentId: profile.id,\n workspace: getWorkspacePath(profile.workspace ?? defaults.workspace),\n model: profile.model ?? defaults.model,\n contextTokens,\n reservedContextTokens: ContextWindowBudgetService.resolveReservedContextTokens({\n contextTokens,\n configuredReservedContextTokens: profile.reservedContextTokens ?? defaults.reservedContextTokens,\n }),\n restrictToWorkspace,\n searchConfig,\n execTimeoutSeconds,\n };\n}\n\nfunction shouldAppendTimeHint(content: string): boolean {\n const normalized = content.trim();\n if (!normalized) {\n return false;\n }\n return TIME_HINT_TRIGGER_PATTERNS.some((pattern) => pattern.test(normalized));\n}\n\nfunction buildMinutePrecisionTimeHint(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hour = String(date.getHours()).padStart(2, \"0\");\n const minute = String(date.getMinutes()).padStart(2, \"0\");\n const offsetMinutes = -date.getTimezoneOffset();\n const sign = offsetMinutes >= 0 ? \"+\" : \"-\";\n const absMinutes = Math.abs(offsetMinutes);\n const offsetHour = String(Math.floor(absMinutes / 60)).padStart(2, \"0\");\n const offsetMinute = String(absMinutes % 60).padStart(2, \"0\");\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || \"local\";\n return `${year}-${month}-${day} ${hour}:${minute} ${sign}${offsetHour}:${offsetMinute} (${timezone})`;\n}\n\nfunction appendTimeHintForPrompt(content: string, timestamp: Date): string {\n if (!shouldAppendTimeHint(content)) {\n return content;\n }\n const date = Number.isNaN(timestamp.getTime()) ? new Date() : timestamp;\n return `${content}\\n\\n[time_hint_local_minute] ${buildMinutePrecisionTimeHint(date)}`;\n}\n\nfunction prependRequestedSkills(content: string, requestedSkillSelectors: string[]): string {\n if (requestedSkillSelectors.length === 0) {\n return content;\n }\n return `[Requested skills for this turn: ${requestedSkillSelectors.join(\", \")}]\\n\\n${content}`;\n}\n\nfunction buildSessionOrchestrationSection(): string {\n return [\n \"## Session Orchestration\",\n \"- Before passing a non-default `runtime` to `sessions_spawn` or agent creation/update flows, inspect the installed runtime kinds with `nextclaw agents runtimes --json`.\",\n \"- `sessions_spawn` is the unified session-creation tool. Omit `scope` or use `scope=\\\"standalone\\\"` for a regular session, and use `scope=\\\"child\\\"` when the new session should be a child session of the current flow.\",\n \"- `sessions_spawn` only creates the session by default. Add top-level `notify: \\\"none\\\" | \\\"final_reply\\\"` when the new session should start working immediately.\",\n \"- When `sessions_spawn.scope=\\\"child\\\"` and `sessions_spawn.notify=\\\"final_reply\\\"`, the new child session starts right away and this session automatically continues after that child reaches its final reply.\",\n \"- Use `sessions_spawn` without `notify` when the user wants a separate thread created now but does not need it to start working yet.\",\n \"- Use `sessions_request` to send one task to an existing session, including a session that was just created by `sessions_spawn` or a previously created child session.\",\n \"- `sessions_request.target` must be an object shaped like `{ \\\"session_id\\\": \\\"<target-session-id>\\\" }`. Do not pass a bare string.\",\n \"- Prefer `notify=\\\"final_reply\\\"` when the current session should continue after the target session produces its final reply. Use `notify=\\\"none\\\"` when you only want the target session to run independently.\",\n ].join(\"\\n\");\n}\n\nfunction buildRequestedOpenAiTools(\n toolDefinitions: ReadonlyArray<NcpToolDefinition>,\n requestedToolNames: string[],\n): OpenAITool[] | undefined {\n const tools = toolDefinitions.map(buildOpenAiFunctionTool);\n if (tools.length === 0) {\n return undefined;\n }\n if (requestedToolNames.length === 0) {\n return tools;\n }\n const requested = new Set(requestedToolNames);\n const filtered = tools.filter((tool) => requested.has(tool.function.name));\n return filtered.length > 0 ? filtered : undefined;\n}\n\nexport class NextclawNcpContextBuilder implements NcpContextBuilder {\n private readonly inputBudgetPruner = new InputBudgetPruner();\n\n constructor(\n private readonly options: NextclawNcpContextBuilderOptions,\n ) {}\n\n prepare = (input: NcpAgentRunInput, _options?: NcpContextPrepareOptions): NcpLLMApiInput => {\n const runContext = this.prepareRunContext(input);\n const modelMessages = this.buildModelMessages(input, _options, runContext);\n const pruned = this.pruneModelMessages(runContext, modelMessages);\n\n return {\n messages: pruned.messages as OpenAIChatMessage[],\n tools: buildRequestedOpenAiTools(modelMessages.toolDefinitions, runContext.requestedToolNames),\n model: runContext.effectiveModel,\n thinkingLevel: runContext.runtimeThinking,\n };\n };\n\n private prepareRunContext = (input: NcpAgentRunInput): PreparedRunContext => {\n const config = this.options.configManager.loadConfig();\n const requestMetadata = mergeInputMetadata(input);\n const sessionMetadata = structuredClone(requestMetadata);\n const profile = resolveAgentProfile({\n config,\n storedAgentId: this.options.agentId,\n requestMetadata,\n });\n let { model: effectiveModel } = resolveEffectiveModel({\n sessionMetadata,\n requestMetadata,\n fallbackModel: profile.model,\n });\n const effectiveWorkspace = resolveSessionWorkspacePath({\n sessionMetadata,\n workspace: profile.workspace,\n });\n const { channel, chatId } = resolveSessionChannelContext({\n sessionMetadata,\n requestMetadata,\n });\n const requestedSkills = REQUESTED_SKILLS_METADATA_READER.readSelection(requestMetadata);\n const currentTurn = buildCurrentTurnState({\n input,\n currentModel: effectiveModel,\n formatPrompt: ({ text, timestamp }) =>\n appendTimeHintForPrompt(\n prependRequestedSkills(text, requestedSkills.selectors),\n timestamp,\n ),\n assetStore: this.options.assetStore,\n });\n effectiveModel = currentTurn.effectiveModel;\n const runtimeThinking = resolveThinkingLevel({\n config,\n agentId: profile.agentId,\n model: effectiveModel,\n sessionThinkingLevel: parseThinkingLevel(sessionMetadata.preferred_thinking) ?? null,\n });\n\n this.options.toolRegistry.prepareForRun({\n sessionId: input.sessionId,\n channel,\n chatId,\n agentId: profile.agentId,\n config,\n execTimeoutSeconds: profile.execTimeoutSeconds,\n handoffDepth: resolveAgentHandoffDepth(requestMetadata),\n metadata: requestMetadata,\n restrictToWorkspace: profile.restrictToWorkspace,\n searchConfig: profile.searchConfig,\n workspace: effectiveWorkspace,\n });\n\n return {\n channel,\n chatId,\n config,\n currentTurn,\n effectiveModel,\n effectiveWorkspace,\n profile,\n requestMetadata,\n requestedSkills,\n requestedToolNames: resolveRequestedToolNames(requestMetadata),\n runtimeThinking,\n sessionMetadata,\n sessionKey: input.sessionId,\n };\n };\n\n private buildModelMessages = (\n input: NcpAgentRunInput,\n _options: NcpContextPrepareOptions | undefined,\n runContext: PreparedRunContext,\n ): BuiltNcpModelMessages => {\n const {\n channel,\n chatId,\n config,\n currentTurn,\n effectiveModel,\n effectiveWorkspace,\n profile,\n requestedSkills,\n runtimeThinking,\n sessionMetadata,\n } = runContext;\n const toolDefinitions = this.options.toolRegistry.getToolDefinitions();\n const additionalSystemSections = [\n buildSessionOrchestrationSection(),\n buildMinimalSystemExecutionPrompt(effectiveModel),\n ].filter(Boolean);\n\n const contextBuilder = new ContextBuilder(\n effectiveWorkspace,\n config.agents.context,\n {\n hostWorkspace: profile.workspace,\n sessionProjectRoot: readSessionProjectRoot(sessionMetadata),\n },\n );\n const sessionMessages = projectNcpMessagesWithContextCompaction({\n sessionId: input.sessionId,\n sessionMessages: _options?.sessionMessages ?? [],\n });\n const messages = contextBuilder.buildMessages({\n history: toLegacyMessages([...sessionMessages], {\n assetStore: this.options.assetStore,\n serviceRole: \"system\",\n }),\n currentMessage: \"\",\n channel,\n chatId,\n sessionKey: input.sessionId,\n thinkingLevel: runtimeThinking,\n skillNames: requestedSkills.selectors,\n availableTools: buildToolCatalogEntries(toolDefinitions),\n additionalSystemSections,\n });\n messages[messages.length - 1] = {\n role: currentTurn.currentRole,\n content: currentTurn.currentUserContent,\n };\n return {\n messages,\n toolDefinitions,\n };\n };\n\n private pruneModelMessages = (\n runContext: PreparedRunContext,\n modelMessages: BuiltNcpModelMessages,\n ) => {\n return this.inputBudgetPruner.prune({\n messages: modelMessages.messages,\n contextTokens: runContext.profile.contextTokens,\n reserveTokensFloor: runContext.profile.reservedContextTokens,\n softThresholdTokens: 0,\n });\n };\n}\n","import type {\n OpenAIChatChunk,\n OpenAIToolCallDelta,\n NcpLLMApi,\n NcpLLMApiInput,\n NcpLLMApiOptions,\n} from \"@nextclaw/ncp\";\nimport { parseThinkingLevel, type LLMResponse, type ThinkingLevel, type ToolCallRequest } from \"@nextclaw/core\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\n\nfunction normalizeModel(value: string | undefined): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizeThinkingLevel(value: string | null | undefined): ThinkingLevel | null {\n return parseThinkingLevel(value);\n}\n\nfunction normalizeFinishReason(value: string | undefined): string {\n if (typeof value !== \"string\") {\n return \"stop\";\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : \"stop\";\n}\n\nfunction toToolCallDelta(toolCall: ToolCallRequest, index: number) {\n return {\n index,\n id: toolCall.id,\n type: \"function\" as const,\n function: {\n name: toolCall.name,\n arguments: JSON.stringify(toolCall.arguments ?? {})\n }\n };\n}\n\nfunction toFinalChunk(\n response: LLMResponse,\n options: {\n includeText: boolean;\n includeReasoning: boolean;\n includeToolCalls: boolean;\n },\n): OpenAIChatChunk {\n const delta: NonNullable<OpenAIChatChunk[\"choices\"]>[number][\"delta\"] = {};\n if (options.includeText && typeof response.content === \"string\" && response.content.length > 0) {\n delta.content = response.content;\n }\n if (\n options.includeReasoning &&\n typeof response.reasoningContent === \"string\" &&\n response.reasoningContent.length > 0\n ) {\n delta.reasoning_content = response.reasoningContent;\n }\n if (options.includeToolCalls && response.toolCalls.length > 0) {\n delta.tool_calls = response.toolCalls.map((toolCall, index) => toToolCallDelta(toolCall, index));\n }\n\n return {\n choices: [\n {\n delta,\n finish_reason: normalizeFinishReason(response.finishReason)\n }\n ],\n usage: response.usage\n };\n}\n\nexport class ProviderManagerNcpLLMApi implements NcpLLMApi {\n constructor(private readonly providerManager: LlmProviderRuntime) {}\n\n readonly generate = async function* (\n this: ProviderManagerNcpLLMApi,\n input: NcpLLMApiInput,\n options?: NcpLLMApiOptions\n ): AsyncGenerator<OpenAIChatChunk> {\n const model = normalizeModel(input.model) ?? this.providerManager.get(null).getDefaultModel();\n const thinkingLevel = normalizeThinkingLevel(input.thinkingLevel);\n let sawTextDelta = false;\n let sawReasoningDelta = false;\n let sawToolCallDelta = false;\n\n for await (const event of this.providerManager.chatStream({\n messages: input.messages as Array<Record<string, unknown>>,\n tools: input.tools as Array<Record<string, unknown>> | undefined,\n model,\n ...(thinkingLevel ? { thinkingLevel } : {}),\n maxTokens: input.max_tokens,\n signal: options?.signal\n })) {\n if (event.type === \"delta\") {\n sawTextDelta = true;\n yield {\n choices: [\n {\n delta: {\n content: event.delta\n }\n }\n ]\n };\n continue;\n }\n\n if (event.type === \"reasoning_delta\") {\n sawReasoningDelta = true;\n yield {\n choices: [\n {\n delta: {\n reasoning_content: event.delta,\n },\n },\n ],\n };\n continue;\n }\n\n if (event.type === \"tool_call_delta\") {\n sawToolCallDelta = true;\n yield {\n choices: [\n {\n delta: {\n tool_calls: event.toolCalls as OpenAIToolCallDelta[],\n },\n },\n ],\n };\n continue;\n }\n\n yield toFinalChunk(event.response, {\n includeText: !sawTextDelta,\n includeReasoning: !sawReasoningDelta,\n includeToolCalls: !sawToolCallDelta,\n });\n }\n };\n}\n","import type { Config } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport { DefaultNcpAgentRuntime, type LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n type NcpAgentRuntime,\n readAssistantReasoningNormalizationMode,\n readAssistantReasoningNormalizationModeFromMetadata,\n type NcpAssistantReasoningNormalizationMode,\n} from \"@nextclaw/ncp\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\nimport { type LlmUsageManager } from \"@kernel/managers/llm-usage.manager.js\";\nimport type {\n ToolManager,\n UpdateToolCallResult,\n} from \"@kernel/managers/tool.manager.js\";\nimport { NextclawNcpContextBuilder } from \"./nextclaw-ncp-context-builder.service.js\";\nimport { ProviderManagerNcpLLMApi } from \"./provider-manager-ncp-llm-api.service.js\";\n\nexport type NativeRuntimeFactory = (runtimeParams: RuntimeFactoryParams) => NcpAgentRuntime;\n\nexport type NativeAgentRuntimeFactoryOptions = {\n providerManager: LlmProviderRuntime;\n configManager: ConfigManager;\n llmUsage: LlmUsageManager;\n assetStore: LocalAssetStore;\n updateToolCallResult: UpdateToolCallResult;\n toolManager: ToolManager;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction resolveNativeReasoningNormalizationMode(params: {\n config: Config;\n sessionMetadata: Record<string, unknown>;\n}): NcpAssistantReasoningNormalizationMode {\n const runtimeEntry =\n params.config.agents.runtimes.entries.native?.config ??\n params.config.ui.ncp.runtimes.native;\n const runtimeMetadata = isRecord(runtimeEntry) ? runtimeEntry : {};\n\n return (\n readAssistantReasoningNormalizationModeFromMetadata(params.sessionMetadata) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoningNormalization) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoning_normalization) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoningNormalizationMode) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoning_normalization_mode) ??\n \"think-tags\"\n );\n}\n\nexport class NativeAgentRuntimeFactory {\n private readonly observedProviderManager: LlmProviderRuntime;\n\n constructor(private readonly options: NativeAgentRuntimeFactoryOptions) {\n this.observedProviderManager = options.llmUsage.observeProviderManager(\n options.providerManager,\n \"ui-ncp\",\n );\n }\n\n create: NativeRuntimeFactory = ({\n agentId,\n stateManager,\n sessionMetadata,\n }: RuntimeFactoryParams): NcpAgentRuntime => {\n const reasoningNormalizationMode = resolveNativeReasoningNormalizationMode({\n config: this.options.configManager.loadConfig(),\n sessionMetadata,\n });\n\n const toolRegistry = this.createToolRegistry();\n const runtime = new DefaultNcpAgentRuntime({\n contextBuilder: new NextclawNcpContextBuilder({\n agentId,\n toolRegistry,\n configManager: this.options.configManager,\n assetStore: this.options.assetStore,\n }),\n llmApi: new ProviderManagerNcpLLMApi(this.observedProviderManager),\n toolRegistry,\n stateManager,\n reasoningNormalizationMode,\n });\n return {\n run: async function* (input, options) {\n yield* runtime.run(input, options);\n },\n };\n };\n\n private createToolRegistry = () => {\n return this.options.toolManager.createRuntimeRegistry({\n updateToolCallResult: this.options.updateToolCallResult,\n });\n };\n}\n","import { resolve } from \"node:path\";\nimport {\n buildAssetContentPath,\n type LocalAssetStore,\n type StoredAssetRecord,\n} from \"@nextclaw/ncp-agent-runtime\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nfunction readOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction readOptionalBase64Bytes(value: unknown): Uint8Array | null {\n const base64 = readOptionalString(value);\n if (!base64) {\n return null;\n }\n try {\n return Buffer.from(base64, \"base64\");\n } catch {\n return null;\n }\n}\n\nfunction toAssetPayload(record: StoredAssetRecord, contentBasePath: string) {\n return {\n uri: record.uri,\n name: record.fileName,\n mimeType: record.mimeType,\n sizeBytes: record.sizeBytes,\n createdAt: record.createdAt,\n url: buildAssetContentPath({\n basePath: contentBasePath,\n assetUri: record.uri,\n }),\n };\n}\n\nclass AssetPutTool implements NcpTool {\n readonly name = \"asset_put\";\n readonly description =\n \"Publish a file to the user as a chat/channel attachment with preview and download support.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Existing local file path to publish to the user as an attachment.\",\n },\n bytesBase64: {\n type: \"string\",\n description: \"Base64 file bytes to publish when no source path exists. Use with fileName.\",\n },\n fileName: {\n type: \"string\",\n description: \"Optional display/download file name. Required when using bytesBase64.\",\n },\n mimeType: {\n type: \"string\",\n description: \"Optional MIME type override for preview and download rendering.\",\n },\n },\n additionalProperties: false,\n };\n\n constructor(\n private readonly assetStore: LocalAssetStore,\n private readonly contentBasePath: string,\n ) {}\n\n validateArgs = (args: Record<string, unknown>): string[] => {\n const path = readOptionalString(args.path);\n const bytesBase64 = readOptionalString(args.bytesBase64);\n const fileName = readOptionalString(args.fileName);\n\n if (path && bytesBase64) {\n return [\"Provide either path, or bytesBase64 + fileName, not both.\"];\n }\n if (path) {\n return [];\n }\n if (bytesBase64) {\n return fileName ? [] : [\"fileName is required when using bytesBase64.\"];\n }\n return [\"Provide either path, or bytesBase64 + fileName.\"];\n };\n\n execute = async (args: unknown): Promise<unknown> => {\n const path = readOptionalString((args as { path?: unknown } | null)?.path);\n const fileName = readOptionalString((args as { fileName?: unknown } | null)?.fileName);\n const mimeType = readOptionalString((args as { mimeType?: unknown } | null)?.mimeType);\n const bytes = readOptionalBase64Bytes((args as { bytesBase64?: unknown } | null)?.bytesBase64);\n\n if (path) {\n const record = await this.assetStore.putPath({\n path,\n fileName: fileName ?? undefined,\n mimeType,\n });\n return {\n ok: true,\n asset: toAssetPayload(record, this.contentBasePath),\n };\n }\n\n if (bytes && fileName) {\n const record = await this.assetStore.putBytes({\n fileName,\n mimeType,\n bytes,\n });\n return {\n ok: true,\n asset: toAssetPayload(record, this.contentBasePath),\n };\n }\n\n throw new Error(\"asset_put received invalid arguments after validation.\");\n };\n}\n\nclass AssetExportTool implements NcpTool {\n readonly name = \"asset_export\";\n readonly description =\n \"Export a managed asset to a normal file path so it can be processed like any ordinary file.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n assetUri: {\n type: \"string\",\n description: \"Managed asset URI to export.\",\n },\n targetPath: {\n type: \"string\",\n description: \"Destination file path.\",\n },\n },\n required: [\"assetUri\", \"targetPath\"],\n additionalProperties: false,\n };\n\n constructor(private readonly assetStore: LocalAssetStore) {}\n\n execute = async (args: unknown): Promise<unknown> => {\n const assetUri = readOptionalString((args as { assetUri?: unknown } | null)?.assetUri);\n const targetPath = readOptionalString((args as { targetPath?: unknown } | null)?.targetPath);\n if (!assetUri || !targetPath) {\n throw new Error(\"asset_export requires assetUri and targetPath.\");\n }\n const exportedPath = await this.assetStore.export({ uri: assetUri }, resolve(targetPath));\n return {\n ok: true,\n assetUri,\n exportedPath,\n };\n };\n}\n\nclass AssetStatTool implements NcpTool {\n readonly name = \"asset_stat\";\n readonly description = \"Read managed asset metadata.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n assetUri: {\n type: \"string\",\n description: \"Managed asset URI to inspect.\",\n },\n },\n required: [\"assetUri\"],\n additionalProperties: false,\n };\n\n constructor(\n private readonly assetStore: LocalAssetStore,\n private readonly contentBasePath: string,\n ) {}\n\n execute = async (args: unknown): Promise<unknown> => {\n const assetUri = readOptionalString((args as { assetUri?: unknown } | null)?.assetUri);\n if (!assetUri) {\n throw new Error(\"asset_stat requires assetUri.\");\n }\n const record = await this.assetStore.statRecord(assetUri);\n if (!record) {\n return {\n ok: false,\n error: {\n code: \"not_found\",\n message: `Asset not found: ${assetUri}`,\n },\n };\n }\n return {\n ok: true,\n asset: toAssetPayload(record, this.contentBasePath),\n };\n };\n}\n\nexport function createAssetTools(params: {\n assetStore: LocalAssetStore;\n contentBasePath?: string;\n}): NcpTool[] {\n const { assetStore } = params;\n const contentBasePath = params.contentBasePath ?? \"/api/ncp/assets/content\";\n return [\n new AssetPutTool(assetStore, contentBasePath),\n new AssetExportTool(assetStore),\n new AssetStatTool(assetStore, contentBasePath),\n ];\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n ingressKeys,\n type AgentRunSendIngressPayload,\n type AgentRunSessionMessageRequestPayload,\n type Ingress,\n type IngressEnvelope,\n} from \"@nextclaw/shared\";\nimport {\n isHiddenNcpMessage,\n NcpEventType,\n type NcpAgentRunSendOptions,\n type NcpAgentSendEnvelope,\n type NcpEndpointEvent,\n type NcpMessageAbortPayload,\n type NcpRequestEnvelope,\n type NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport {\n consumeRunHandle,\n isTerminalRunEvent,\n type LiveSessionExecution,\n type MaterializedAgentRunRequest,\n normalizeRunEvent,\n normalizeSendRunEvent,\n readMessageTask,\n readMetadataString,\n readString,\n withSession,\n} from \"@kernel/utils/session-run.utils.js\";\nimport type { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport {\n resolveEffectiveModel,\n resolveSessionChannelContext,\n syncSessionThinkingPreference,\n} from \"@kernel/features/native-runtime/index.js\";\nimport type { ContextCompactionManager } from \"@kernel/features/context-compaction/index.js\";\n\nexport class AgentRunRequestManager {\n private readonly contextCompactionManager: ContextCompactionManager;\n private readonly cleanups: Array<() => Promise<void> | void> = [];\n private readonly ingress: Ingress;\n private readonly ncpSessionManager: NcpSessionManager;\n private readonly sessionRunManager: SessionRunManager;\n private disposed = false;\n private started = false;\n\n constructor(options: {\n contextCompactionManager: ContextCompactionManager;\n ingress: Ingress;\n ncpSessionManager: NcpSessionManager;\n sessionRunManager: SessionRunManager;\n }) {\n const {\n contextCompactionManager,\n ingress,\n ncpSessionManager,\n sessionRunManager,\n } = options;\n this.contextCompactionManager = contextCompactionManager;\n this.ingress = ingress;\n this.ncpSessionManager = ncpSessionManager;\n this.sessionRunManager = sessionRunManager;\n }\n\n start = (): void => {\n this.assertNotDisposed();\n if (this.started) {\n return;\n }\n this.started = true;\n this.cleanups.push(\n this.ingress.addHandler(ingressKeys.agentRun.send, this.handleSendRequest),\n this.ingress.addHandler(ingressKeys.agentRun.abort, this.handleAbortRequest),\n this.ingress.addHandler(ingressKeys.agentRun.sessionMessageRequest, this.handleSessionMessageRequest),\n );\n };\n\n dispose = async (): Promise<void> => {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n while (this.cleanups.length > 0) {\n await this.cleanups.pop()?.();\n }\n this.started = false;\n };\n\n run = (\n envelope: NcpRequestEnvelope,\n options?: NcpAgentRunSendOptions,\n ): AsyncIterable<NcpEndpointEvent> => this.iterateRun(this.materializeRunEnvelope(envelope), options);\n\n private readonly handleSendRequest = async (\n envelope: IngressEnvelope<AgentRunSendIngressPayload>,\n ): Promise<NcpRunHandle> => {\n if (!envelope.payload) {\n throw new Error(\"Invalid agent run send request.\");\n }\n const requestEnvelope = await this.materializeSendEnvelope(envelope.payload);\n return await consumeRunHandle(\n this.iterateRun(requestEnvelope),\n {\n sessionId: requestEnvelope.sessionId,\n userMessageId: requestEnvelope.message.id,\n assistantMessageId: null,\n runId: requestEnvelope.runId,\n ...(requestEnvelope.correlationId ? { correlationId: requestEnvelope.correlationId } : {}),\n },\n );\n };\n\n private readonly handleAbortRequest = async (\n envelope: IngressEnvelope<NcpMessageAbortPayload>,\n ): Promise<void> => {\n const payload = envelope.payload;\n if (!payload?.sessionId) {\n throw new Error(\"Invalid agent run abort request.\");\n }\n const activeRun = this.sessionRunManager.getActiveSessionRun(payload.sessionId);\n if (!activeRun || activeRun.closed) {\n return;\n }\n activeRun.abortHandled = true;\n activeRun.controller.abort();\n this.sessionRunManager.setActiveSessionRun(payload.sessionId, activeRun);\n await this.sessionRunManager.appendSessionEvent(payload.sessionId, {\n type: NcpEventType.MessageAbort,\n payload: {\n sessionId: payload.sessionId,\n ...(payload.messageId ? { messageId: payload.messageId } : {}),\n },\n });\n this.sessionRunManager.deleteActiveSessionRun(payload.sessionId, activeRun.runId);\n };\n\n private readonly iterateRun = async function* (\n this: AgentRunRequestManager,\n envelope: MaterializedAgentRunRequest,\n options?: NcpAgentRunSendOptions,\n ): AsyncIterable<NcpEndpointEvent> {\n const metadata = await this.prepareRunSessionMetadata(envelope.sessionId, envelope.metadata);\n const session = await this.sessionRunManager.getOrCreateLiveSession(envelope.sessionId, metadata);\n const controller = new AbortController();\n options?.signal?.addEventListener(\"abort\", () => controller.abort(), { once: true });\n const activeRun: LiveSessionExecution = {\n runId: envelope.runId,\n controller,\n requestEnvelope: structuredClone(envelope),\n abortHandled: false,\n closed: false,\n };\n this.sessionRunManager.setActiveSessionRun(session.sessionId, activeRun);\n let completedMessageSeen = false;\n\n try {\n if (!isHiddenNcpMessage(envelope.message)) {\n const messageSentEvent: NcpEndpointEvent = {\n type: NcpEventType.MessageSent,\n payload: {\n sessionId: envelope.sessionId,\n message: structuredClone(envelope.message),\n ...(envelope.correlationId ? { correlationId: envelope.correlationId } : {}),\n metadata,\n },\n };\n await this.sessionRunManager.appendSessionEvent(session.sessionId, messageSentEvent, {\n dispatchToStateManager: false,\n });\n yield messageSentEvent;\n }\n\n const runtimeInput = {\n sessionId: envelope.sessionId,\n runId: envelope.runId,\n messages: [envelope.message],\n correlationId: envelope.correlationId,\n metadata,\n };\n yield* this.contextCompactionManager.runLivePreflight({\n input: runtimeInput,\n session,\n });\n for await (const event of session.runtime.run(runtimeInput, {\n signal: activeRun.controller.signal,\n })) {\n const normalizedEvent = normalizeSendRunEvent({\n session,\n event: normalizeRunEvent(event, envelope),\n completedMessageSeen,\n });\n completedMessageSeen = normalizedEvent.completedMessageSeen;\n for (const eventToPublish of normalizedEvent.eventsToPublish) {\n await this.sessionRunManager.appendSessionEvent(session.sessionId, eventToPublish, {\n dispatchToStateManager: false,\n });\n yield eventToPublish;\n }\n }\n\n if (activeRun.controller.signal.aborted && !activeRun.abortHandled) {\n const abortEvent: NcpEndpointEvent = {\n type: NcpEventType.MessageAbort,\n payload: { sessionId: session.sessionId },\n };\n await this.sessionRunManager.appendSessionEvent(session.sessionId, abortEvent);\n yield abortEvent;\n }\n } catch (error) {\n if (!activeRun.controller.signal.aborted) {\n const runErrorEvent: NcpEndpointEvent = {\n type: NcpEventType.RunError,\n payload: {\n sessionId: envelope.sessionId,\n runId: envelope.runId,\n ...(envelope.correlationId ? { correlationId: envelope.correlationId } : {}),\n error: error instanceof Error ? error.message : String(error),\n },\n };\n await this.sessionRunManager.appendSessionEvent(session.sessionId, runErrorEvent);\n yield runErrorEvent;\n }\n } finally {\n this.sessionRunManager.deleteActiveSessionRun(session.sessionId, activeRun.runId);\n }\n };\n\n private readonly materializeSendEnvelope = async (\n envelope: AgentRunSendIngressPayload,\n ): Promise<MaterializedAgentRunRequest> => {\n const sendEnvelope = this.toNcpSendEnvelope(envelope);\n const existingSessionId = readString(sendEnvelope.sessionId) ?? readString(sendEnvelope.message.sessionId);\n if (existingSessionId) {\n return this.materializeRunEnvelope(withSession(sendEnvelope, existingSessionId));\n }\n\n const metadata = sendEnvelope.metadata ?? {};\n const createdSession = await this.ncpSessionManager.createSession({\n task: readMessageTask(sendEnvelope.message),\n title: readMetadataString(metadata, \"label\", \"title\"),\n sourceSessionMetadata: {},\n metadataOverrides: metadata,\n agentId: readMetadataString(metadata, \"agent_id\", \"agentId\"),\n model: readMetadataString(metadata, \"preferred_model\", \"model\"),\n runtime: readMetadataString(metadata, \"runtime\", \"session_type\"),\n sessionType: readMetadataString(metadata, \"session_type\", \"runtime\"),\n thinkingLevel: readMetadataString(metadata, \"preferred_thinking\", \"thinking\"),\n projectRoot: readMetadataString(metadata, \"project_root\"),\n });\n return this.materializeRunEnvelope(withSession(sendEnvelope, createdSession.sessionId));\n };\n\n private readonly toNcpSendEnvelope = (\n envelope: AgentRunSendIngressPayload,\n ): NcpAgentSendEnvelope => {\n if (Array.isArray(envelope.content)) {\n const { content, ...request } = envelope;\n return {\n ...request,\n message: {\n id: `user-message-${randomUUID()}`,\n role: \"user\",\n status: \"final\",\n timestamp: new Date().toISOString(),\n parts: structuredClone(content),\n },\n };\n }\n if (\"message\" in envelope && envelope.message) {\n return envelope;\n }\n throw new Error(\"Invalid agent run send request.\");\n };\n\n private readonly materializeRunEnvelope = (envelope: NcpRequestEnvelope): MaterializedAgentRunRequest => ({\n ...envelope,\n runId: `ncp-run-${randomUUID()}`,\n });\n\n private readonly prepareRunSessionMetadata = async (\n sessionId: string,\n requestMetadata: Record<string, unknown> = {},\n ): Promise<Record<string, unknown>> => {\n const storedSession = await this.ncpSessionManager.getSessionRecord(sessionId);\n const currentMetadata = {\n ...(storedSession?.metadata ?? {}),\n ...structuredClone(requestMetadata),\n };\n let nextMetadata = resolveEffectiveModel({\n sessionMetadata: currentMetadata,\n requestMetadata,\n fallbackModel: \"\",\n }).metadata;\n nextMetadata = syncSessionThinkingPreference({\n sessionMetadata: nextMetadata,\n requestMetadata,\n });\n nextMetadata = resolveSessionChannelContext({\n sessionMetadata: nextMetadata,\n requestMetadata,\n }).metadata;\n await this.sessionRunManager.updateSessionMetadata(sessionId, nextMetadata);\n return nextMetadata;\n };\n\n private readonly handleSessionMessageRequest = async (\n envelope: IngressEnvelope<AgentRunSessionMessageRequestPayload>,\n ): Promise<void> => {\n const request = envelope.payload;\n if (!request?.requestId || !request.sessionId || !request.message) {\n throw new Error(\"Invalid agent run session message request.\");\n }\n let terminalEventSeen = false;\n for await (const event of this.run({\n sessionId: request.sessionId,\n message: request.message,\n correlationId: request.requestId,\n })) {\n terminalEventSeen ||= isTerminalRunEvent(event);\n }\n if (!terminalEventSeen) {\n throw new Error(\"Session request completed without a final reply.\");\n }\n };\n\n private readonly assertNotDisposed = (): void => {\n if (this.disposed) {\n throw new Error(\"Agent run request manager has already been disposed.\");\n }\n };\n}\n","import { toDisposable, type Disposable } from \"@nextclaw/core\";\nimport type { NcpAgentRuntime } from \"@nextclaw/ncp\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\n\nexport const DEFAULT_AGENT_RUNTIME_ENTRY_ID = \"native\";\n\nexport type AgentRuntimeSessionTypeIcon = {\n kind: \"image\";\n src: string;\n alt?: string | null;\n};\n\nexport type AgentRuntimeSessionTypeOption = {\n value: string;\n label: string;\n icon?: AgentRuntimeSessionTypeIcon | null;\n ready?: boolean;\n reason?: string | null;\n reasonMessage?: string | null;\n supportedModels?: string[];\n recommendedModel?: string | null;\n cta?: {\n kind: string;\n label?: string;\n href?: string;\n } | null;\n};\n\nexport type AgentRuntimeSessionTypeDescribeParams = {\n describeMode?: \"observation\" | \"probe\";\n};\n\nexport type AgentRuntimeEntry = {\n id: string;\n label: string;\n icon?: AgentRuntimeSessionTypeIcon | null;\n type: string;\n enabled?: boolean;\n config?: Record<string, unknown>;\n};\n\nexport type AgentRuntimeProviderRegistration = {\n kind: string;\n label: string;\n createRuntime: (params: RuntimeFactoryParams) => NcpAgentRuntime;\n createRuntimeForEntry?: (params: {\n entry: AgentRuntimeEntry;\n runtimeParams: RuntimeFactoryParams;\n }) => NcpAgentRuntime;\n describeSessionType?: (params?: AgentRuntimeSessionTypeDescribeParams) => Promise<Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\"> | null | undefined>\n | Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\">\n | null\n | undefined;\n describeSessionTypeForEntry?: (params: {\n entry: AgentRuntimeEntry;\n describeParams?: AgentRuntimeSessionTypeDescribeParams;\n }) => Promise<Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\"> | null | undefined>\n | Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\">\n | null\n | undefined;\n};\n\ntype RuntimeProviderRegistrationEntry = AgentRuntimeProviderRegistration & { token: symbol };\n\nfunction normalizeIdentifier(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const normalized = value.trim().toLowerCase();\n return normalized.length > 0 ? normalized : null;\n}\n\nfunction cloneRuntimeEntry(entry: AgentRuntimeEntry): AgentRuntimeEntry {\n return {\n id: entry.id,\n label: entry.label,\n ...(entry.icon ? { icon: { ...entry.icon } } : {}),\n type: entry.type,\n enabled: entry.enabled !== false,\n config: entry.config ? { ...entry.config } : {},\n };\n}\n\nexport function normalizeAgentRuntimeSessionTypeIcon(\n value: unknown,\n): AgentRuntimeSessionTypeIcon | null {\n if (typeof value === \"string\") {\n const src = value.trim();\n return src ? { kind: \"image\", src } : null;\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n const iconRecord = value as Record<string, unknown>;\n const src = typeof iconRecord.src === \"string\" ? iconRecord.src.trim() : \"\";\n if (!src) {\n return null;\n }\n const alt =\n typeof iconRecord.alt === \"string\" && iconRecord.alt.trim().length > 0\n ? iconRecord.alt.trim()\n : null;\n return {\n kind: \"image\",\n src,\n ...(alt ? { alt } : {}),\n };\n}\n\ntype ConfigRuntimeEntry = {\n enabled?: boolean;\n label?: string;\n icon?: unknown;\n type?: string;\n config?: Record<string, unknown>;\n};\n\ntype AgentRuntimeResolverConfig = {\n ui?: {\n ncp?: {\n runtimes?: {\n native?: unknown;\n };\n };\n };\n agents: {\n runtimes: {\n entries?: Record<string, ConfigRuntimeEntry>;\n };\n };\n};\n\nconst BUILTIN_RUNTIME_PRESENTATION = {\n hermes: {\n label: \"Hermes\",\n icon: {\n kind: \"image\",\n src: \"app://runtime-icons/hermes-agent.png\",\n alt: \"Hermes\",\n },\n },\n} satisfies Record<string, { label: string; icon?: AgentRuntimeSessionTypeIcon }>;\n\ntype BuiltinRuntimePresentationKey = keyof typeof BUILTIN_RUNTIME_PRESENTATION;\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction readRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction resolveBuiltinRuntimePresentation(\n value: string | undefined,\n): { label: string; icon?: AgentRuntimeSessionTypeIcon } | null {\n const normalized = readString(value)?.toLowerCase();\n if (!normalized) {\n return null;\n }\n if (!(normalized in BUILTIN_RUNTIME_PRESENTATION)) {\n return null;\n }\n return BUILTIN_RUNTIME_PRESENTATION[normalized as BuiltinRuntimePresentationKey] ?? null;\n}\n\nfunction buildNativeRuntimeEntry(config: AgentRuntimeResolverConfig): AgentRuntimeEntry {\n const nativeRuntimeConfig = readRecord(config.ui?.ncp?.runtimes?.native) ?? {};\n return {\n id: DEFAULT_AGENT_RUNTIME_ENTRY_ID,\n label: \"Native\",\n type: DEFAULT_AGENT_RUNTIME_ENTRY_ID,\n enabled: nativeRuntimeConfig.enabled !== false,\n config: nativeRuntimeConfig,\n };\n}\n\nexport function resolveAgentRuntimeEntries(params: {\n config: AgentRuntimeResolverConfig;\n}): {\n defaultEntryId: string;\n entries: AgentRuntimeEntry[];\n} {\n const entries = new Map<string, AgentRuntimeEntry>();\n\n entries.set(DEFAULT_AGENT_RUNTIME_ENTRY_ID, buildNativeRuntimeEntry(params.config));\n\n for (const [rawId, rawEntry] of Object.entries(params.config.agents.runtimes.entries ?? {})) {\n const id = rawId.trim().toLowerCase();\n const type = readString(rawEntry.type)?.toLowerCase();\n if (!id || !type) {\n continue;\n }\n const explicitIcon = normalizeAgentRuntimeSessionTypeIcon(rawEntry.icon);\n const builtinPresentation =\n resolveBuiltinRuntimePresentation(id) ??\n resolveBuiltinRuntimePresentation(type);\n entries.set(id, {\n id,\n label: readString(rawEntry.label) ?? builtinPresentation?.label ?? id,\n ...(explicitIcon ?? builtinPresentation?.icon\n ? { icon: explicitIcon ?? builtinPresentation?.icon }\n : {}),\n type,\n enabled: rawEntry.enabled !== false,\n config: rawEntry.config ? { ...rawEntry.config } : {},\n });\n }\n\n const defaultEntryId = entries.has(DEFAULT_AGENT_RUNTIME_ENTRY_ID)\n ? DEFAULT_AGENT_RUNTIME_ENTRY_ID\n : [...entries.keys()][0] ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n return {\n defaultEntryId,\n entries: [...entries.values()],\n };\n}\n\nfunction readRequestedRuntimeEntryId(sessionMetadata: Record<string, unknown>): string | null {\n return (\n normalizeIdentifier(sessionMetadata.runtime) ??\n normalizeIdentifier(sessionMetadata.session_type) ??\n normalizeIdentifier(sessionMetadata.sessionType) ??\n null\n );\n}\n\nexport class AgentRuntimeRegistry {\n private readonly providers = new Map<string, RuntimeProviderRegistrationEntry>();\n private entries = new Map<string, AgentRuntimeEntry>();\n private defaultEntryId = DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n\n register = (registration: AgentRuntimeProviderRegistration): Disposable => {\n const normalizedKind = normalizeIdentifier(registration.kind);\n if (!normalizedKind) {\n throw new Error(\"agent runtime kind must be a non-empty string\");\n }\n\n const token = Symbol(normalizedKind);\n this.providers.set(normalizedKind, {\n ...registration,\n kind: normalizedKind,\n token,\n });\n\n return toDisposable(() => {\n const current = this.providers.get(normalizedKind);\n if (!current || current.token !== token) {\n return;\n }\n this.providers.delete(normalizedKind);\n });\n };\n\n applyEntries = (params: {\n entries: AgentRuntimeEntry[];\n defaultEntryId?: string;\n }): void => {\n const nextEntries = new Map<string, AgentRuntimeEntry>();\n for (const rawEntry of params.entries) {\n const id = normalizeIdentifier(rawEntry.id);\n const type = normalizeIdentifier(rawEntry.type);\n const label = rawEntry.label?.trim() ?? \"\";\n if (!id || !type || !label) {\n continue;\n }\n nextEntries.set(id, cloneRuntimeEntry({\n ...rawEntry,\n id,\n type,\n label,\n }));\n }\n this.entries = nextEntries;\n this.defaultEntryId =\n normalizeIdentifier(params.defaultEntryId) ??\n (nextEntries.has(DEFAULT_AGENT_RUNTIME_ENTRY_ID)\n ? DEFAULT_AGENT_RUNTIME_ENTRY_ID\n : [...nextEntries.keys()][0] ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID);\n };\n\n resolveSessionMetadata = (sessionMetadata: Record<string, unknown>): Record<string, unknown> => {\n const { entry } = this.resolveRuntimeEntry(sessionMetadata);\n return {\n ...sessionMetadata,\n runtime: entry.id,\n session_type: entry.id,\n runtime_type: entry.type,\n };\n };\n\n createRuntime = (params: RuntimeFactoryParams): NcpAgentRuntime => {\n const nextSessionMetadata = this.resolveSessionMetadata(params.sessionMetadata);\n const { entry, provider } = this.resolveRuntimeEntry(nextSessionMetadata);\n if (provider.createRuntimeForEntry) {\n return provider.createRuntimeForEntry({\n entry: cloneRuntimeEntry(entry),\n runtimeParams: {\n ...params,\n sessionMetadata: nextSessionMetadata,\n },\n });\n }\n return provider.createRuntime({\n ...params,\n sessionMetadata: nextSessionMetadata,\n });\n };\n\n private resolveRuntimeEntry = (sessionMetadata: Record<string, unknown>) => {\n const requestedEntryId =\n readRequestedRuntimeEntryId(sessionMetadata) ?? this.defaultEntryId;\n const entry = this.entries.get(requestedEntryId);\n if (!entry || entry.enabled === false) {\n throw new Error(`ncp runtime unavailable: ${requestedEntryId}`);\n }\n\n const provider = this.providers.get(entry.type);\n if (!provider) {\n throw new Error(`ncp runtime provider unavailable: ${entry.type}`);\n }\n return { entry, provider };\n };\n\n listSessionTypes = async (params?: AgentRuntimeSessionTypeDescribeParams): Promise<{\n defaultType: string;\n options: AgentRuntimeSessionTypeOption[];\n }> => {\n const options = await Promise.all(\n [...this.entries.values()]\n .filter((entry) => entry.enabled !== false)\n .map(async (entry) => {\n const provider = this.providers.get(entry.type);\n if (!provider) {\n return {\n value: entry.id,\n label: entry.label,\n icon: entry.icon ?? null,\n ready: false,\n reason: \"runtime_provider_unavailable\",\n reasonMessage: `Runtime provider unavailable for type \"${entry.type}\".`,\n recommendedModel: null,\n cta: {\n kind: \"settings\",\n label: \"Configure Runtime\",\n },\n } satisfies AgentRuntimeSessionTypeOption;\n }\n\n const descriptor = provider.describeSessionTypeForEntry\n ? await provider.describeSessionTypeForEntry({\n entry: cloneRuntimeEntry(entry),\n describeParams: params,\n })\n : await provider.describeSessionType?.(params);\n return {\n value: entry.id,\n label: entry.label,\n icon: descriptor?.icon ?? entry.icon ?? null,\n ready: descriptor?.ready ?? true,\n reason: descriptor?.reason ?? null,\n reasonMessage: descriptor?.reasonMessage ?? null,\n recommendedModel: descriptor?.recommendedModel ?? null,\n cta: descriptor?.cta ?? null,\n ...(descriptor?.supportedModels ? { supportedModels: descriptor.supportedModels } : {}),\n } satisfies AgentRuntimeSessionTypeOption;\n }),\n );\n\n return {\n defaultType: this.defaultEntryId,\n options: options.sort((left, right) => {\n if (left.value === this.defaultEntryId) {\n return -1;\n }\n if (right.value === this.defaultEntryId) {\n return 1;\n }\n return left.value.localeCompare(right.value);\n }),\n };\n };\n}\n","import {\n type Disposable,\n type Config,\n} from \"@nextclaw/core\";\nimport type { LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\nimport {\n AgentRuntimeRegistry,\n type AgentRuntimeSessionTypeDescribeParams,\n type AgentRuntimeProviderRegistration,\n resolveAgentRuntimeEntries,\n} from \"@kernel/features/runtime-registry/index.js\";\n\n\nexport type AgentRuntimeManagerOptions = {\n configManager: { loadConfig: () => Config };\n assetStore: LocalAssetStore;\n};\n\nexport class AgentRuntimeManager {\n private readonly runtimeRegistry = new AgentRuntimeRegistry();\n private readonly refreshConfiguredRuntimeEntries = () => {\n this.runtimeRegistry.applyEntries(\n resolveAgentRuntimeEntries({\n config: this.params.configManager.loadConfig(),\n }),\n );\n };\n\n private disposed = false;\n\n constructor(private readonly params: AgentRuntimeManagerOptions) {}\n\n registerRuntimeProvider = (registration: AgentRuntimeProviderRegistration): Disposable => {\n this.assertNotDisposed();\n const disposable = this.runtimeRegistry.register(registration);\n this.refreshConfiguredRuntimeEntries();\n return disposable;\n };\n\n createRuntime = (runtimeParams: RuntimeFactoryParams) => {\n this.assertNotDisposed();\n this.refreshConfiguredRuntimeEntries();\n return this.runtimeRegistry.createRuntime({\n ...runtimeParams,\n resolveAssetContentPath: (assetUri) => this.params.assetStore.resolveContentPath(assetUri),\n });\n };\n\n resolveSessionMetadata = (sessionMetadata: Record<string, unknown>): Record<string, unknown> => {\n this.assertNotDisposed();\n this.refreshConfiguredRuntimeEntries();\n return this.runtimeRegistry.resolveSessionMetadata(sessionMetadata);\n };\n\n listSessionTypes = (describeParams?: AgentRuntimeSessionTypeDescribeParams) => {\n this.refreshConfiguredRuntimeEntries();\n return this.runtimeRegistry.listSessionTypes(describeParams);\n };\n\n dispose = async (): Promise<void> => {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n };\n\n private readonly assertNotDisposed = (): void => {\n if (this.disposed) {\n throw new Error(\"Agent runtime has already been disposed.\");\n }\n };\n}\n","import { CronService } from \"@nextclaw/core\";\n\nexport type AutomationManagerOptions = {\n storePath: string;\n};\n\nexport class AutomationManager extends CronService {\n constructor(options: AutomationManagerOptions) {\n super(options.storePath);\n }\n}\n","import {\n buildConfigSchema,\n buildReloadPlan,\n ConfigSchema,\n diffConfigPaths,\n getConfigPath,\n loadConfig,\n normalizeInlineSecretRefs,\n redactConfigObject,\n resolveConfigSecrets,\n saveConfig,\n type ChannelManager,\n type Config,\n type ExtensionRegistry,\n} from \"@nextclaw/core\";\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type { LlmProviderManager } from \"./llm-provider.manager.js\";\n\nexport type ConfigManagerRuntimeHooks = {\n resolveChannelConfig?: (config: Config) => Config;\n getExtensionChannels?: () => ExtensionRegistry[\"channels\"];\n applyAgentRuntimeConfig?: (config: Config) => void;\n reloadCompanion?: (params: { config: Config; changedPaths: string[] }) => Promise<void> | void;\n reloadMcp?: (params: { config: Config; changedPaths: string[] }) => Promise<void> | void;\n reloadPlugins?: (\n params: { config: Config; changedPaths: string[] },\n ) => Promise<{ restartChannels?: boolean } | void> | { restartChannels?: boolean } | void;\n onRestartRequired?: (paths: string[]) => void;\n};\n\nexport type ConfigManagerOptions = {\n configPath?: string;\n channels: ChannelManager;\n providerManager: LlmProviderManager;\n};\n\nexport type ConfigMutationResult = Record<string, unknown> & { ok: boolean; error?: string };\n\ntype ConfigSnapshot = { raw: string | null; hash: string | null; config: Config; redacted: Record<string, unknown>; valid: boolean };\ntype RawConfigMutationParams = { raw: string; baseHash?: string; note?: string; version?: string };\n\nconst hashRaw = (raw: string): string => createHash(\"sha256\").update(raw).digest(\"hex\");\n\nconst mergeDeep = (base: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown> => {\n const next: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const baseVal = base[key];\n next[key] = baseVal && typeof baseVal === \"object\" && !Array.isArray(baseVal)\n ? mergeDeep(baseVal as Record<string, unknown>, value as Record<string, unknown>)\n : mergeDeep({}, value as Record<string, unknown>);\n continue;\n }\n next[key] = value;\n }\n return next;\n};\n\nexport class ConfigManager {\n readonly configPath: string;\n private currentConfig: Config;\n private hooks: ConfigManagerRuntimeHooks = {};\n private reloadTask: Promise<void> | null = null;\n private providerReloadTask: Promise<void> | null = null;\n private reloadTimer: ReturnType<typeof setTimeout> | null = null;\n private reloadRunning = false;\n private reloadPending = false;\n\n constructor(private readonly options: ConfigManagerOptions) {\n this.configPath = options.configPath ?? getConfigPath();\n this.currentConfig = this.loadConfig();\n this.options.providerManager.load(this.currentConfig);\n this.options.channels.load({\n channelConfig: this.resolveChannelConfig(this.currentConfig),\n extensionChannels: this.resolveExtensionChannels(),\n });\n }\n\n get config(): Config {\n return this.currentConfig;\n }\n\n loadConfig = (): Config =>\n resolveConfigSecrets(loadConfig(this.configPath), { configPath: this.configPath });\n\n installRuntimeHooks = (hooks: ConfigManagerRuntimeHooks): void => {\n this.hooks = { ...this.hooks, ...hooks };\n };\n\n applyLiveConfigReload = async (): Promise<void> => {\n await this.applyReloadPlan(this.loadConfig());\n };\n\n applyReloadPlan = async (nextConfig: Config): Promise<void> => {\n const changedPaths = diffConfigPaths(this.currentConfig, nextConfig);\n if (!changedPaths.length) {\n return;\n }\n this.currentConfig = nextConfig;\n const plan = buildReloadPlan(changedPaths);\n\n let reloadPluginsResult: { restartChannels?: boolean } | void = undefined;\n if (plan.reloadPlugins) {\n reloadPluginsResult = await this.reloadPlugins({\n config: nextConfig,\n changedPaths,\n });\n console.log(\"Config reload: plugins reloaded.\");\n }\n if (plan.reloadMcp) {\n await this.reloadMcp({\n config: nextConfig,\n changedPaths,\n });\n console.log(\"Config reload: MCP servers reloaded.\");\n }\n if (plan.reloadCompanion) {\n await this.reloadCompanion({\n config: nextConfig,\n changedPaths,\n });\n console.log(\"Config reload: companion setting applied.\");\n }\n if (plan.restartChannels || reloadPluginsResult?.restartChannels) {\n await this.rebuildChannels(nextConfig, { start: true });\n console.log(\"Config reload: channels restarted.\");\n }\n if (plan.reloadProviders) {\n await this.reloadProvider(nextConfig);\n console.log(\"Config reload: provider settings applied.\");\n }\n if (plan.reloadAgent) {\n this.hooks.applyAgentRuntimeConfig?.(nextConfig);\n console.log(\"Config reload: agent defaults applied.\");\n }\n if (plan.restartRequired.length > 0) {\n this.hooks.onRestartRequired?.(plan.restartRequired);\n }\n };\n\n getConfigSnapshot = (params: { version?: string } = {}): Record<string, unknown> => {\n const { hash, raw, redacted, valid } = this.readConfigSnapshot(params);\n return {\n raw,\n hash,\n path: this.configPath,\n config: redacted,\n parsed: redacted,\n resolved: redacted,\n valid,\n };\n };\n\n getConfigSchema = (params: { version?: string } = {}): Record<string, unknown> => buildConfigSchema({ version: params.version });\n\n applyRawConfig = async (params: RawConfigMutationParams): Promise<ConfigMutationResult> =>\n this.mutateRawConfig(params, (_snapshot, parsed) => parsed);\n\n patchRawConfig = async (params: RawConfigMutationParams): Promise<ConfigMutationResult> =>\n this.mutateRawConfig(params, (snapshot, patch) => mergeDeep(snapshot.config as Record<string, unknown>, patch));\n\n scheduleReload = (reason: string): void => {\n if (this.reloadTimer) {\n clearTimeout(this.reloadTimer);\n }\n this.reloadTimer = setTimeout(() => {\n void this.runReload(reason);\n }, 300);\n };\n\n runReload = async (reason: string): Promise<void> => {\n if (this.reloadRunning) {\n this.reloadPending = true;\n return;\n }\n this.reloadRunning = true;\n if (this.reloadTimer) {\n clearTimeout(this.reloadTimer);\n this.reloadTimer = null;\n }\n try {\n await this.applyLiveConfigReload();\n } catch (error) {\n console.error(`Config reload failed (${reason}): ${String(error)}`);\n } finally {\n this.reloadRunning = false;\n if (this.reloadPending) {\n this.reloadPending = false;\n this.scheduleReload(\"pending\");\n }\n }\n };\n\n reloadConfig = async (reason?: string): Promise<string> => {\n await this.runReload(reason ?? \"gateway tool\");\n return \"Config reload triggered\";\n };\n\n rebuildChannels = async (nextConfig: Config, options: { start?: boolean } = {}): Promise<void> => {\n if (this.reloadTask) {\n await this.reloadTask;\n return;\n }\n this.reloadTask = (async () => {\n await this.options.channels.reload({\n channelConfig: this.resolveChannelConfig(nextConfig),\n extensionChannels: this.resolveExtensionChannels(),\n start: options.start ?? true,\n });\n })();\n try {\n await this.reloadTask;\n } finally {\n this.reloadTask = null;\n }\n };\n\n private resolveChannelConfig = (config: Config): Config =>\n this.hooks.resolveChannelConfig?.(config) ?? config;\n\n private resolveExtensionChannels = (): ExtensionRegistry[\"channels\"] =>\n this.hooks.getExtensionChannels?.() ?? [];\n\n private reloadProvider = async (nextConfig: Config): Promise<void> => {\n if (this.providerReloadTask) {\n await this.providerReloadTask;\n return;\n }\n this.providerReloadTask = (async () => {\n this.options.providerManager.load(nextConfig);\n })();\n try {\n await this.providerReloadTask;\n } finally {\n this.providerReloadTask = null;\n }\n };\n\n private reloadPlugins = async (params: {\n config: Config;\n changedPaths: string[];\n }): Promise<{ restartChannels?: boolean } | void> => {\n return await this.hooks.reloadPlugins?.(params);\n };\n\n private reloadMcp = async (params: {\n config: Config;\n changedPaths: string[];\n }): Promise<void> => {\n await this.hooks.reloadMcp?.(params);\n };\n\n private reloadCompanion = async (params: {\n config: Config;\n changedPaths: string[];\n }): Promise<void> => {\n await this.hooks.reloadCompanion?.(params);\n };\n\n private readConfigSnapshot = (params: { version?: string } = {}): ConfigSnapshot => {\n let raw = \"\";\n let parsed: Record<string, unknown> = {};\n if (existsSync(this.configPath)) {\n raw = readFileSync(this.configPath, \"utf-8\");\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n parsed = {};\n }\n }\n\n let config: Config;\n let valid = true;\n try {\n config = ConfigSchema.parse(normalizeInlineSecretRefs(parsed));\n } catch {\n config = ConfigSchema.parse({});\n valid = false;\n }\n if (!raw) {\n raw = JSON.stringify(config, null, 2);\n }\n const hash = hashRaw(raw);\n return {\n raw: valid ? JSON.stringify(this.redactConfig(config, params), null, 2) : null,\n hash: valid ? hash : null,\n config,\n redacted: this.redactConfig(config, params),\n valid,\n };\n };\n\n private redactConfig = (config: Config, params: { version?: string } = {}): Record<string, unknown> => {\n const schema = buildConfigSchema({ version: params.version });\n return redactConfigObject(config, schema.uiHints) as Record<string, unknown>;\n };\n\n private validateBaseHash = (baseHash: string | undefined, snapshot: ConfigSnapshot): ConfigMutationResult | null => {\n if (!baseHash) {\n return { ok: false, error: \"config base hash required; re-run config.get and retry\" };\n }\n if (!snapshot.valid || !snapshot.hash) {\n return { ok: false, error: \"config base hash unavailable; re-run config.get and retry\" };\n }\n if (baseHash !== snapshot.hash) {\n return { ok: false, error: \"config changed since last load; re-run config.get and retry\" };\n }\n return null;\n };\n\n private validateConfigInput = (input: Record<string, unknown>): { ok: true; config: Config } | { ok: false; error: string } => {\n try {\n return { ok: true, config: ConfigSchema.parse(normalizeInlineSecretRefs(input)) };\n } catch (error) {\n return { ok: false, error: `invalid config: ${String(error)}` };\n }\n };\n\n private mutateRawConfig = async (\n params: RawConfigMutationParams,\n resolveInput: (snapshot: ConfigSnapshot, parsed: Record<string, unknown>) => Record<string, unknown>,\n ): Promise<ConfigMutationResult> => {\n const { baseHash, note, raw, version } = params;\n const snapshot = this.readConfigSnapshot({ version });\n const baseHashValidation = this.validateBaseHash(baseHash, snapshot);\n if (baseHashValidation) {\n return baseHashValidation;\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return { ok: false, error: \"invalid JSON in raw config\" };\n }\n\n const validated = this.validateConfigInput(resolveInput(snapshot, parsed));\n return validated.ok\n ? this.applyConfigChange({ nextConfig: validated.config, note, version })\n : validated;\n };\n\n private applyConfigChange = async (params: {\n nextConfig: Config;\n note?: string;\n version?: string;\n }): Promise<ConfigMutationResult> => {\n const { nextConfig, note, version } = params;\n const changedPaths = diffConfigPaths(this.readConfigSnapshot({ version }).config, nextConfig);\n\n if (changedPaths.length === 0) {\n return this.createConfigMutationResult({\n changedPaths,\n config: nextConfig,\n note,\n version,\n });\n }\n\n saveConfig(nextConfig, this.configPath);\n await this.applyReloadPlan(nextConfig);\n return this.createConfigMutationResult({\n changedPaths,\n config: nextConfig,\n note,\n version,\n });\n };\n\n private createConfigMutationResult = (params: {\n changedPaths: string[];\n config: Config;\n note?: string;\n version?: string;\n }): ConfigMutationResult => {\n const { changedPaths, config, note, version } = params;\n const plan = buildReloadPlan(changedPaths);\n const pendingRestart =\n plan.restartRequired.length > 0\n ? {\n required: true as const,\n automatic: false as const,\n changedPaths: [...plan.restartRequired],\n message: `Config saved. Restart manually to apply: ${plan.restartRequired.join(\", \")}.`,\n }\n : null;\n const message =\n changedPaths.length === 0\n ? \"Config already matched the requested state.\"\n : pendingRestart\n ? changedPaths.length > plan.restartRequired.length\n ? \"Config saved. Supported changes were applied immediately; restart manually to apply the rest.\"\n : \"Config saved. Restart manually to apply changes.\"\n : \"Config saved and applied.\";\n\n return {\n ok: true,\n note: note ?? null,\n path: this.configPath,\n config: this.redactConfig(config, { version }),\n changedPaths: [...changedPaths],\n message,\n pendingRestart,\n };\n };\n}\n","import { spawn } from \"node:child_process\";\nimport type {\n ExtensionManifest,\n RunningExtensionProcess,\n} from \"@kernel/features/extension-runtime/index.js\";\n\nfunction sanitizeExtensionNodeOptions(value: string | undefined): string | undefined {\n if (!value?.trim()) {\n return undefined;\n }\n const tokens = value.split(/\\s+/).filter(Boolean);\n const sanitized: string[] = [];\n for (let index = 0; index < tokens.length; index += 1) {\n const token = tokens[index];\n if (token === \"--conditions=development\" || token === \"-C=development\") {\n continue;\n }\n if ((token === \"--conditions\" || token === \"-C\") && tokens[index + 1] === \"development\") {\n index += 1;\n continue;\n }\n sanitized.push(token);\n }\n return sanitized.length > 0 ? sanitized.join(\" \") : undefined;\n}\n\nexport class ExtensionLifecycleService {\n private readonly processes = new Map<string, RunningExtensionProcess>();\n\n startAll = (manifests: ExtensionManifest[], params: {\n endpoint: string;\n token: string;\n }): RunningExtensionProcess[] => {\n const started: RunningExtensionProcess[] = [];\n for (const manifest of manifests) {\n try {\n started.push(this.start(manifest, params));\n } catch (error) {\n console.warn(`Extension ${manifest.id} failed to start: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n return started;\n };\n\n stopAll = async (): Promise<void> => {\n const processes = [...this.processes.values()];\n this.processes.clear();\n await Promise.all(processes.map(async ({ process }) => {\n if (process.exitCode !== null || process.signalCode !== null) {\n return;\n }\n process.kill();\n await new Promise<void>((resolvePromise) => {\n process.once(\"exit\", () => resolvePromise());\n process.once(\"error\", () => resolvePromise());\n setTimeout(resolvePromise, 1000).unref();\n });\n }));\n };\n\n private start = (\n manifest: ExtensionManifest,\n params: {\n endpoint: string;\n token: string;\n },\n ): RunningExtensionProcess => {\n const existing = this.processes.get(manifest.id);\n if (existing) {\n return existing;\n }\n const command = manifest.server.command === \"node\" || manifest.server.command === \"node.exe\"\n ? process.execPath\n : manifest.server.command;\n const child = spawn(command, manifest.server.args ?? [], {\n cwd: manifest.rootDir,\n env: {\n ...process.env,\n NODE_OPTIONS: sanitizeExtensionNodeOptions(process.env.NODE_OPTIONS),\n ...manifest.server.env,\n NEXTCLAW_EXTENSION_ID: manifest.id,\n NEXTCLAW_EXTENSION_ENDPOINT: params.endpoint,\n NEXTCLAW_EXTENSION_TOKEN: params.token,\n },\n stdio: [\"ignore\", \"ignore\", \"inherit\"],\n windowsHide: true,\n });\n const running = { manifest, process: child };\n this.processes.set(manifest.id, running);\n child.once(\"exit\", () => {\n if (this.processes.get(manifest.id)?.process === child) {\n this.processes.delete(manifest.id);\n }\n console.warn(`Extension ${manifest.id} exited.`);\n });\n child.once(\"error\", (error) => {\n console.warn(`Extension ${manifest.id} failed: ${error.message}`);\n });\n return running;\n };\n}\n","import { getDataPath } from \"@nextclaw/core\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Config, ExtensionManifest } from \"@kernel/features/extension-runtime/index.js\";\n\nconst EXTENSION_MANIFEST_FILE = \"nextclaw.extension.json\";\nconst BUILTIN_EXTENSION_PACKAGES = [\n \"@nextclaw/channel-extension-feishu\",\n \"@nextclaw/channel-extension-qq\",\n \"@nextclaw/channel-extension-weixin\",\n] as const;\nconst runtimeRequire = createRequire(import.meta.url);\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readStringArray(value: unknown): string[] | undefined {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\") ? value : undefined;\n}\n\nfunction readStringRecord(value: unknown): Record<string, string> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n const entries = Object.entries(value);\n return entries.every(([, item]) => typeof item === \"string\")\n ? Object.fromEntries(entries) as Record<string, string>\n : undefined;\n}\n\nfunction readRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {};\n}\n\nfunction uniquePaths(paths: string[]): string[] {\n const seen = new Set<string>();\n const unique: string[] = [];\n for (const path of paths) {\n const normalized = resolve(path);\n if (!seen.has(normalized)) {\n seen.add(normalized);\n unique.push(normalized);\n }\n }\n return unique;\n}\n\nfunction findExtensionManifestRoot(startPath: string): string | undefined {\n let current = resolve(startPath);\n while (true) {\n if (existsSync(join(current, EXTENSION_MANIFEST_FILE))) {\n return current;\n }\n const parent = dirname(current);\n if (parent === current) {\n return undefined;\n }\n current = parent;\n }\n}\n\nfunction resolveDevFirstPartyExtensionDir(\n explicitDir = process.env.NEXTCLAW_DEV_FIRST_PARTY_PLUGIN_DIR,\n moduleDir = dirname(fileURLToPath(import.meta.url)),\n): string | undefined {\n const configured = explicitDir?.trim();\n if (configured) {\n return configured;\n }\n const candidates = [\n resolve(moduleDir, \"../../extensions\"),\n resolve(moduleDir, \"../../../extensions\"),\n resolve(moduleDir, \"../../../../extensions\"),\n resolve(moduleDir, \"../../../../../extensions\"),\n ];\n return candidates.find((candidate) => existsSync(candidate));\n}\n\nfunction toManifest(value: unknown, rootDir: string): ExtensionManifest {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"extension manifest must be an object\");\n }\n const record = value as Record<string, unknown>;\n const server = readRecord(record.server);\n const id = readString(record.id);\n const command = readString(server.command);\n if (!id) {\n throw new Error(\"extension manifest id is required\");\n }\n if (server.type !== \"stdio\") {\n throw new Error(\"extension server.type must be stdio\");\n }\n if (!command) {\n throw new Error(\"extension server.command is required\");\n }\n return {\n id,\n rootDir,\n ...(readString(record.name) ? { name: readString(record.name) } : {}),\n ...(readString(record.version) ? { version: readString(record.version) } : {}),\n server: {\n type: \"stdio\",\n command,\n ...(readStringArray(server.args) ? { args: readStringArray(server.args) } : {}),\n ...(readStringRecord(server.env) ? { env: readStringRecord(server.env) } : {}),\n },\n ...(record.contributes && typeof record.contributes === \"object\" && !Array.isArray(record.contributes)\n ? { contributes: record.contributes as ExtensionManifest[\"contributes\"] }\n : {}),\n };\n}\n\nexport function resolveBuiltinExtensionManifestRoots(): string[] {\n if (process.env.NEXTCLAW_DISABLE_BUILTIN_EXTENSIONS === \"1\") {\n return [];\n }\n const roots: string[] = [];\n for (const packageName of BUILTIN_EXTENSION_PACKAGES) {\n try {\n const entryPath = runtimeRequire.resolve(packageName);\n const root = findExtensionManifestRoot(dirname(entryPath));\n if (root) {\n roots.push(root);\n }\n } catch {\n // Built-in packages can be omitted by some development package manager installs.\n }\n }\n return uniquePaths(roots);\n}\n\nexport function resolveExtensionManifestRoots(params: {\n config: Config;\n workspace: string;\n}): string[] {\n const devExtensionsDir = resolveDevFirstPartyExtensionDir();\n return uniquePaths([\n join(getDataPath(), \"extensions\"),\n join(params.workspace, \".nextclaw\", \"extensions\"),\n ...(devExtensionsDir ? [devExtensionsDir] : []),\n ...resolveBuiltinExtensionManifestRoots(),\n ...(params.config.plugins.load?.paths ?? []),\n ]);\n}\n\nexport class ExtensionManifestDiscoveryService {\n discover = async (roots: string[]): Promise<ExtensionManifest[]> => {\n const manifests: ExtensionManifest[] = [];\n for (const root of roots) {\n manifests.push(...(await this.discoverRoot(root)));\n }\n return this.uniqueById(manifests);\n };\n\n discoverSync = (roots: string[]): ExtensionManifest[] => {\n const manifests: ExtensionManifest[] = [];\n for (const root of roots) {\n manifests.push(...this.discoverRootSync(root));\n }\n return this.uniqueById(manifests);\n };\n\n private uniqueById = (manifests: ExtensionManifest[]): ExtensionManifest[] => {\n const seen = new Set<string>();\n const unique: ExtensionManifest[] = [];\n for (const manifest of manifests) {\n if (seen.has(manifest.id)) {\n continue;\n }\n seen.add(manifest.id);\n unique.push(manifest);\n }\n return unique;\n };\n\n private discoverRoot = async (root: string): Promise<ExtensionManifest[]> => {\n const directManifest = await this.readManifestIfExists(join(root, EXTENSION_MANIFEST_FILE));\n if (directManifest) {\n return [directManifest];\n }\n const entries = await readdir(root, { withFileTypes: true }).catch(() => []);\n const manifests = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => this.readManifestIfExists(join(root, entry.name, EXTENSION_MANIFEST_FILE))),\n );\n return manifests.filter((manifest): manifest is ExtensionManifest => Boolean(manifest));\n };\n\n private discoverRootSync = (root: string): ExtensionManifest[] => {\n const directManifest = this.readManifestIfExistsSync(join(root, EXTENSION_MANIFEST_FILE));\n if (directManifest) {\n return [directManifest];\n }\n return this.readDirectoriesSync(root)\n .map((entry) => this.readManifestIfExistsSync(join(root, entry, EXTENSION_MANIFEST_FILE)))\n .filter((manifest): manifest is ExtensionManifest => Boolean(manifest));\n };\n\n private readManifestIfExists = async (path: string): Promise<ExtensionManifest | null> => {\n try {\n return toManifest(JSON.parse(await readFile(path, \"utf-8\")), dirname(path));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n };\n\n private readManifestIfExistsSync = (path: string): ExtensionManifest | null => {\n try {\n return toManifest(JSON.parse(readFileSync(path, \"utf-8\")), dirname(path));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n };\n\n private readDirectoriesSync = (root: string): string[] => {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n } catch {\n return [];\n }\n };\n}\n","import type { Config } from \"@nextclaw/core\";\nimport {\n ExtensionManifestDiscoveryService,\n resolveExtensionManifestRoots,\n} from \"@kernel/features/extension-runtime/index.js\";\n\nexport function listExtensionChannelIds(params: {\n config: Config;\n workspace: string;\n}): string[] {\n const discovery = new ExtensionManifestDiscoveryService();\n const manifests = discovery.discoverSync(resolveExtensionManifestRoots(params));\n const channelIds: string[] = [];\n for (const manifest of manifests) {\n for (const channel of manifest.contributes?.channels ?? []) {\n const channelId = typeof channel.id === \"string\" ? channel.id.trim() : \"\";\n if (channelId && !channelIds.includes(channelId)) {\n channelIds.push(channelId);\n }\n }\n }\n return channelIds;\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n ingressKeys,\n type ExtensionChannelConfigGetIngressPayload,\n type ExtensionChannelMessageSubmitIngressPayload,\n type ExtensionResponseIngressPayload,\n type IngressContext,\n type IngressEnvelope,\n} from \"@nextclaw/shared\";\nimport type {\n OpenClawChannelAuthLoginResult,\n OpenClawChannelAuthPollResult,\n OpenClawChannelAuthStartResult,\n PluginChannelBinding,\n PluginUiMetadata,\n} from \"@nextclaw/openclaw-compat\";\nimport {\n ExtensionLifecycleService,\n ExtensionManifestDiscoveryService,\n resolveExtensionManifestRoots,\n type Config,\n type ExtensionChannelRequestKind,\n type ExtensionManifest,\n type ExtensionRequestSender,\n type ExtensionRuntimeContributions,\n type ExtensionRuntimeServiceOptions,\n type InboundAttachment,\n type InboundMessage,\n type PendingExtensionRequest,\n} from \"@kernel/features/extension-runtime/index.js\";\n\nconst EXTENSION_REQUEST_EVENT_TYPE = \"extension.request\";\nconst EXTENSION_REQUEST_TIMEOUT_MS = 60_000;\n\ntype PluginChannelAuth = NonNullable<PluginChannelBinding[\"channel\"][\"auth\"]>;\ntype PluginChannelOutbound = NonNullable<PluginChannelBinding[\"channel\"][\"outbound\"]>;\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {};\n}\n\nfunction readRequiredString(value: unknown, name: string): string {\n const trimmed = readString(value);\n if (!trimmed) {\n throw new Error(`${name} is required`);\n }\n return trimmed;\n}\n\nfunction readTextContent(value: unknown): string {\n const content = readRecord(value);\n if (content.type !== \"text\" || typeof content.text !== \"string\") {\n throw new Error(\"only text channel messages are supported by the first ingress bridge\");\n }\n return content.text;\n}\n\nfunction readOptionalNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction readInboundAttachments(value: unknown): InboundAttachment[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .filter((entry): entry is Record<string, unknown> =>\n Boolean(entry && typeof entry === \"object\" && !Array.isArray(entry))\n )\n .map((entry) => ({\n ...(readString(entry.id) ? { id: readString(entry.id) } : {}),\n ...(readString(entry.name) ? { name: readString(entry.name) } : {}),\n ...(readString(entry.path) ? { path: readString(entry.path) } : {}),\n ...(readString(entry.url) ? { url: readString(entry.url) } : {}),\n ...(readString(entry.assetUri) ? { assetUri: readString(entry.assetUri) } : {}),\n ...(readString(entry.mimeType) ? { mimeType: readString(entry.mimeType) } : {}),\n ...(readOptionalNumber(entry.size) !== undefined ? { size: readOptionalNumber(entry.size) } : {}),\n ...(readString(entry.source) ? { source: readString(entry.source) } : {}),\n ...(entry.status === \"ready\" || entry.status === \"remote-only\" ? { status: entry.status } : {}),\n ...(readString(entry.errorCode) ? { errorCode: readString(entry.errorCode) as InboundAttachment[\"errorCode\"] } : {}),\n }));\n}\n\nfunction toInboundMessage(value: unknown): InboundMessage {\n const payload = readRecord(value);\n return {\n channel: readRequiredString(payload.channelId, \"channelId\"),\n chatId: readRequiredString(payload.conversationId, \"conversationId\"),\n senderId: readRequiredString(payload.senderId, \"senderId\"),\n content: readTextContent(payload.content),\n timestamp: new Date(),\n attachments: readInboundAttachments(payload.attachments),\n metadata: readRecord(payload.metadata),\n };\n}\n\nclass ExtensionChannelClient implements PluginChannelAuth, PluginChannelOutbound {\n constructor(\n private readonly params: {\n extensionId: string;\n channelId: string;\n request: ExtensionRequestSender;\n },\n ) {}\n\n readonly login: PluginChannelAuth[\"login\"] = async ({ accountId, baseUrl, verbose }) =>\n await this.params.request<OpenClawChannelAuthLoginResult>({\n extensionId: this.params.extensionId,\n kind: \"channel.auth.login\",\n payload: {\n channelId: this.params.channelId,\n accountId,\n baseUrl,\n verbose,\n },\n });\n\n readonly start: PluginChannelAuth[\"start\"] = async (params) =>\n await this.params.request<OpenClawChannelAuthStartResult>({\n extensionId: this.params.extensionId,\n kind: \"channel.auth.start\",\n payload: {\n channelId: this.params.channelId,\n accountId: params.accountId,\n baseUrl: params.baseUrl,\n domain: (params as { domain?: string | null }).domain,\n },\n });\n\n readonly poll: PluginChannelAuth[\"poll\"] = async ({ sessionId }) =>\n await this.params.request<OpenClawChannelAuthPollResult | null>({\n extensionId: this.params.extensionId,\n kind: \"channel.auth.poll\",\n payload: {\n channelId: this.params.channelId,\n sessionId,\n },\n });\n\n readonly sendText: PluginChannelOutbound[\"sendText\"] = async ({ to, text, accountId, replyTo, media, metadata }) =>\n await this.params.request({\n extensionId: this.params.extensionId,\n kind: \"channel.outbound.sendText\",\n payload: {\n channelId: this.params.channelId,\n to,\n text,\n accountId,\n replyTo,\n media,\n metadata,\n },\n });\n}\n\nexport class ExtensionRuntimeService {\n readonly token = randomUUID();\n private readonly lifecycle = new ExtensionLifecycleService();\n private readonly pendingRequests = new Map<string, PendingExtensionRequest>();\n private manifests: ExtensionManifest[] = [];\n\n constructor(private readonly options: ExtensionRuntimeServiceOptions) {}\n\n readonly registerIngressHandlers = (): void => {\n this.options.ingress.addHandler(\n ingressKeys.extension.channelConfigGet,\n this.handleChannelConfigGet,\n );\n this.options.ingress.addHandler(\n ingressKeys.extension.channelMessageSubmit,\n this.handleChannelMessageSubmit,\n );\n this.options.ingress.addHandler(\n ingressKeys.extension.response,\n this.handleExtensionResponse,\n );\n };\n\n readonly loadChannelContributions = async (params: {\n config: Config;\n workspace: string;\n }): Promise<ExtensionRuntimeContributions> => {\n this.manifests = await this.discoverManifests(params);\n return this.toContributions(this.manifests);\n };\n\n readonly start = async (params: { endpoint: string | null }): Promise<void> => {\n const endpoint = params.endpoint?.trim();\n if (!endpoint) {\n return;\n }\n const manifests = this.manifests.length > 0\n ? this.manifests\n : await this.discoverManifests({\n config: this.options.getConfig(),\n workspace: this.options.getWorkspace(),\n });\n const running = this.lifecycle.startAll(manifests, {\n endpoint,\n token: this.token,\n });\n if (running.length > 0) {\n console.log(`✓ Extensions started: ${running.map((entry) => entry.manifest.id).join(\", \")}`);\n }\n };\n\n readonly stop = async (): Promise<void> => {\n await this.lifecycle.stopAll();\n for (const [requestId, request] of this.pendingRequests) {\n clearTimeout(request.timeout);\n request.reject(new Error(`Extension request cancelled: ${requestId}`));\n }\n this.pendingRequests.clear();\n };\n\n private readonly discoverManifests = async (params: {\n config: Config;\n workspace: string;\n }): Promise<ExtensionManifest[]> => {\n const discovery = new ExtensionManifestDiscoveryService();\n return await discovery.discover(resolveExtensionManifestRoots(params));\n };\n\n private readonly toContributions = (manifests: ExtensionManifest[]): ExtensionRuntimeContributions => {\n const channelBindings: PluginChannelBinding[] = [];\n const uiMetadata: PluginUiMetadata[] = [];\n for (const manifest of manifests) {\n for (const channel of manifest.contributes?.channels ?? []) {\n const channelId = readString(channel.id);\n if (!channelId) {\n continue;\n }\n const configUiHints = this.readConfigUiHints(channel.configUiHints);\n channelBindings.push({\n pluginId: manifest.id,\n channelId,\n channel: {\n id: channelId,\n meta: {\n label: channel.name ?? channelId,\n selectionLabel: channel.name ?? channelId,\n ...(channel.description ? { blurb: channel.description } : {}),\n ...(channel.meta ?? {}),\n },\n ...(channel.configSchema ? {\n configSchema: {\n schema: channel.configSchema,\n ...(configUiHints ? { uiHints: configUiHints } : {}),\n },\n } : {}),\n ...(channel.auth ? { auth: this.createChannelAuth(manifest.id, channelId) } : {}),\n outbound: this.createChannelOutbound(manifest.id, channelId),\n },\n });\n uiMetadata.push({\n id: manifest.id,\n configSchema: channel.configSchema,\n ...(configUiHints ? { configUiHints } : {}),\n });\n }\n }\n return { channelBindings, uiMetadata };\n };\n\n private readonly handleChannelConfigGet = (\n envelope: IngressEnvelope<ExtensionChannelConfigGetIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n const payload = readRecord(envelope.payload);\n const channelId = readRequiredString(payload.channelId, \"channelId\");\n return {\n config: (this.options.getConfig().channels as Record<string, unknown>)[channelId] ?? {},\n };\n };\n\n private readonly handleChannelMessageSubmit = async (\n envelope: IngressEnvelope<ExtensionChannelMessageSubmitIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n await this.options.messageBus.publishInbound(toInboundMessage(envelope.payload));\n return { accepted: true };\n };\n\n private readonly handleExtensionResponse = (\n envelope: IngressEnvelope<ExtensionResponseIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n const payload = readRecord(envelope.payload);\n const requestId = readRequiredString(payload.requestId, \"requestId\");\n const pending = this.pendingRequests.get(requestId);\n if (!pending) {\n return { accepted: false };\n }\n this.pendingRequests.delete(requestId);\n clearTimeout(pending.timeout);\n if (payload.ok === false) {\n const error = readRecord(payload.error);\n const message = readString(error.message) ?? \"Extension request failed\";\n pending.reject(new Error(message));\n return { accepted: true };\n }\n pending.resolve(payload.data);\n return { accepted: true };\n };\n\n private readonly readConfigUiHints = (\n value: unknown,\n ): PluginUiMetadata[\"configUiHints\"] | undefined => {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as PluginUiMetadata[\"configUiHints\"]\n : undefined;\n };\n\n private readonly createChannelAuth = (\n extensionId: string,\n channelId: string,\n ): PluginChannelAuth =>\n new ExtensionChannelClient({\n extensionId,\n channelId,\n request: this.requestExtension,\n });\n\n private readonly createChannelOutbound = (\n extensionId: string,\n channelId: string,\n ): PluginChannelOutbound =>\n new ExtensionChannelClient({\n extensionId,\n channelId,\n request: this.requestExtension,\n });\n\n private readonly requestExtension = async <T>(params: {\n extensionId: string;\n kind: ExtensionChannelRequestKind;\n payload: Record<string, unknown>;\n }): Promise<T> => {\n const requestId = randomUUID();\n const result = new Promise<T>((resolvePromise, rejectPromise) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n rejectPromise(new Error(`Extension request timed out: ${params.kind}`));\n }, EXTENSION_REQUEST_TIMEOUT_MS);\n this.pendingRequests.set(requestId, {\n resolve: (value) => resolvePromise(value as T),\n reject: rejectPromise,\n timeout,\n });\n });\n this.options.eventBus.emitEnvelope({\n type: EXTENSION_REQUEST_EVENT_TYPE,\n payload: {\n requestId,\n extensionId: params.extensionId,\n kind: params.kind,\n payload: params.payload,\n },\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n });\n return await result;\n };\n\n private readonly assertAuthorized = (context: IngressContext): void => {\n if (context.token !== this.token) {\n throw new Error(\"Unauthorized ingress token\");\n }\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { getDataPath, type Config } from \"@nextclaw/core\";\n\ntype WorkspacePluginPackage = {\n pluginId: string;\n packageName: string;\n dir: string;\n supportsDevelopmentSource: boolean;\n};\n\ntype InstalledFirstPartyPluginMatch = {\n packageName: string;\n workspaceDir: string;\n installPath: string;\n};\n\nconst readJsonFile = (filePath: string): Record<string, unknown> | null => {\n try {\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null;\n } catch {\n return null;\n }\n};\n\nconst readString = (value: unknown): string | undefined => {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n};\n\nconst toPluginIdFromPackageName = (packageName: string): string => {\n const trimmed = packageName.trim();\n if (!trimmed) {\n return \"\";\n }\n return trimmed.includes(\"/\") ? (trimmed.split(\"/\").pop() ?? trimmed) : trimmed;\n};\n\nconst normalizeInstallRecordPath = (value: unknown): string | undefined => {\n const filePath = readString(value);\n return filePath ? path.resolve(filePath) : undefined;\n};\n\nexport const resolveDevFirstPartyPluginDir = (\n explicitDir: string | undefined,\n moduleDir = path.dirname(fileURLToPath(import.meta.url)),\n): string | undefined => {\n const configured = explicitDir?.trim();\n if (configured) {\n return configured;\n }\n\n const candidates = [\n path.resolve(moduleDir, \"../../../extensions\"),\n path.resolve(moduleDir, \"../../../../extensions\"),\n path.resolve(moduleDir, \"../../../../../extensions\"),\n ];\n return candidates.find((candidate) => fs.existsSync(candidate));\n};\n\nconst hasOpenClawExtensions = (pkg: Record<string, unknown>): boolean => {\n const openclaw = pkg.openclaw;\n if (!openclaw || typeof openclaw !== \"object\" || Array.isArray(openclaw)) {\n return false;\n }\n const extensions = (openclaw as Record<string, unknown>).extensions;\n return (\n Array.isArray(extensions) &&\n extensions.some((entry) => typeof entry === \"string\" && entry.trim().length > 0)\n );\n};\n\nconst hasOpenClawDevelopmentExtensions = (\n pkg: Record<string, unknown>,\n): boolean => {\n const openclaw = pkg.openclaw;\n if (!openclaw || typeof openclaw !== \"object\" || Array.isArray(openclaw)) {\n return false;\n }\n const development = (openclaw as Record<string, unknown>).development;\n if (!development || typeof development !== \"object\" || Array.isArray(development)) {\n return false;\n }\n const extensions = (development as Record<string, unknown>).extensions;\n return (\n Array.isArray(extensions) &&\n extensions.some((entry) => typeof entry === \"string\" && entry.trim().length > 0)\n );\n};\n\nconst normalizePackageSpec = (spec: string): string | undefined => {\n const trimmed = spec.trim();\n if (!trimmed) {\n return undefined;\n }\n if (trimmed.startsWith(\"@\")) {\n const slashIndex = trimmed.indexOf(\"/\");\n if (slashIndex < 0) {\n return undefined;\n }\n const secondAtIndex = trimmed.indexOf(\"@\", slashIndex + 1);\n return secondAtIndex < 0 ? trimmed : trimmed.slice(0, secondAtIndex);\n }\n const versionIndex = trimmed.indexOf(\"@\");\n return versionIndex < 0 ? trimmed : trimmed.slice(0, versionIndex);\n};\n\nconst readWorkspacePluginPackages = (\n workspaceExtensionsDir: string,\n): WorkspacePluginPackage[] => {\n if (!workspaceExtensionsDir.trim() || !fs.existsSync(workspaceExtensionsDir)) {\n return [];\n }\n\n const entries = fs.readdirSync(workspaceExtensionsDir, { withFileTypes: true });\n const packages: WorkspacePluginPackage[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n const packageDir = path.join(workspaceExtensionsDir, entry.name);\n const pkg = readJsonFile(path.join(packageDir, \"package.json\"));\n if (!pkg || !hasOpenClawExtensions(pkg)) {\n continue;\n }\n const packageName = readString(pkg.name);\n if (!packageName?.startsWith(\"@nextclaw/\")) {\n continue;\n }\n packages.push({\n pluginId: toPluginIdFromPackageName(packageName),\n packageName,\n dir: packageDir,\n supportsDevelopmentSource: hasOpenClawDevelopmentExtensions(pkg),\n });\n }\n return packages;\n};\n\nconst readInstalledFirstPartyPluginMatches = (\n workspaceExtensionsDir: string,\n): InstalledFirstPartyPluginMatch[] => {\n const workspacePackages = readWorkspacePluginPackages(workspaceExtensionsDir);\n if (workspacePackages.length === 0) {\n return [];\n }\n\n const globalExtensionsDir = path.join(getDataPath(), \"extensions\");\n if (!fs.existsSync(globalExtensionsDir)) {\n return [];\n }\n\n const workspacePackageByName = new Map(\n workspacePackages.map((entry) => [entry.packageName, entry]),\n );\n const entries = fs.readdirSync(globalExtensionsDir, { withFileTypes: true });\n const matches: InstalledFirstPartyPluginMatch[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n const packageDir = path.join(globalExtensionsDir, entry.name);\n const pkg = readJsonFile(path.join(packageDir, \"package.json\"));\n const packageName = readString(pkg?.name);\n if (!packageName) {\n continue;\n }\n const workspacePackage = workspacePackageByName.get(packageName);\n if (!workspacePackage) {\n continue;\n }\n matches.push({\n packageName,\n workspaceDir: workspacePackage.dir,\n installPath: packageDir,\n });\n }\n return matches;\n};\n\nconst mergeLoadPaths = (existingLoadPaths: string[], devLoadPaths: string[]): string[] => {\n const mergedLoadPaths = [...devLoadPaths];\n for (const entry of existingLoadPaths) {\n if (!mergedLoadPaths.includes(entry)) {\n mergedLoadPaths.push(entry);\n }\n }\n return mergedLoadPaths;\n};\n\nconst findWorkspacePackageForInstallRecord = (\n installRecord: Record<string, unknown>,\n workspacePackages: WorkspacePluginPackage[],\n packageByName: Map<string, WorkspacePluginPackage>,\n): WorkspacePluginPackage | undefined => {\n const packageName = normalizePackageSpec(readString(installRecord.spec) ?? \"\");\n if (packageName) {\n const matchedByPackageName = packageByName.get(packageName);\n if (matchedByPackageName) {\n return matchedByPackageName;\n }\n }\n\n const installPathCandidates = new Set(\n [installRecord.sourcePath, installRecord.installPath]\n .map(normalizeInstallRecordPath)\n .filter((entry): entry is string => Boolean(entry)),\n );\n if (installPathCandidates.size === 0) {\n return undefined;\n }\n\n return workspacePackages.find((workspacePackage) =>\n installPathCandidates.has(path.resolve(workspacePackage.dir)),\n );\n};\n\nexport const resolveDevFirstPartyPluginLoadPaths = (\n config: Config,\n workspaceExtensionsDir: string | undefined,\n): string[] => {\n const rootDir = resolveDevFirstPartyPluginDir(workspaceExtensionsDir);\n if (!rootDir) {\n return [];\n }\n\n const workspacePackages = readWorkspacePluginPackages(rootDir);\n if (workspacePackages.length === 0) {\n return [];\n }\n const installedPluginMatches = readInstalledFirstPartyPluginMatches(rootDir);\n\n const packageDirByName = new Map(\n workspacePackages.map((entry) => [entry.packageName, entry.dir]),\n );\n const packageByName = new Map(\n workspacePackages.map((entry) => [entry.packageName, entry]),\n );\n const loadPaths: string[] = [];\n const installs = config.plugins.installs ?? {};\n\n for (const installRecord of Object.values(installs)) {\n const matchedWorkspacePackage = findWorkspacePackageForInstallRecord(\n installRecord,\n workspacePackages,\n packageByName,\n );\n const packageDir = matchedWorkspacePackage\n ? matchedWorkspacePackage.dir\n : packageDirByName.get(normalizePackageSpec(readString(installRecord.spec) ?? \"\") ?? \"\");\n if (!packageDir || loadPaths.includes(packageDir)) {\n continue;\n }\n loadPaths.push(packageDir);\n }\n\n for (const installedPlugin of installedPluginMatches) {\n if (loadPaths.includes(installedPlugin.workspaceDir)) {\n continue;\n }\n loadPaths.push(installedPlugin.workspaceDir);\n }\n\n return loadPaths;\n};\n\nexport const resolveDevFirstPartyPluginInstallRoots = (\n config: Config,\n workspaceExtensionsDir: string | undefined,\n): string[] => {\n const rootDir = resolveDevFirstPartyPluginDir(workspaceExtensionsDir);\n if (!rootDir) {\n return [];\n }\n\n const workspacePackages = readWorkspacePluginPackages(rootDir);\n if (workspacePackages.length === 0) {\n return [];\n }\n\n const packageNames = new Set(\n workspacePackages.map((entry) => entry.packageName),\n );\n const packageByName = new Map(\n workspacePackages.map((entry) => [entry.packageName, entry]),\n );\n const installRoots: string[] = [];\n const installedPluginMatches = readInstalledFirstPartyPluginMatches(rootDir);\n\n for (const installedPlugin of installedPluginMatches) {\n if (installRoots.includes(installedPlugin.installPath)) {\n continue;\n }\n installRoots.push(installedPlugin.installPath);\n }\n\n for (const installRecord of Object.values(config.plugins.installs ?? {})) {\n const workspacePackage = findWorkspacePackageForInstallRecord(\n installRecord,\n workspacePackages,\n packageByName,\n );\n const packageName = normalizePackageSpec(readString(installRecord.spec) ?? \"\");\n if (!workspacePackage && (!packageName || !packageNames.has(packageName))) {\n continue;\n }\n const installPath = readString(installRecord.installPath);\n if (!installPath || installRoots.includes(installPath)) {\n continue;\n }\n if (workspacePackage && path.resolve(installPath) === path.resolve(workspacePackage.dir)) {\n continue;\n }\n installRoots.push(installPath);\n }\n\n return installRoots;\n};\n\nexport const applyDevFirstPartyPluginLoadPaths = (\n config: Config,\n workspaceExtensionsDir: string | undefined,\n): Config => {\n const rootDir = resolveDevFirstPartyPluginDir(workspaceExtensionsDir);\n if (!rootDir) {\n return config;\n }\n const workspacePackages = readWorkspacePluginPackages(rootDir);\n if (workspacePackages.length === 0) {\n return config;\n }\n const devLoadPaths = resolveDevFirstPartyPluginLoadPaths(config, rootDir);\n if (devLoadPaths.length === 0) {\n return config;\n }\n const existingLoadPaths = Array.isArray(config.plugins.load?.paths)\n ? config.plugins.load.paths.filter(\n (entry): entry is string =>\n typeof entry === \"string\" && entry.trim().length > 0,\n )\n : [];\n const mergedLoadPaths = mergeLoadPaths(existingLoadPaths, devLoadPaths);\n return {\n ...config,\n plugins: {\n ...config.plugins,\n load: {\n ...config.plugins.load,\n paths: mergedLoadPaths,\n },\n },\n };\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { Config } from \"@nextclaw/core\";\nimport {\n getPackageManifestExtensions,\n loadPluginManifest,\n type PackageManifest,\n} from \"@nextclaw/openclaw-compat\";\nimport {\n applyDevFirstPartyPluginLoadPaths,\n resolveDevFirstPartyPluginInstallRoots,\n} from \"./first-party-plugin-load-paths.utils.js\";\n\nexport const DEV_PLUGIN_OVERRIDES_ENV = \"NEXTCLAW_DEV_PLUGIN_OVERRIDES\";\ntype PluginEntrySource = \"production\" | \"development\";\n\nexport type DevPluginOverride = {\n pluginId: string;\n pluginPath: string;\n source: PluginEntrySource;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction readOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction readPackageManifest(pluginPath: string): PackageManifest | null {\n const packageJsonPath = path.join(pluginPath, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) {\n return null;\n }\n try {\n return JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\")) as PackageManifest;\n } catch {\n return null;\n }\n}\n\nfunction assertOverridePluginReadable(override: DevPluginOverride): void {\n if (!fs.existsSync(override.pluginPath)) {\n throw new Error(\n `[dev-plugin-override] plugin path does not exist for \"${override.pluginId}\": ${override.pluginPath}`,\n );\n }\n\n const packageManifest = readPackageManifest(override.pluginPath);\n if (!packageManifest) {\n throw new Error(\n `[dev-plugin-override] package.json is missing or invalid for \"${override.pluginId}\": ${override.pluginPath}`,\n );\n }\n\n const pluginManifest = loadPluginManifest(override.pluginPath);\n if (!pluginManifest.ok) {\n throw new Error(\n `[dev-plugin-override] ${pluginManifest.error} for \"${override.pluginId}\": ${override.pluginPath}`,\n );\n }\n if (pluginManifest.manifest.id !== override.pluginId) {\n throw new Error(\n `[dev-plugin-override] plugin id mismatch: expected \"${override.pluginId}\" but found \"${pluginManifest.manifest.id}\" at ${override.pluginPath}`,\n );\n }\n\n const extensions = getPackageManifestExtensions(packageManifest, override.source);\n if (extensions.length === 0) {\n const missingEntry =\n override.source === \"development\"\n ? \"openclaw.development.extensions\"\n : \"openclaw.extensions\";\n throw new Error(\n `[dev-plugin-override] ${missingEntry} is missing for \"${override.pluginId}\" at ${override.pluginPath}`,\n );\n }\n}\n\nfunction readOverrideRecord(\n value: unknown,\n index: number,\n): DevPluginOverride {\n if (!isRecord(value)) {\n throw new Error(\n `[dev-plugin-override] override[${index}] must be an object`,\n );\n }\n\n const pluginId = readOptionalString(value.pluginId);\n const pluginPath = readOptionalString(value.pluginPath);\n const source =\n value.source === \"development\" ? \"development\" : \"production\";\n if (!pluginId || !pluginPath) {\n throw new Error(\n `[dev-plugin-override] override[${index}] requires pluginId and pluginPath`,\n );\n }\n\n const normalized = {\n pluginId,\n pluginPath: path.resolve(pluginPath),\n source,\n } satisfies DevPluginOverride;\n assertOverridePluginReadable(normalized);\n return normalized;\n}\n\nexport function resolveDevPluginOverrides(\n rawEnv = process.env[DEV_PLUGIN_OVERRIDES_ENV],\n): DevPluginOverride[] {\n if (typeof rawEnv !== \"string\" || rawEnv.trim().length === 0) {\n return [];\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawEnv);\n } catch (error) {\n throw new Error(\n `[dev-plugin-override] failed to parse ${DEV_PLUGIN_OVERRIDES_ENV}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n\n if (!Array.isArray(parsed)) {\n throw new Error(\n `[dev-plugin-override] ${DEV_PLUGIN_OVERRIDES_ENV} must be a JSON array`,\n );\n }\n\n const seenPluginIds = new Set<string>();\n const overrides = parsed.map((entry, index) => readOverrideRecord(entry, index));\n for (const entry of overrides) {\n if (seenPluginIds.has(entry.pluginId)) {\n throw new Error(\n `[dev-plugin-override] duplicate plugin override for \"${entry.pluginId}\"`,\n );\n }\n seenPluginIds.add(entry.pluginId);\n }\n return overrides;\n}\n\nfunction mergeLoadPaths(existingLoadPaths: string[], overrideLoadPaths: string[]): string[] {\n const merged = [...overrideLoadPaths];\n for (const entry of existingLoadPaths) {\n if (!merged.includes(entry)) {\n merged.push(entry);\n }\n }\n return merged;\n}\n\nfunction applyExplicitDevPluginOverrides(\n config: Config,\n overrides: DevPluginOverride[],\n): Config {\n if (overrides.length === 0) {\n return config;\n }\n\n const nextEntries = { ...(config.plugins.entries ?? {}) };\n for (const override of overrides) {\n nextEntries[override.pluginId] = {\n ...(nextEntries[override.pluginId] ?? {}),\n source: override.source,\n };\n }\n\n const existingLoadPaths = Array.isArray(config.plugins.load?.paths)\n ? config.plugins.load.paths.filter(\n (entry): entry is string =>\n typeof entry === \"string\" && entry.trim().length > 0,\n )\n : [];\n\n return {\n ...config,\n plugins: {\n ...config.plugins,\n entries: nextEntries,\n load: {\n ...config.plugins.load,\n paths: mergeLoadPaths(\n existingLoadPaths,\n overrides.map((entry) => entry.pluginPath),\n ),\n },\n },\n };\n}\n\nfunction resolveDevPluginOverrideInstallRoots(\n config: Config,\n overrides: DevPluginOverride[],\n): string[] {\n const installRoots: string[] = [];\n for (const override of overrides) {\n const installRecord = config.plugins.installs?.[override.pluginId];\n const installPath = readOptionalString(installRecord?.installPath);\n if (!installPath || installRoots.includes(installPath)) {\n continue;\n }\n installRoots.push(installPath);\n }\n return installRoots;\n}\n\nexport function resolveDevPluginLoadingContext(\n config: Config,\n workspaceExtensionsDir: string | undefined,\n rawOverridesEnv = process.env[DEV_PLUGIN_OVERRIDES_ENV],\n): {\n configWithDevPluginOverrides: Config;\n excludedRoots: string[];\n overrides: DevPluginOverride[];\n} {\n const configWithFirstPartyOverrides = applyDevFirstPartyPluginLoadPaths(\n config,\n workspaceExtensionsDir,\n );\n const overrides = resolveDevPluginOverrides(rawOverridesEnv);\n const configWithDevPluginOverrides = applyExplicitDevPluginOverrides(\n configWithFirstPartyOverrides,\n overrides,\n );\n\n const excludedRoots = [\n ...resolveDevFirstPartyPluginInstallRoots(config, workspaceExtensionsDir),\n ...resolveDevPluginOverrideInstallRoots(config, overrides),\n ].filter((entry, index, list) => list.indexOf(entry) === index);\n\n return {\n configWithDevPluginOverrides,\n excludedRoots,\n overrides,\n };\n}\n","import { getAppLogger, type Config } from \"@nextclaw/core\";\nimport {\n discoverPluginStatusReport,\n loadOpenClawPlugins,\n loadOpenClawPluginsProgressively,\n type PluginRegistry,\n} from \"@nextclaw/openclaw-compat\";\nimport { builtinProviderIds } from \"@nextclaw/runtime\";\nimport {\n resolveDevPluginLoadingContext,\n resolveDevFirstPartyPluginDir,\n} from \"@kernel/features/extension-development-source/index.js\";\n\nexport type ExtensionPluginLoadProgress = { loadedPluginCount: number; pluginId?: string };\n\nconst RESERVED_TOOL_NAMES = [\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"list_dir\",\n \"exec\",\n \"web_search\",\n \"web_fetch\",\n \"message\",\n \"spawn\",\n \"sessions_list\",\n \"sessions_history\",\n \"memory_search\",\n \"memory_get\",\n \"subagents\",\n \"gateway\",\n \"cron\",\n] as const;\n\nfunction buildReservedPluginLoadOptions() {\n return {\n reservedToolNames: [...RESERVED_TOOL_NAMES],\n reservedChannelIds: [] as string[],\n reservedProviderIds: builtinProviderIds(),\n };\n}\n\nfunction createPluginLogger() {\n return getAppLogger(\"extension.manager.plugin_registry\");\n}\n\nexport class ExtensionPluginRegistryService {\n discoverEnabledPluginCount = (params: {\n config: Config;\n workspace: string;\n }): number => {\n const { configWithDevPluginOverrides } = this.resolveLoadingContext(params.config);\n return discoverPluginStatusReport({\n config: configWithDevPluginOverrides,\n workspaceDir: params.workspace,\n }).plugins.filter((plugin) => plugin.enabled).length;\n };\n\n load = (params: {\n config: Config;\n workspace: string;\n }): PluginRegistry => {\n const { configWithDevPluginOverrides, excludedRoots } = this.resolveLoadingContext(params.config);\n return loadOpenClawPlugins({\n config: configWithDevPluginOverrides,\n workspaceDir: params.workspace,\n excludeRoots: excludedRoots,\n ...buildReservedPluginLoadOptions(),\n logger: createPluginLogger(),\n });\n };\n\n loadProgressively = async (params: {\n config: Config;\n workspace: string;\n onPluginProcessed?: (params: ExtensionPluginLoadProgress) => void;\n }): Promise<PluginRegistry> => {\n const { configWithDevPluginOverrides, excludedRoots } = this.resolveLoadingContext(params.config);\n return await loadOpenClawPluginsProgressively({\n config: configWithDevPluginOverrides,\n workspaceDir: params.workspace,\n excludeRoots: excludedRoots,\n ...buildReservedPluginLoadOptions(),\n onPluginProcessed: params.onPluginProcessed,\n logger: createPluginLogger(),\n });\n };\n\n private resolveLoadingContext = (config: Config) => {\n const workspaceExtensionsDir = resolveDevFirstPartyPluginDir(\n process.env.NEXTCLAW_DEV_FIRST_PARTY_PLUGIN_DIR,\n );\n return resolveDevPluginLoadingContext(config, workspaceExtensionsDir);\n };\n}\n","import { getWorkspacePath, type Config, type ExtensionChannelRegistration, type ExtensionRegistry, type MessageBus } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { EventBus, Ingress } from \"@nextclaw/shared\";\nimport {\n getPluginChannelBindings,\n getPluginUiMetadataFromRegistry,\n mergePluginConfigView,\n toPluginConfigView,\n type PluginChannelBinding,\n type PluginRegistry,\n type PluginUiMetadata,\n} from \"@nextclaw/openclaw-compat\";\nimport { ExtensionRuntimeService } from \"@kernel/services/extension-runtime.service.js\";\nimport { ExtensionPluginRegistryService, type ExtensionPluginLoadProgress } from \"@kernel/services/extension-plugin-registry.service.js\";\n\ntype ExtensionManifestContributions = {\n channelBindings: PluginChannelBinding[];\n uiMetadata: PluginUiMetadata[];\n};\n\ntype ExtensionSnapshot = {\n extensionRegistry: ExtensionRegistry;\n channelBindings: PluginChannelBinding[];\n uiMetadata: PluginUiMetadata[];\n};\n\nexport type ExtensionLoadProgress = ExtensionPluginLoadProgress;\n\nexport type ExtensionLoadResult = {\n diagnostics: PluginRegistry[\"diagnostics\"];\n totalPluginCount: number;\n loadedPluginCount: number;\n shouldRestartChannels: boolean;\n};\n\ntype ExtensionManagerOptions = {\n configManager: Pick<ConfigManager, \"loadConfig\">;\n eventBus: Pick<EventBus, \"emitEnvelope\">;\n ingress: Pick<Ingress, \"addHandler\">;\n messageBus: Pick<MessageBus, \"publishInbound\">;\n};\n\ntype ExtensionLoadParams = {\n config?: Config;\n changedPaths?: readonly string[];\n onLoadStart?: (params: { totalPluginCount: number }) => void;\n onPluginProcessed?: (params: ExtensionLoadProgress) => void;\n};\n\nfunction createEmptyPluginRegistry(): PluginRegistry {\n return {\n plugins: [],\n tools: [],\n channels: [],\n providers: [],\n diagnostics: [],\n resolvedTools: [],\n };\n}\n\nfunction buildSortedBindingSignatures(bindings: readonly PluginChannelBinding[]): `${string}:${string}`[] {\n return bindings.map((binding) => `${binding.pluginId}:${binding.channelId}` as const).sort();\n}\n\nfunction buildSortedExtensionChannelIds(channels: readonly ExtensionChannelRegistration[]): string[] {\n return channels\n .map((registration) => registration.channel.id)\n .filter((id): id is string => typeof id === \"string\" && id.trim().length > 0)\n .sort();\n}\n\nfunction areSortedStringListsEqual(left: readonly string[], right: readonly string[]): boolean {\n return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction readConfigPathSegment(path: string, prefix: string): string | null {\n if (!path.startsWith(prefix)) {\n return null;\n }\n const [segment] = path.slice(prefix.length).split(\".\");\n return segment?.trim() ? segment.trim() : null;\n}\n\nfunction shouldRestartChannelsForExtensionReload(params: {\n changedPaths: readonly string[];\n currentSnapshot: ExtensionSnapshot;\n nextSnapshot: ExtensionSnapshot;\n}): boolean {\n const { changedPaths, currentSnapshot, nextSnapshot } = params;\n const currentBindingSignatures = buildSortedBindingSignatures(currentSnapshot.channelBindings);\n const nextBindingSignatures = buildSortedBindingSignatures(nextSnapshot.channelBindings);\n if (!areSortedStringListsEqual(currentBindingSignatures, nextBindingSignatures)) {\n return true;\n }\n\n const currentExtensionChannelIds = buildSortedExtensionChannelIds(currentSnapshot.extensionRegistry.channels);\n const nextExtensionChannelIds = buildSortedExtensionChannelIds(nextSnapshot.extensionRegistry.channels);\n if (!areSortedStringListsEqual(currentExtensionChannelIds, nextExtensionChannelIds)) {\n return true;\n }\n\n const channelPluginIds = new Set<string>();\n const channelIds = new Set<string>();\n for (const binding of [...currentSnapshot.channelBindings, ...nextSnapshot.channelBindings]) {\n channelPluginIds.add(binding.pluginId);\n channelIds.add(binding.channelId);\n }\n\n for (const path of changedPaths) {\n const pluginId = readConfigPathSegment(path, \"plugins.entries.\");\n if (pluginId && channelPluginIds.has(pluginId)) {\n return true;\n }\n\n const channelId = readConfigPathSegment(path, \"channels.\");\n if (channelId && channelIds.has(channelId)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction toExtensionRegistry(pluginRegistry: PluginRegistry): ExtensionRegistry {\n return {\n tools: pluginRegistry.tools.map((tool) => ({\n extensionId: tool.pluginId,\n factory: tool.factory,\n names: tool.names,\n optional: tool.optional,\n source: tool.source,\n })),\n channels: pluginRegistry.channels.map((channel) => ({\n extensionId: channel.pluginId,\n channel: channel.channel,\n source: channel.source,\n })),\n diagnostics: pluginRegistry.diagnostics.map((diag) => ({\n level: diag.level,\n message: diag.message,\n extensionId: diag.pluginId,\n source: diag.source,\n })),\n };\n}\n\nfunction toManifestChannelRegistrations(\n channelBindings: PluginChannelBinding[],\n): ExtensionRegistry[\"channels\"] {\n return channelBindings.map((binding) => ({\n extensionId: binding.pluginId,\n channel: binding.channel,\n source: \"extension-manifest\",\n }));\n}\n\nfunction buildExtensionSnapshot(\n registry: PluginRegistry,\n contributions: ExtensionManifestContributions,\n): ExtensionSnapshot {\n const extensionChannelIds = new Set(contributions.channelBindings.map((binding) => binding.channelId));\n const extensionPluginIds = new Set(contributions.uiMetadata.map((metadata) => metadata.id));\n const registryExtensionRegistry = toExtensionRegistry(registry);\n return {\n extensionRegistry: {\n ...registryExtensionRegistry,\n channels: [\n ...registryExtensionRegistry.channels.filter((registration) => {\n const channelId = registration.channel.id?.trim();\n return !channelId || !extensionChannelIds.has(channelId);\n }),\n ...toManifestChannelRegistrations(contributions.channelBindings),\n ],\n },\n channelBindings: [\n ...getPluginChannelBindings(registry).filter((binding) => !extensionChannelIds.has(binding.channelId)),\n ...contributions.channelBindings,\n ],\n uiMetadata: [\n ...getPluginUiMetadataFromRegistry(registry).filter((metadata) => !extensionPluginIds.has(metadata.id)),\n ...contributions.uiMetadata,\n ],\n };\n}\n\nexport class ExtensionManager {\n private snapshot: ExtensionSnapshot = buildExtensionSnapshot(createEmptyPluginRegistry(), {\n channelBindings: [],\n uiMetadata: [],\n });\n private readonly runtime: ExtensionRuntimeService;\n private readonly pluginRegistry = new ExtensionPluginRegistryService();\n\n constructor(private readonly options: ExtensionManagerOptions) {\n this.runtime = new ExtensionRuntimeService({\n eventBus: options.eventBus,\n getConfig: options.configManager.loadConfig,\n getWorkspace: this.getWorkspace,\n ingress: options.ingress,\n messageBus: options.messageBus,\n });\n }\n\n load = async (params: ExtensionLoadParams): Promise<ExtensionLoadResult> => {\n const { changedPaths = [], onLoadStart, onPluginProcessed } = params;\n const config = params.config ?? this.options.configManager.loadConfig();\n const workspace = getWorkspacePath(config.agents.defaults.workspace);\n const totalPluginCount = this.pluginRegistry.discoverEnabledPluginCount({\n config,\n workspace,\n });\n onLoadStart?.({ totalPluginCount });\n let loadedPluginCount = 0;\n const registry = await this.pluginRegistry.loadProgressively({\n config,\n workspace,\n onPluginProcessed: (progress) => {\n loadedPluginCount = progress.loadedPluginCount;\n onPluginProcessed?.(progress);\n },\n });\n const contributions = await this.runtime.loadChannelContributions({\n config,\n workspace,\n });\n const currentSnapshot = this.snapshot;\n const nextSnapshot = buildExtensionSnapshot(registry, contributions);\n this.snapshot = nextSnapshot;\n return {\n diagnostics: registry.diagnostics,\n totalPluginCount,\n loadedPluginCount: loadedPluginCount || totalPluginCount,\n shouldRestartChannels: shouldRestartChannelsForExtensionReload({\n changedPaths,\n currentSnapshot,\n nextSnapshot,\n }),\n };\n };\n\n reloadForConfigChange = async (params: ExtensionLoadParams & {\n changedPaths: readonly string[];\n }): Promise<ExtensionLoadResult> => await this.load(params);\n\n registerIngressHandlers = (): void => {\n this.runtime.registerIngressHandlers();\n };\n\n start = async (params: { endpoint: string | null }): Promise<void> => {\n await this.runtime.start(params);\n };\n\n stop = async (): Promise<void> => {\n await this.runtime.stop();\n };\n\n getExtensionRegistry = (): ExtensionRegistry => this.snapshot.extensionRegistry;\n\n getChannelBindings = (): PluginChannelBinding[] => this.snapshot.channelBindings;\n\n getUiMetadata = (): PluginUiMetadata[] => this.snapshot.uiMetadata;\n\n toConfigView = (config: Config): Config =>\n toPluginConfigView(config, this.snapshot.channelBindings) as Config;\n\n mergeConfigView = (current: Config, nextConfigView: Record<string, unknown>): Config =>\n mergePluginConfigView(current, nextConfigView, this.snapshot.channelBindings);\n\n private readonly getWorkspace = (): string =>\n getWorkspacePath(this.options.configManager.loadConfig().agents.defaults.workspace);\n}\n","import {\n LLMProvider,\n LiteLLMProvider,\n ProviderRegistry,\n type Config,\n type LLMResponse,\n type LLMStreamEvent,\n type ProviderConfig,\n type ThinkingLevel,\n} from \"@nextclaw/core\";\nimport { BUILTIN_PROVIDER_PLUGINS } from \"@nextclaw/runtime\";\n\ntype ProviderChatParams = {\n messages: Array<Record<string, unknown>>;\n tools?: Array<Record<string, unknown>>;\n model?: string | null;\n maxTokens?: number;\n thinkingLevel?: ThinkingLevel | null;\n signal?: AbortSignal;\n};\n\nexport type LlmProviderRuntime = {\n get: (model?: string | null) => LLMProvider;\n chat: (params: ProviderChatParams) => Promise<LLMResponse>;\n chatStream: (params: ProviderChatParams) => AsyncGenerator<LLMStreamEvent>;\n};\n\ntype ProviderRoute = {\n model: string;\n providerName: string | null;\n provider: ProviderConfig | null;\n apiBase: string | null;\n};\n\ntype ProviderConnectionTestInput = {\n providerName: string | null;\n apiKey?: string | null;\n apiBase?: string | null;\n defaultModel: string;\n extraHeaders?: Record<string, string> | null;\n wireApi?: \"auto\" | \"chat\" | \"responses\" | null;\n messages: Array<Record<string, unknown>>;\n maxTokens?: number;\n signal?: AbortSignal;\n};\n\nconst normalizedModel = (value: string | null | undefined): string | null => {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n};\n\nconst headersFingerprint = (headers: Record<string, string> | null | undefined): string => {\n if (!headers) {\n return \"\";\n }\n const sortedEntries = Object.entries(headers).sort(([left], [right]) => left.localeCompare(right));\n return JSON.stringify(sortedEntries);\n};\n\nclass MissingKernelProvider extends LLMProvider {\n constructor(private defaultModel: string) {\n super(null, null);\n }\n\n setDefaultModel = (model: string): void => {\n this.defaultModel = model;\n };\n\n getDefaultModel = (): string => {\n return this.defaultModel;\n };\n\n readonly chat = async (_params: ProviderChatParams): Promise<never> => {\n throw new Error(\"No API key configured yet. Configure provider credentials in UI and retry.\");\n };\n}\n\nexport class LlmProviderManager {\n private readonly providerRegistry: ProviderRegistry;\n private readonly providerPool = new Map<string, LLMProvider>();\n private readonly missingProvider = new MissingKernelProvider(\"gpt-4o\");\n private config: Config | null = null;\n\n constructor() {\n this.providerRegistry = new ProviderRegistry(BUILTIN_PROVIDER_PLUGINS);\n }\n\n load = (config: Config): void => {\n this.config = config;\n this.providerPool.clear();\n this.missingProvider.setDefaultModel(config.agents.defaults.model);\n };\n\n get = (model?: string | null): LLMProvider => {\n const route = this.resolveRoute(model);\n if (!route) {\n return this.missingProvider;\n }\n return this.getOrCreateProvider(route);\n };\n\n readonly chat = async (params: ProviderChatParams): Promise<LLMResponse> => {\n return this.get(params.model ?? null).chat(params);\n };\n\n readonly chatStream = async function* (\n this: LlmProviderManager,\n params: ProviderChatParams\n ): AsyncGenerator<LLMStreamEvent> {\n for await (const event of this.get(params.model ?? null).chatStream(params)) {\n yield event;\n }\n };\n\n readonly testConnection = async (input: ProviderConnectionTestInput): Promise<void> => {\n const provider = this.createProvider({\n providerName: input.providerName,\n provider: {\n enabled: true,\n displayName: \"\",\n apiKey: input.apiKey ?? \"\",\n apiBase: input.apiBase ?? null,\n extraHeaders: input.extraHeaders ?? null,\n wireApi: input.wireApi ?? \"auto\",\n models: [],\n modelThinking: {},\n },\n apiBase: input.apiBase ?? null,\n model: input.defaultModel,\n });\n await provider.chat({\n messages: input.messages,\n model: input.defaultModel,\n maxTokens: input.maxTokens,\n signal: input.signal,\n });\n };\n\n private resolveRoute = (model?: string | null): ProviderRoute | null => {\n if (!this.config) {\n return null;\n }\n\n const effectiveModel = normalizedModel(model) ?? this.config.agents.defaults.model;\n const { provider, name } = this.resolveProvider(effectiveModel);\n const providerSpec = name ? this.providerRegistry.findProviderByName(name) : undefined;\n return {\n model: effectiveModel,\n providerName: name,\n provider,\n apiBase: provider?.apiBase ?? providerSpec?.defaultApiBase ?? null,\n };\n };\n\n private resolveProvider = (model: string): {\n provider: ProviderConfig | null;\n name: string | null;\n } => {\n const providers = this.config?.providers as Record<string, ProviderConfig> | undefined;\n if (!providers) {\n return { provider: null, name: null };\n }\n\n const specs = this.providerRegistry.listProviderSpecs();\n const modelLower = model.toLowerCase();\n const modelPrefix = modelLower.includes(\"/\")\n ? modelLower.slice(0, modelLower.indexOf(\"/\"))\n : \"\";\n\n if (modelPrefix) {\n const prefixed = this.matchPrefixedProvider(providers, modelPrefix);\n if (prefixed) {\n return prefixed;\n }\n }\n\n const keywordMatches = specs\n .map((spec) => ({ name: spec.name, provider: providers[spec.name], spec }))\n .filter((entry) => entry.provider?.enabled !== false && Boolean(entry.provider?.apiKey))\n .filter((entry) => entry.spec.keywords.some((keyword) => modelLower.includes(keyword)));\n if (keywordMatches.length === 1) {\n const match = keywordMatches[0];\n return { provider: match.provider ?? null, name: match.name };\n }\n if (keywordMatches.length > 1) {\n return { provider: null, name: null };\n }\n\n const builtinNames = new Set(specs.map((spec) => spec.name));\n const enabledProviders = Object.entries(providers)\n .filter(([, provider]) => provider.enabled !== false && Boolean(provider.apiKey));\n const enabledBuiltin = enabledProviders.filter(([name]) => builtinNames.has(name));\n if (enabledBuiltin.length === 1) {\n const [name, provider] = enabledBuiltin[0];\n return { provider, name };\n }\n const enabledCustom = enabledProviders.filter(([name]) => !builtinNames.has(name));\n if (enabledCustom.length === 1) {\n const [name, provider] = enabledCustom[0];\n return { provider, name };\n }\n return { provider: null, name: null };\n };\n\n private matchPrefixedProvider = (\n providers: Record<string, ProviderConfig>,\n modelPrefix: string\n ): { provider: ProviderConfig | null; name: string | null } | null => {\n for (const spec of this.providerRegistry.listProviderSpecs()) {\n const provider = providers[spec.name];\n const aliases = [spec.name, spec.modelPrefix ?? \"\"]\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean);\n if (provider && aliases.includes(modelPrefix)) {\n return provider.enabled !== false\n ? { provider, name: spec.name }\n : { provider: null, name: null };\n }\n }\n const customProvider = Object.entries(providers)\n .find(([name]) => name.toLowerCase() === modelPrefix);\n if (!customProvider) {\n return null;\n }\n const [name, provider] = customProvider;\n return provider.enabled !== false ? { provider, name } : { provider: null, name: null };\n };\n\n private getOrCreateProvider = (route: ProviderRoute): LLMProvider => {\n if (!route.provider?.apiKey && !route.model.startsWith(\"bedrock/\")) {\n return this.missingProvider;\n }\n\n const cacheKey = this.buildCacheKey(route);\n const cached = this.providerPool.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const created = this.createProvider(route);\n this.providerPool.set(cacheKey, created);\n return created;\n };\n\n private createProvider = (route: ProviderRoute): LLMProvider => {\n return new LiteLLMProvider({\n apiKey: route.provider?.apiKey ?? null,\n apiBase: route.apiBase,\n defaultModel: route.model,\n extraHeaders: route.provider?.extraHeaders ?? null,\n providerName: route.providerName,\n providerRegistry: this.providerRegistry,\n wireApi: route.provider?.wireApi ?? null,\n });\n };\n\n private buildCacheKey = (route: ProviderRoute): string => {\n const routeProvider = route.provider;\n return [\n route.providerName ?? \"\",\n routeProvider?.apiKey ?? \"\",\n route.apiBase ?? \"\",\n routeProvider?.wireApi ?? \"\",\n headersFingerprint(routeProvider?.extraHeaders ?? null),\n ].join(\"||\");\n };\n}\n","import type { Config } from \"@nextclaw/core\";\nimport { McpRegistryService, McpServerLifecycleManager } from \"@nextclaw/mcp\";\nimport { McpNcpToolRegistryAdapter } from \"@nextclaw/ncp-mcp\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class McpManager {\n private currentMcpConfig: Config;\n private readonly mcpLifecycleManager: McpServerLifecycleManager;\n private readonly mcpRegistryService: McpRegistryService;\n private readonly toolRegistryAdapter: McpNcpToolRegistryAdapter;\n private warmupPromise: Promise<void> | null = null;\n\n constructor(getConfig: () => Config) {\n this.currentMcpConfig = getConfig();\n this.mcpLifecycleManager = new McpServerLifecycleManager({\n getConfig: () => this.currentMcpConfig,\n });\n this.mcpRegistryService = new McpRegistryService({\n getConfig: () => this.currentMcpConfig,\n lifecycleManager: this.mcpLifecycleManager,\n });\n this.toolRegistryAdapter = new McpNcpToolRegistryAdapter(this.mcpRegistryService);\n }\n\n listToolsForRun = (params: { agentId: string }): ReadonlyArray<NcpTool> =>\n this.toolRegistryAdapter.listToolsForRun(params);\n\n start = (): void => {\n this.warmupPromise ??= this.prewarmEnabledServersSafely();\n };\n\n applyConfig = async (config: Config): Promise<void> => {\n const previousConfig = this.currentMcpConfig;\n this.currentMcpConfig = config;\n const reconcileResult = await this.mcpRegistryService.reconcileConfig({\n prevConfig: previousConfig,\n nextConfig: config,\n });\n\n for (const warmResult of reconcileResult.warmed) {\n if (!warmResult.ok) {\n console.warn(`[mcp] Failed to warm ${warmResult.name}: ${warmResult.error}`);\n }\n }\n };\n\n dispose = async (): Promise<void> => {\n await this.warmupPromise?.catch(() => undefined);\n await this.mcpRegistryService.close();\n };\n\n private prewarmEnabledServersSafely = async (): Promise<void> => {\n const results = await this.mcpRegistryService.prewarmEnabledServers();\n for (const result of results) {\n if (!result.ok) {\n console.warn(`[mcp] Failed to warm ${result.name}: ${result.error}`);\n }\n }\n };\n}\n","import {\n type AgentSessionEventRecord,\n type AgentSessionRecord,\n DefaultNcpAgentConversationStateManager,\n} from \"@nextclaw/ncp-toolkit\";\nimport {\n type NcpEndpointEvent,\n NcpEventType,\n type NcpMessage,\n type NcpSessionSummary,\n} from \"@nextclaw/ncp\";\n\nexport const NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION = 1;\nexport const NCP_AGENT_SESSION_JOURNAL_INDEX_FILE = \".ncp-agent-session-index.json\";\n\nconst AUTO_SESSION_LABEL_MAX_LENGTH = 64;\n\nexport type NcpAgentSessionJournalMetadataEntry = {\n _type: \"metadata\";\n version: typeof NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION;\n created_at: string;\n agent_id?: string;\n metadata: Record<string, unknown>;\n};\n\nexport const NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE = \"session.snapshot.message\";\nexport const NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE = \"session.request.accepted\";\nexport const NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE = \"session.request.completed\";\nexport const NCP_SESSION_REQUEST_FAILED_EVENT_TYPE = \"session.request.failed\";\n\ntype NcpAgentSessionSnapshotMessageEvent = {\n type: typeof NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE;\n payload: Extract<NcpEndpointEvent, { type: NcpEventType.MessageSent }>[\"payload\"];\n};\n\nexport type NcpSessionRequestJournalEventType =\n | typeof NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE\n | typeof NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE\n | typeof NCP_SESSION_REQUEST_FAILED_EVENT_TYPE;\n\nexport type NcpSessionRequestJournalEvent = {\n type: NcpSessionRequestJournalEventType;\n payload: {\n sessionId: string;\n request: unknown;\n };\n};\n\nexport type NcpAgentSessionJournalReplayEvent =\n | NcpEndpointEvent\n | NcpAgentSessionSnapshotMessageEvent\n | NcpSessionRequestJournalEvent;\n\ntype NcpAgentSessionReplayableEvent = NcpEndpointEvent | NcpAgentSessionSnapshotMessageEvent;\n\nexport type NcpAgentSessionJournalEventEntry = {\n _type: \"event\";\n version: typeof NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION;\n seq: number;\n timestamp: string;\n event: NcpAgentSessionJournalReplayEvent;\n};\n\nexport type NcpAgentSessionJournalIndex = {\n version: typeof NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION;\n records: NcpSessionSummary[];\n};\n\nexport type LoadedNcpAgentJournalSession = {\n record: AgentSessionRecord;\n nextSeq: number;\n};\n\nexport function normalizeNcpSessionId(sessionId: string): string {\n return sessionId.trim();\n}\n\nexport function safeNcpSessionFilename(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n}\n\nexport function normalizeNcpAgentId(agentId: string | undefined): string | undefined {\n return agentId?.trim().toLowerCase() || undefined;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function toIsoString(value: unknown, fallback: string): string {\n const parsed = typeof value === \"string\" ? Date.parse(value) : NaN;\n return Number.isFinite(parsed) ? new Date(parsed).toISOString() : fallback;\n}\n\nexport function createNcpAgentSessionSummary(record: AgentSessionRecord): NcpSessionSummary {\n const metadata = structuredClone(record.metadata ?? {});\n const label = readOptionalText(metadata.label) ?? resolveAutoSessionLabel(record.messages);\n if (label) {\n metadata.label = label;\n }\n const lastMessageAt = readMessageTimestamp(record.messages.at(-1));\n return {\n sessionId: record.sessionId,\n ...(normalizeNcpAgentId(record.agentId) ? { agentId: normalizeNcpAgentId(record.agentId) } : {}),\n messageCount: record.messages.length,\n ...(record.createdAt ? { createdAt: record.createdAt } : {}),\n updatedAt: record.updatedAt,\n ...(lastMessageAt ? { lastMessageAt } : {}),\n status: \"idle\",\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n };\n}\n\nexport function createNcpAgentSessionJournalMetadataEntry(\n record: AgentSessionEventRecord,\n): NcpAgentSessionJournalMetadataEntry {\n return {\n _type: \"metadata\",\n version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n created_at: record.createdAt ?? record.updatedAt,\n ...(normalizeNcpAgentId(record.agentId) ? { agent_id: normalizeNcpAgentId(record.agentId) } : {}),\n metadata: structuredClone(record.metadata ?? {}),\n };\n}\n\nexport function upsertNcpAgentSessionSummaryEvent(params: {\n current: NcpSessionSummary | undefined;\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n updatedAt: string;\n}): NcpSessionSummary {\n const { current, event, sessionId, updatedAt } = params;\n const eventMessage = readMessageFromSummaryEvent(event);\n const messageCount = current\n ? current.messageCount + (eventMessage ? 1 : 0)\n : eventMessage\n ? 1\n : 0;\n const lastMessageAt = readMessageTimestamp(eventMessage) ?? current?.lastMessageAt;\n return {\n sessionId,\n ...(normalizeNcpAgentId(current?.agentId) ? { agentId: normalizeNcpAgentId(current?.agentId) } : {}),\n messageCount,\n createdAt: current?.createdAt ?? updatedAt,\n updatedAt,\n ...(lastMessageAt ? { lastMessageAt } : {}),\n status: \"idle\",\n };\n}\n\nexport async function replayNcpAgentSessionEvents(\n events: readonly NcpAgentSessionJournalReplayEvent[],\n): Promise<NcpMessage[]> {\n const stateManager = new DefaultNcpAgentConversationStateManager();\n for (const event of events) {\n if (isJournalOnlyEvent(event)) {\n continue;\n }\n await stateManager.dispatch(createReplayEvent(event));\n }\n const snapshot = stateManager.getSnapshot();\n return [\n ...snapshot.messages.map((message) => structuredClone(message)),\n ...(snapshot.streamingMessage ? [structuredClone(snapshot.streamingMessage)] : []),\n ];\n}\n\nfunction createReplayEvent(event: NcpAgentSessionReplayableEvent): NcpEndpointEvent {\n const replayEvent = structuredClone(event);\n const replayMessage = readMessageFromSummaryEvent(replayEvent);\n if (\n replayMessage?.role === \"assistant\" &&\n (replayMessage.status === \"pending\" || replayMessage.status === \"streaming\")\n ) {\n replayMessage.status = \"final\";\n }\n if (\n replayEvent.type === NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE ||\n replayEvent.type === NcpEventType.MessageCompleted\n ) {\n return { type: NcpEventType.MessageSent, payload: replayEvent.payload };\n }\n return replayEvent;\n}\n\nfunction isJournalOnlyEvent(event: NcpAgentSessionJournalReplayEvent): event is NcpSessionRequestJournalEvent {\n return (\n event.type === NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE ||\n event.type === NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE ||\n event.type === NCP_SESSION_REQUEST_FAILED_EVENT_TYPE\n );\n}\n\nexport function readNcpSessionSummaryActivityAt(summary: NcpSessionSummary): string {\n return summary.lastMessageAt ?? summary.createdAt ?? summary.updatedAt;\n}\n\nfunction readMessageTimestamp(message: NcpMessage | undefined): string | undefined {\n return toIsoString(message?.timestamp, \"\") || undefined;\n}\n\nfunction truncateLabel(value: string): string {\n const chars = Array.from(value);\n return chars.length <= AUTO_SESSION_LABEL_MAX_LENGTH\n ? value\n : `${chars.slice(0, AUTO_SESSION_LABEL_MAX_LENGTH).join(\"\")}...`;\n}\n\nfunction readOptionalText(value: unknown): string | null {\n const trimmed = typeof value === \"string\" ? value.trim() : \"\";\n return trimmed || null;\n}\n\nfunction resolveAutoSessionLabel(messages: readonly NcpMessage[]): string | null {\n for (const message of messages) {\n if (message.role !== \"user\") {\n continue;\n }\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"rich-text\") {\n const text = readOptionalText(part.text);\n if (text) {\n return truncateLabel(text);\n }\n }\n }\n }\n return null;\n}\n\nfunction readMessageFromSummaryEvent(event: NcpAgentSessionJournalReplayEvent): NcpMessage | undefined {\n switch (event.type) {\n case NcpEventType.MessageSent:\n return event.payload.message;\n case NcpEventType.MessageCompleted:\n return event.payload.message;\n case NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE:\n return event.payload.message;\n default:\n return undefined;\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport type {\n CreatedSession,\n CreateSessionInput,\n SessionSearchManager,\n} from \"@nextclaw/core\";\nimport { BUILTIN_MAIN_AGENT_ID } from \"@nextclaw/core\";\nimport type {\n ListMessagesOptions,\n ListSessionsOptions,\n NcpMessage,\n NcpSessionApi,\n NcpSessionPatch,\n NcpSessionSummary,\n} from \"@nextclaw/ncp\";\nimport { NcpEventType } from \"@nextclaw/ncp\";\nimport type { AgentSessionRecord } from \"@nextclaw/ncp-toolkit\";\nimport { ContextWindowPreviewManager } from \"@kernel/features/context-compaction/index.js\";\nimport type { NcpAgentSessionJournalStore } from \"@kernel/stores/ncp-agent-session-journal.store.js\";\nimport {\n createNcpAgentSessionSummary,\n type NcpAgentSessionJournalReplayEvent,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\nimport { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\n\nconst DEFAULT_SESSION_TYPE = \"native\";\nconst DEFAULT_LIFECYCLE = \"persistent\";\nconst SESSION_METADATA_LABEL_KEY = \"label\";\nconst CHILD_SESSION_PARENT_METADATA_KEY = \"parent_session_id\";\nconst CHILD_SESSION_REQUEST_METADATA_KEY = \"spawned_by_request_id\";\nconst CHILD_SESSION_LIFECYCLE_METADATA_KEY = \"session_lifecycle\";\n\nexport type NcpSessionManagerOptions = {\n configManager: ConfigManager;\n eventBus: EventBus;\n journalStore: NcpAgentSessionJournalStore;\n sessionSearch: SessionSearchManager;\n};\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim();\n}\n\nfunction applyLimit<T>(items: T[], limit?: number): T[] {\n if (!Number.isFinite(limit) || typeof limit !== \"number\" || limit <= 0) {\n return items;\n }\n return items.slice(0, Math.trunc(limit));\n}\n\nfunction readOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction summarizeTask(task: string): string {\n const normalized = task.trim().replace(/\\s+/g, \" \");\n if (!normalized) {\n return \"Session\";\n }\n return normalized.length <= 72 ? normalized : `${normalized.slice(0, 69)}...`;\n}\n\nfunction buildSessionId(): string {\n return `ncp-${Date.now().toString(36)}-${randomUUID().replace(/-/g, \"\").slice(0, 8)}`;\n}\n\nfunction cloneInheritedMetadata(sourceMetadata: Record<string, unknown>): Record<string, unknown> {\n const nextMetadata: Record<string, unknown> = {};\n const inheritedKeys = [\n \"runtime\",\n \"session_type\",\n \"preferred_model\",\n \"preferred_thinking\",\n \"project_root\",\n \"requested_skill_refs\",\n \"codex_runtime_backend\",\n \"reasoningNormalizationMode\",\n \"reasoning_normalization_mode\",\n ];\n for (const key of inheritedKeys) {\n if (Object.prototype.hasOwnProperty.call(sourceMetadata, key)) {\n nextMetadata[key] = structuredClone(sourceMetadata[key]);\n }\n }\n return nextMetadata;\n}\n\nfunction mergeMetadataOverrides(\n metadata: Record<string, unknown>,\n overrides?: Record<string, unknown>,\n): Record<string, unknown> {\n return overrides && Object.keys(overrides).length > 0\n ? { ...metadata, ...structuredClone(overrides) }\n : metadata;\n}\n\nfunction resolveSessionType(params: {\n runtime?: string;\n sessionType?: string;\n metadata: Record<string, unknown>;\n}): string {\n const { metadata, runtime, sessionType } = params;\n return (\n readOptionalString(runtime) ??\n readOptionalString(metadata.runtime) ??\n readOptionalString(sessionType) ??\n readOptionalString(metadata.session_type) ??\n DEFAULT_SESSION_TYPE\n );\n}\n\nfunction applySessionOverrides(params: {\n lifecycle: string;\n metadata: Record<string, unknown>;\n model?: string;\n parentSessionId?: string;\n projectRoot?: string | null;\n requestId?: string;\n sessionType: string;\n thinkingLevel?: string;\n title?: string;\n}): void {\n const {\n lifecycle,\n metadata,\n model,\n parentSessionId,\n projectRoot,\n requestId,\n sessionType,\n thinkingLevel,\n title,\n } = params;\n metadata.session_type = sessionType;\n metadata.runtime = sessionType;\n metadata[SESSION_METADATA_LABEL_KEY] = title;\n metadata[CHILD_SESSION_LIFECYCLE_METADATA_KEY] = lifecycle;\n if (parentSessionId) {\n metadata[CHILD_SESSION_PARENT_METADATA_KEY] = parentSessionId;\n }\n if (requestId) {\n metadata[CHILD_SESSION_REQUEST_METADATA_KEY] = requestId;\n }\n if (readOptionalString(model)) {\n metadata.model = model?.trim();\n metadata.preferred_model = model?.trim();\n }\n if (readOptionalString(thinkingLevel)) {\n metadata.thinking = thinkingLevel?.trim();\n metadata.preferred_thinking = thinkingLevel?.trim();\n }\n if (readOptionalString(projectRoot)) {\n metadata.project_root = projectRoot?.trim();\n }\n}\n\nfunction isSessionSummaryRefreshEvent(event: NcpAgentSessionJournalReplayEvent): boolean {\n switch (event.type) {\n case NcpEventType.MessageSent:\n case NcpEventType.MessageCompleted:\n case NcpEventType.MessageAbort:\n case NcpEventType.RunFinished:\n case NcpEventType.RunError:\n return true;\n default:\n return false;\n }\n}\n\nexport class NcpSessionManager implements NcpSessionApi {\n private readonly contextWindowPreview: ContextWindowPreviewManager;\n private readonly runningSessionIds = new Set<string>();\n private readonly unsubscribeSessionRunStatus: () => void;\n\n constructor(private readonly options: NcpSessionManagerOptions) {\n this.contextWindowPreview = new ContextWindowPreviewManager({\n configManager: options.configManager,\n });\n this.unsubscribeSessionRunStatus = options.eventBus.on(\n eventKeys.sessionRunStatus,\n this.handleSessionRunStatus,\n );\n }\n\n dispose = (): void => {\n this.unsubscribeSessionRunStatus();\n this.runningSessionIds.clear();\n };\n\n createSession = async (params: CreateSessionInput): Promise<CreatedSession> => {\n const {\n agentId: requestedAgentId,\n metadataOverrides,\n model,\n parentSessionId: rawParentSessionId,\n projectRoot,\n requestId: rawRequestId,\n runtime,\n sessionType: requestedSessionType,\n sourceSessionId,\n sourceSessionMetadata,\n task,\n thinkingLevel,\n title: requestedTitle,\n } = params;\n const sourceRecord = sourceSessionId\n ? await this.getSessionRecord(sourceSessionId)\n : null;\n const metadata = cloneInheritedMetadata(sourceSessionMetadata);\n const title = readOptionalString(requestedTitle) ?? summarizeTask(task);\n const parentSessionId = readOptionalString(rawParentSessionId);\n const requestId = readOptionalString(rawRequestId);\n const sessionType = resolveSessionType({\n runtime,\n sessionType: requestedSessionType,\n metadata,\n });\n applySessionOverrides({\n lifecycle: DEFAULT_LIFECYCLE,\n metadata,\n model,\n parentSessionId: parentSessionId ?? undefined,\n projectRoot,\n requestId: requestId ?? undefined,\n sessionType,\n thinkingLevel,\n title,\n });\n const now = new Date().toISOString();\n const nextMetadata = mergeMetadataOverrides(metadata, metadataOverrides);\n const agentId =\n readOptionalString(requestedAgentId) ??\n readOptionalString(sourceRecord?.agentId) ??\n BUILTIN_MAIN_AGENT_ID;\n const sessionId = buildSessionId();\n const record: AgentSessionRecord = {\n sessionId,\n ...(agentId ? { agentId } : {}),\n messages: [],\n createdAt: now,\n updatedAt: now,\n metadata: nextMetadata,\n };\n await this.options.journalStore.importSessionSnapshot(record);\n await this.publishSessionChange(sessionId);\n return {\n sessionId,\n agentId,\n sessionType,\n runtimeFamily: sessionType === DEFAULT_SESSION_TYPE ? \"native\" : \"external\",\n ...(parentSessionId ? { parentSessionId } : {}),\n ...(requestId ? { spawnedByRequestId: requestId } : {}),\n lifecycle: DEFAULT_LIFECYCLE,\n title,\n metadata: nextMetadata,\n createdAt: now,\n updatedAt: now,\n };\n };\n\n appendSessionEvent = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n }): Promise<void> => {\n const { event } = params;\n const sessionId = normalizeSessionId(params.sessionId);\n if (!sessionId) {\n return;\n }\n await this.options.journalStore.appendSessionEvent({\n event,\n sessionId,\n });\n if (isSessionSummaryRefreshEvent(event)) {\n await this.publishSessionChange(sessionId);\n }\n };\n\n setSessionMetadata = async (\n sessionId: string,\n metadata: Record<string, unknown>,\n ): Promise<boolean> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return false;\n }\n const updated = await this.options.journalStore.setSessionMetadata({\n sessionId: normalizedSessionId,\n metadata: structuredClone(metadata),\n });\n if (!updated) {\n return false;\n }\n this.publishSessionMetadataChanged(normalizedSessionId, metadata, \"set\");\n await this.publishSessionChange(normalizedSessionId);\n return true;\n };\n\n updateSessionMetadata = async (\n sessionId: string,\n metadata: Record<string, unknown>,\n ): Promise<boolean> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return false;\n }\n const updated = await this.options.journalStore.updateSessionMetadata({\n sessionId: normalizedSessionId,\n metadata: structuredClone(metadata),\n });\n if (!updated) {\n return false;\n }\n this.publishSessionMetadataChanged(normalizedSessionId, metadata, \"update\");\n await this.publishSessionChange(normalizedSessionId);\n return true;\n };\n\n updateSession = async (\n sessionId: string,\n patch: NcpSessionPatch,\n ): Promise<NcpSessionSummary | null> => {\n if (!Object.prototype.hasOwnProperty.call(patch, \"metadata\")) {\n return await this.getSession(sessionId);\n }\n const updated = patch.metadata === null\n ? await this.setSessionMetadata(sessionId, {})\n : await this.updateSessionMetadata(sessionId, patch.metadata ?? {});\n return updated ? await this.getSession(sessionId) : null;\n };\n\n deleteSession = async (sessionId: string): Promise<void> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return;\n }\n await this.options.journalStore.deleteSession(normalizedSessionId);\n await this.publishSessionChange(normalizedSessionId);\n };\n\n getSessionRecord = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return null;\n }\n return await this.options.journalStore.getSession(normalizedSessionId);\n };\n\n listSessions = async (options?: ListSessionsOptions): Promise<NcpSessionSummary[]> => {\n const summaries = await this.options.journalStore.listSessionSummaries();\n return applyLimit(summaries, options?.limit).map(this.withLiveSessionStatus);\n };\n\n listSessionMessages = async (\n sessionId: string,\n options?: ListMessagesOptions,\n ): Promise<NcpMessage[]> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return [];\n }\n const messages = await this.options.journalStore.listSessionMessages(normalizedSessionId);\n return applyLimit(messages, options?.limit);\n };\n\n getSession = async (sessionId: string): Promise<NcpSessionSummary | null> => {\n const record = await this.getSessionRecord(sessionId);\n return record ? this.withLiveSessionStatus(this.createSummaryFromRecord(record, true)) : null;\n };\n\n getContextWindow = async (\n sessionId: string,\n liveRecord?: AgentSessionRecord | null,\n ): Promise<Record<string, unknown> | null> => {\n const summary = liveRecord\n ? this.withLiveSessionStatus(this.createSummaryFromRecord(liveRecord, true))\n : await this.getSession(sessionId);\n return summary?.contextWindow ?? null;\n };\n\n publishSessionChange = async (sessionKey: string): Promise<void> => {\n const normalizedSessionKey = normalizeSessionId(sessionKey);\n if (!normalizedSessionKey) {\n return;\n }\n this.options.eventBus.emit(eventKeys.sessionUpdated, { sessionKey: normalizedSessionKey }, {\n emittedAt: new Date().toISOString(),\n source: \"ncp-session\",\n });\n await this.options.sessionSearch.handleSessionUpdated(normalizedSessionKey);\n const summary = await this.getSession(normalizedSessionKey);\n if (summary) {\n this.options.eventBus.emit(eventKeys.sessionSummaryUpsert, { summary });\n return;\n }\n this.options.eventBus.emit(eventKeys.sessionSummaryDelete, {\n sessionKey: normalizedSessionKey,\n });\n };\n\n private createSummaryFromRecord = (\n record: AgentSessionRecord,\n includeContextWindow = false,\n ): NcpSessionSummary => {\n const summary = createNcpAgentSessionSummary(record);\n const contextWindow = includeContextWindow\n ? this.contextWindowPreview.preview({\n requestMetadata: record.metadata ?? {},\n sessionId: record.sessionId,\n sessionMessages: record.messages,\n storedAgentId: record.agentId,\n storedMetadata: record.metadata ?? {},\n })\n : undefined;\n return contextWindow ? { ...summary, contextWindow } : summary;\n };\n\n private withLiveSessionStatus = (summary: NcpSessionSummary): NcpSessionSummary =>\n this.runningSessionIds.has(summary.sessionId)\n ? { ...summary, status: \"running\" }\n : summary;\n\n private handleSessionRunStatus = (payload: {\n sessionKey: string;\n status: \"running\" | \"idle\";\n }): void => {\n const sessionId = normalizeSessionId(payload.sessionKey);\n if (!sessionId) {\n return;\n }\n if (payload.status === \"running\") this.runningSessionIds.add(sessionId);\n else this.runningSessionIds.delete(sessionId);\n };\n\n private publishSessionMetadataChanged = (\n sessionKey: string,\n metadata: Record<string, unknown>,\n mode: \"set\" | \"update\",\n ): void => {\n this.options.eventBus.emit(\n eventKeys.sessionMetadataChanged,\n { sessionKey, mode, metadata: structuredClone(metadata) },\n { emittedAt: new Date().toISOString(), source: \"ncp-session\" },\n );\n };\n}\n","import { parse as parseYaml } from \"yaml\";\n\nexport type LocalizedTextMap = Record<string, string>;\n\nexport type SkillFrontmatter = {\n name?: string;\n summary?: string;\n summaryI18n?: LocalizedTextMap;\n description?: string;\n descriptionI18n?: LocalizedTextMap;\n author?: string;\n tags?: string[];\n};\n\nexport function parseSkillFrontmatter(raw: string): SkillFrontmatter {\n const frontmatter = parseFrontmatterBlock(raw);\n if (!frontmatter) {\n return {};\n }\n\n const parsed = parseYamlFrontmatter(frontmatter);\n const summaryI18n = readLocalizedTextMap(parsed, \"summaryi18n\", \"summary_i18n\");\n const descriptionI18n = readLocalizedTextMap(parsed, \"descriptioni18n\", \"description_i18n\");\n\n return {\n name: readString(parsed, \"name\"),\n summary: readString(parsed, \"summary\"),\n summaryI18n: mergeLocalizedTextMap(summaryI18n, { zh: readString(parsed, \"summaryzh\", \"summary_zh\") }),\n description: readString(parsed, \"description\"),\n descriptionI18n: mergeLocalizedTextMap(descriptionI18n, {\n zh: readString(parsed, \"descriptionzh\", \"description_zh\"),\n }),\n author: readString(parsed, \"author\"),\n tags: readTags(parsed),\n };\n}\n\nexport function stripSkillFrontmatter(raw: string): string {\n const normalized = raw.replace(/\\r\\n/g, \"\\n\");\n const match = normalized.match(/^---\\n[\\s\\S]*?\\n---\\n?/);\n return match ? normalized.slice(match[0].length).trim() : normalized.trim();\n}\n\nexport function buildLocalizedTextMap(\n englishText: string,\n ...maps: Array<LocalizedTextMap | Partial<LocalizedTextMap> | undefined>\n): LocalizedTextMap {\n return {\n ...(mergeLocalizedTextMap(...maps) ?? {}),\n en: englishText,\n };\n}\n\nfunction parseFrontmatterBlock(raw: string): string | null {\n const match = raw.replace(/\\r\\n/g, \"\\n\").match(/^---\\n([\\s\\S]*?)\\n---/);\n return match?.[1] ?? null;\n}\n\nfunction parseYamlFrontmatter(raw: string): Record<string, unknown> {\n try {\n const parsed = parseYaml(raw);\n return isRecord(parsed) ? parsed : {};\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Invalid SKILL.md frontmatter: ${message}`);\n }\n}\n\nfunction readString(record: Record<string, unknown>, ...names: string[]): string | undefined {\n const value = readValue(record, names);\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readLocalizedTextMap(record: Record<string, unknown>, ...names: string[]): LocalizedTextMap | undefined {\n const value = readValue(record, names);\n if (!isRecord(value)) {\n return undefined;\n }\n\n const localized = Object.fromEntries(\n Object.entries(value)\n .filter((entry): entry is [string, string] => typeof entry[1] === \"string\" && entry[1].trim().length > 0)\n .map(([locale, text]) => [normalizeLocaleTag(locale), text.trim()]),\n );\n return Object.keys(localized).length > 0 ? localized : undefined;\n}\n\nfunction readTags(record: Record<string, unknown>): string[] | undefined {\n const value = readValue(record, [\"tags\"]);\n const tags = Array.isArray(value) ? value : typeof value === \"string\" ? value.split(\",\") : [];\n const normalized = tags\n .filter((entry): entry is string => typeof entry === \"string\")\n .map((entry) => entry.trim())\n .filter(Boolean);\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction mergeLocalizedTextMap(\n ...maps: Array<LocalizedTextMap | Partial<LocalizedTextMap> | undefined>\n): LocalizedTextMap | undefined {\n const localized = Object.fromEntries(\n maps.flatMap((map) =>\n Object.entries(map ?? {})\n .filter((entry): entry is [string, string] => typeof entry[1] === \"string\" && entry[1].trim().length > 0)\n .map(([locale, text]) => [normalizeLocaleTag(locale), text.trim()]),\n ),\n );\n return Object.keys(localized).length > 0 ? localized : undefined;\n}\n\nfunction readValue(record: Record<string, unknown>, names: string[]): unknown {\n const normalizedNames = names.map(normalizeFrontmatterKey);\n const matchingKey = Object.keys(record).find((candidate) =>\n normalizedNames.includes(normalizeFrontmatterKey(candidate)),\n );\n return matchingKey ? record[matchingKey] : undefined;\n}\n\nfunction normalizeFrontmatterKey(raw: string): string {\n return raw.replace(/[-_]/g, \"\").toLowerCase();\n}\n\nfunction normalizeLocaleTag(raw: string): string {\n return raw.trim().toLowerCase();\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, relative, resolve } from \"node:path\";\nimport {\n SkillsLoader,\n type SkillInfo as CoreSkillInfo,\n} from \"@nextclaw/core\";\nimport {\n parseSkillFrontmatter,\n stripSkillFrontmatter,\n type LocalizedTextMap,\n} from \"@kernel/utils/skill-frontmatter.utils.js\";\n\nexport type { SkillInfo, SkillScope } from \"@nextclaw/core\";\n\ntype WorkspaceParams = { workspace: string };\ntype InstalledSkillScopeFilter = CoreSkillInfo[\"scope\"] | \"all\";\n\nexport type InstalledSkillSummary = {\n ref: string;\n name: string;\n path: string;\n relativePath: string | null;\n scope: CoreSkillInfo[\"scope\"];\n source: CoreSkillInfo[\"source\"];\n summary: string | null;\n summaryI18n: LocalizedTextMap | null;\n description: string | null;\n descriptionI18n: LocalizedTextMap | null;\n author: string | null;\n tags: string[];\n always: boolean;\n};\n\nexport type InstalledSkillDetail = InstalledSkillSummary & {\n metadata: Record<string, string> | null;\n raw: string;\n bodyRaw: string;\n};\n\nexport type InstalledSkillsList = {\n workspace: string;\n total: number;\n skills: InstalledSkillSummary[];\n};\n\nexport class SkillManager {\n private readonly loader: SkillsLoader;\n private readonly workspace: string;\n\n constructor(params: WorkspaceParams) {\n this.workspace = resolve(params.workspace);\n this.loader = new SkillsLoader(this.workspace);\n }\n\n listSkills = (params: { filterUnavailable?: boolean } = {}): CoreSkillInfo[] => {\n return this.loader.listSkills(params.filterUnavailable);\n };\n\n getSkillInfo = (selector: string): CoreSkillInfo | null => {\n return this.loader.getSkillInfo(selector);\n };\n\n getSkillMetadata = (selector: string | CoreSkillInfo): Record<string, string> | null => {\n return this.loader.getSkillMetadata(selector);\n };\n\n loadSkillContent = (selector: string): string | null => {\n return this.loader.loadSkill(selector);\n };\n\n listInstalledSkills = (params: {\n query?: string;\n scope?: string;\n } = {}): InstalledSkillsList => {\n const scope = this.normalizeInstalledScope(params.scope);\n const normalizedQuery = this.normalizeOptionalString(params.query)?.toLowerCase() ?? null;\n\n const skills = this\n .listSkills({ filterUnavailable: false })\n .map((skill) => this.buildInstalledSkillSummary(skill))\n .filter((skill) => scope === \"all\" || skill.scope === scope)\n .filter((skill) => this.matchesInstalledSkillQuery(skill, normalizedQuery));\n\n return {\n workspace: this.workspace,\n total: skills.length,\n skills,\n };\n };\n\n getInstalledSkillDetail = (selector: string): InstalledSkillDetail | null => {\n const skill = this.getSkillInfo(selector);\n if (!skill) {\n return null;\n }\n\n const summary = this.buildInstalledSkillSummary(skill);\n const raw = readFileSync(skill.path, \"utf8\");\n return {\n ...summary,\n metadata: this.getSkillMetadata(skill),\n raw,\n bodyRaw: stripSkillFrontmatter(raw),\n };\n };\n\n findBuiltinSkill = (name: string): CoreSkillInfo | null => {\n return this\n .listSkills({ filterUnavailable: false })\n .find((skill) => skill.name === name && skill.source === \"builtin\") ?? null;\n };\n\n resolveBuiltinSkillDir = (name: string): string | null => {\n const skill = this.findBuiltinSkill(name);\n return skill ? dirname(skill.path) : null;\n };\n\n private buildInstalledSkillSummary = (skill: CoreSkillInfo): InstalledSkillSummary => {\n const raw = readFileSync(skill.path, \"utf8\");\n const metadata = this.getSkillMetadata(skill);\n const frontmatter = parseSkillFrontmatter(raw);\n\n return {\n ref: skill.ref,\n name: skill.name,\n path: skill.path,\n relativePath: this.buildRelativePath(skill.path),\n scope: skill.scope,\n source: skill.source,\n summary: frontmatter.summary ?? null,\n summaryI18n: frontmatter.summaryI18n ?? null,\n description: frontmatter.description ?? metadata?.description ?? null,\n descriptionI18n: frontmatter.descriptionI18n ?? null,\n author: frontmatter.author ?? null,\n tags: frontmatter.tags ?? [],\n always: this.readAlwaysFlag(metadata),\n };\n };\n\n private matchesInstalledSkillQuery = (\n skill: InstalledSkillSummary,\n query: string | null,\n ): boolean => {\n if (!query) {\n return true;\n }\n\n const haystacks = [\n skill.ref,\n skill.name,\n skill.path,\n skill.relativePath ?? \"\",\n skill.scope,\n skill.source,\n skill.summary ?? \"\",\n skill.description ?? \"\",\n skill.author ?? \"\",\n ...skill.tags,\n ...Object.values(skill.summaryI18n ?? {}),\n ...Object.values(skill.descriptionI18n ?? {}),\n ];\n\n return haystacks.some((value) => value.toLowerCase().includes(query));\n };\n\n private readAlwaysFlag = (metadata: Record<string, string> | null): boolean => {\n if (metadata?.always === \"true\") {\n return true;\n }\n\n const raw = metadata?.metadata;\n if (!raw) {\n return false;\n }\n\n try {\n const parsed = JSON.parse(raw) as {\n nextclaw?: {\n always?: unknown;\n };\n };\n return parsed.nextclaw?.always === true;\n } catch {\n return false;\n }\n };\n\n private buildRelativePath = (absolutePath: string): string | null => {\n const relativePath = relative(this.workspace, absolutePath).replace(/\\\\/g, \"/\");\n return relativePath.startsWith(\"..\") ? null : relativePath;\n };\n\n private normalizeInstalledScope = (value: string | undefined): InstalledSkillScopeFilter => {\n const normalized = this.normalizeOptionalString(value);\n if (!normalized || normalized === \"all\") {\n return \"all\";\n }\n if (normalized === \"builtin\" || normalized === \"project\" || normalized === \"workspace\") {\n return normalized;\n }\n throw new Error(`Invalid skill scope: ${value}. Expected all, builtin, project, or workspace.`);\n };\n\n private normalizeOptionalString = (value: string | undefined): string | null => {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n };\n}\n","import { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport type { UpdateToolCallResult } from \"@kernel/managers/tool.manager.js\";\nimport {\n NcpEventType,\n type NcpAgentRuntime,\n type NcpAgentRunStreamOptions,\n type NcpEndpointEvent,\n type NcpStreamRequestPayload,\n} from \"@nextclaw/ncp\";\nimport {\n DefaultNcpAgentConversationStateManager,\n} from \"@nextclaw/ncp-toolkit\";\nimport {\n AsyncEventQueue,\n buildSessionRecord,\n disposeRuntime,\n type LiveSession,\n type LiveSessionExecution,\n type PublishSessionEventOptions,\n readAgentId,\n readString,\n} from \"@kernel/utils/session-run.utils.js\";\nimport type { AgentRuntimeManager } from \"@kernel/managers/agent-runtime.manager.js\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\n\ntype Cleanup = () => Promise<void> | void;\nconst RUNTIME_METADATA_KEYS = [\"runtime\", \"session_type\", \"runtime_type\"] as const;\n\nfunction isDurableSessionEvent(event: NcpEndpointEvent): boolean {\n return event.type !== NcpEventType.ContextWindowUpdated;\n}\n\nfunction readEventSessionId(event: NcpEndpointEvent): string | null {\n const payload = \"payload\" in event ? event.payload : null;\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n return \"sessionId\" in payload && typeof payload.sessionId === \"string\"\n ? payload.sessionId\n : null;\n}\n\nfunction pickRuntimeMetadataPatch(\n current: Record<string, unknown>,\n next: Record<string, unknown>,\n): Record<string, unknown> {\n const patch: Record<string, unknown> = {};\n for (const key of RUNTIME_METADATA_KEYS) {\n const value = next[key];\n if (!Object.is(current[key], value)) {\n patch[key] = structuredClone(value);\n }\n }\n return patch;\n}\n\nexport class SessionRunManager {\n private readonly agentRuntimeManager: AgentRuntimeManager;\n private readonly ncpSessionManager: NcpSessionManager;\n private readonly eventBus: EventBus;\n private readonly liveSessions = new Map<string, LiveSession>();\n private readonly cleanups: Cleanup[] = [];\n private disposed = false;\n\n constructor(options: {\n agentRuntimeManager: AgentRuntimeManager;\n eventBus: EventBus;\n ncpSessionManager: NcpSessionManager;\n }) {\n const {\n agentRuntimeManager,\n eventBus,\n ncpSessionManager,\n } = options;\n this.agentRuntimeManager = agentRuntimeManager;\n this.ncpSessionManager = ncpSessionManager;\n this.eventBus = eventBus;\n }\n\n dispose = async (): Promise<void> => {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n while (this.cleanups.length > 0) {\n await this.cleanups.pop()?.();\n }\n };\n\n isRunning = (sessionId: string): boolean => Boolean(this.liveSessions.get(sessionId)?.activeExecution);\n\n getOrCreateLiveSession = async (\n sessionId: string,\n initialMetadata: Record<string, unknown> = {},\n ): Promise<LiveSession> => this.ensureLiveSession(sessionId, initialMetadata);\n\n getActiveSessionRun = (sessionId: string): LiveSessionExecution | null =>\n this.liveSessions.get(sessionId)?.activeExecution ?? null;\n\n getLiveSessionRecord = (sessionId: string) => {\n const session = this.liveSessions.get(sessionId.trim());\n return session ? buildSessionRecord(session, new Date().toISOString()) : null;\n };\n\n setActiveSessionRun = (\n sessionId: string,\n activeRun: LiveSessionExecution,\n ): void => {\n const session = this.requireLiveSession(sessionId);\n const current = session.activeExecution;\n if (current && current !== activeRun && !current.closed) {\n throw new Error(`Session ${session.sessionId} already has an active execution.`);\n }\n session.activeExecution = activeRun;\n if (current !== activeRun) {\n this.publishSessionRunStatus({ sessionKey: session.sessionId, status: \"running\" });\n }\n };\n\n deleteActiveSessionRun = (\n sessionId: string,\n runId: string,\n ): void => {\n const session = this.requireLiveSession(sessionId);\n const current = session.activeExecution;\n if (!current || current.runId !== runId) {\n return;\n }\n current.closed = true;\n session.activeExecution = null;\n this.publishSessionRunStatus({ sessionKey: session.sessionId, status: \"idle\" });\n };\n\n streamSessionEvents = (\n payload: NcpStreamRequestPayload,\n options?: NcpAgentRunStreamOptions,\n ): AsyncIterable<NcpEndpointEvent> => {\n this.assertNotDisposed();\n const signal = options?.signal ?? new AbortController().signal;\n const queue = new AsyncEventQueue<NcpEndpointEvent>();\n const stop = () => queue.close();\n const unsubscribe = this.eventBus.on(eventKeys.ncpEvent, (event) => {\n const eventSessionId = readEventSessionId(event);\n if (eventSessionId === payload.sessionId) {\n queue.push(event);\n }\n });\n signal.addEventListener(\"abort\", stop, { once: true });\n if (signal.aborted) {\n stop();\n }\n return (async function* (): AsyncIterable<NcpEndpointEvent> {\n try {\n for await (const event of queue.iterate()) {\n if (signal.aborted) {\n break;\n }\n yield event;\n }\n } finally {\n unsubscribe();\n signal.removeEventListener(\"abort\", stop);\n queue.close();\n }\n })();\n };\n\n updateToolCallResult: UpdateToolCallResult = async ({\n result,\n sessionId,\n toolCallId,\n }): Promise<void> => {\n this.assertNotDisposed();\n const normalizedSessionId = sessionId.trim();\n const normalizedToolCallId = toolCallId.trim();\n if (!normalizedSessionId || !normalizedToolCallId) {\n return;\n }\n const session = await this.ensureLiveSession(normalizedSessionId);\n await this.publishSessionEvent(session, {\n type: NcpEventType.MessageToolCallResult,\n payload: {\n sessionId: normalizedSessionId,\n toolCallId: normalizedToolCallId,\n content: result,\n },\n });\n };\n\n updateSessionMetadata = async (\n sessionId: string,\n metadata: Record<string, unknown>,\n ): Promise<boolean> => {\n this.assertNotDisposed();\n const normalizedSessionId = sessionId.trim();\n if (!normalizedSessionId) return false;\n const liveSession = this.liveSessions.has(normalizedSessionId);\n const storedSession = liveSession ? null : await this.ncpSessionManager.getSessionRecord(normalizedSessionId);\n if (!liveSession && !storedSession) return false;\n return await this.ncpSessionManager.updateSessionMetadata(normalizedSessionId, metadata);\n };\n\n appendSessionEvent = async (\n sessionId: string,\n event: NcpEndpointEvent,\n options: PublishSessionEventOptions = {},\n ): Promise<void> => {\n await this.publishSessionEvent(this.requireLiveSession(sessionId), event, options);\n };\n\n private readonly ensureLiveSession = async (\n sessionId: string,\n initialMetadata: Record<string, unknown> = {},\n ): Promise<LiveSession> => {\n const existing = this.liveSessions.get(sessionId);\n if (existing) {\n return existing;\n }\n\n const storedSession = await this.ncpSessionManager.getSessionRecord(sessionId);\n const stateManager = new DefaultNcpAgentConversationStateManager();\n stateManager.hydrate({\n sessionId,\n messages: storedSession?.messages.map((message) => structuredClone(message)) ?? [],\n });\n const metadata = {\n ...(storedSession?.metadata ? structuredClone(storedSession.metadata) : {}),\n ...structuredClone(initialMetadata),\n };\n const runtimeMetadata = this.agentRuntimeManager.resolveSessionMetadata(metadata);\n const runtimeMetadataPatch = pickRuntimeMetadataPatch(metadata, runtimeMetadata);\n if (Object.keys(runtimeMetadataPatch).length > 0) {\n await this.ncpSessionManager.updateSessionMetadata(sessionId, runtimeMetadataPatch);\n }\n const session: LiveSession = {\n sessionId,\n ...(readString(storedSession?.agentId) ?? readAgentId(metadata)\n ? { agentId: readString(storedSession?.agentId) ?? readAgentId(metadata) }\n : {}),\n stateManager,\n runtime: null as unknown as NcpAgentRuntime,\n activeExecution: null,\n };\n session.runtime = this.agentRuntimeManager.createRuntime({\n sessionId,\n ...(session.agentId ? { agentId: session.agentId } : {}),\n stateManager,\n sessionMetadata: runtimeMetadata,\n });\n this.liveSessions.set(sessionId, session);\n this.cleanups.push(async () => {\n session.activeExecution?.controller.abort();\n await disposeRuntime(session.runtime);\n this.liveSessions.delete(sessionId);\n });\n return session;\n };\n\n private readonly requireLiveSession = (sessionId: string): LiveSession => {\n const session = this.liveSessions.get(sessionId);\n if (!session) {\n throw new Error(`Session ${sessionId} is not live.`);\n }\n return session;\n };\n\n private readonly publishSessionEvent = async (\n session: LiveSession,\n event: NcpEndpointEvent,\n options: PublishSessionEventOptions = {},\n ): Promise<void> => {\n if (options.dispatchToStateManager !== false) {\n await session.stateManager.dispatch(event);\n }\n if (options.persistSession !== false) {\n await this.persistLiveSessionEvent(session, event);\n }\n this.eventBus.emit(eventKeys.ncpEvent, event, {\n emittedAt: new Date().toISOString(),\n source: \"session-run\",\n });\n };\n\n private readonly persistLiveSessionEvent = async (session: LiveSession, event: NcpEndpointEvent): Promise<void> => {\n if (!isDurableSessionEvent(event)) {\n return;\n }\n await this.ncpSessionManager.appendSessionEvent({\n sessionId: session.sessionId,\n event,\n });\n };\n\n private readonly assertNotDisposed = (): void => {\n if (this.disposed) {\n throw new Error(\"Session run manager has already been disposed.\");\n }\n };\n\n private publishSessionRunStatus = (payload: { sessionKey: string; status: \"running\" | \"idle\" }): void => {\n this.eventBus.emit(eventKeys.sessionRunStatus, payload, {\n emittedAt: new Date().toISOString(),\n source: \"session-run\",\n });\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AgentSessionEventRecord } from \"@nextclaw/ncp-toolkit\";\nimport {\n createNcpAgentSessionJournalMetadataEntry,\n isRecord,\n normalizeNcpAgentId,\n safeNcpSessionFilename,\n toIsoString,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\n\nexport type NcpAgentSessionActivitySnapshot = {\n metadata: Record<string, unknown>;\n agentId?: string;\n createdAt: string;\n updatedAt: string;\n};\n\nexport class NcpAgentSessionMetadataStore {\n constructor(private readonly journalDir: string) {}\n\n write = async (record: AgentSessionEventRecord): Promise<void> => {\n await mkdir(this.journalDir, { recursive: true });\n const targetPath = this.metadataPath(record.sessionId);\n const tempPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await writeFile(tempPath, `${JSON.stringify(createNcpAgentSessionJournalMetadataEntry(record))}\\n`, \"utf-8\");\n await rename(tempPath, targetPath);\n } catch (error) {\n await rm(tempPath, { force: true });\n throw error;\n }\n };\n\n read = async (\n sessionId: string,\n activitySnapshot: NcpAgentSessionActivitySnapshot,\n ): Promise<NcpAgentSessionActivitySnapshot> => {\n try {\n const parsed = JSON.parse(await readFile(this.metadataPath(sessionId), \"utf-8\")) as unknown;\n if (!isRecord(parsed) || parsed._type !== \"metadata\" || !isRecord(parsed.metadata)) {\n throw new Error(`invalid ncp agent session metadata sidecar: ${sessionId}`);\n }\n const createdAt = toIsoString(parsed.created_at, activitySnapshot.createdAt);\n const agentId = normalizeNcpAgentId(typeof parsed.agent_id === \"string\" ? parsed.agent_id : undefined);\n return {\n metadata: structuredClone(parsed.metadata),\n ...(agentId ? { agentId } : {}),\n createdAt,\n updatedAt: activitySnapshot.updatedAt,\n };\n } catch (error) {\n const code = error && typeof error === \"object\" && \"code\" in error ? error.code : undefined;\n if (code === \"ENOENT\") {\n return activitySnapshot;\n }\n throw error;\n }\n };\n\n delete = async (sessionId: string): Promise<void> => {\n await rm(this.metadataPath(sessionId), { force: true });\n };\n\n private metadataPath = (sessionId: string): string => {\n return join(this.journalDir, `${safeNcpSessionFilename(sessionId.replace(/:/g, \"_\"))}.metadata.json`);\n };\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { NcpSessionSummary } from \"@nextclaw/ncp\";\nimport {\n createNcpAgentSessionSummary,\n type LoadedNcpAgentJournalSession,\n NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n NCP_AGENT_SESSION_JOURNAL_INDEX_FILE,\n type NcpAgentSessionJournalIndex,\n type NcpAgentSessionJournalReplayEvent,\n readNcpSessionSummaryActivityAt,\n upsertNcpAgentSessionSummaryEvent,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\n\nfunction stripSummaryMetadata(summary: NcpSessionSummary): NcpSessionSummary {\n const { metadata: _metadata, ...nextSummary } = summary;\n void _metadata;\n return nextSummary;\n}\n\nexport class NcpAgentSessionSummaryIndexStore {\n private summaryIndex: Map<string, NcpSessionSummary> | null = null;\n\n constructor(\n private readonly journalDir: string,\n private readonly loadSession: (sessionId: string) => Promise<LoadedNcpAgentJournalSession | null>,\n ) {}\n\n has = async (sessionId: string): Promise<boolean> => (await this.load()).has(sessionId);\n\n list = async (): Promise<NcpSessionSummary[]> => {\n const index = await this.load();\n return [...index.values()]\n .map((summary) => structuredClone(summary))\n .sort((left, right) => readNcpSessionSummaryActivityAt(right).localeCompare(readNcpSessionSummaryActivityAt(left)));\n };\n\n upsert = async (summary: NcpSessionSummary): Promise<void> => {\n const index = await this.load();\n index.set(summary.sessionId, stripSummaryMetadata(structuredClone(summary)));\n await this.persist();\n };\n\n upsertForEvent = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n updatedAt: string;\n }): Promise<void> => {\n const { event, sessionId, updatedAt } = params;\n const index = await this.load();\n const summary = upsertNcpAgentSessionSummaryEvent({\n current: index.get(sessionId),\n sessionId,\n event,\n updatedAt,\n });\n index.set(summary.sessionId, stripSummaryMetadata(summary));\n await this.persist();\n };\n\n remove = async (sessionId: string): Promise<void> => {\n const index = await this.load();\n index.delete(sessionId);\n await this.persist();\n };\n\n private load = async (): Promise<Map<string, NcpSessionSummary>> => {\n if (this.summaryIndex) {\n return this.summaryIndex;\n }\n try {\n const parsed = JSON.parse(await readFile(this.indexPath(), \"utf-8\")) as NcpAgentSessionJournalIndex;\n if (parsed.version === NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION && Array.isArray(parsed.records)) {\n this.summaryIndex = new Map(parsed.records.map((record) => [\n record.sessionId,\n stripSummaryMetadata(structuredClone(record)),\n ]));\n return this.summaryIndex;\n }\n } catch {\n // Rebuild below.\n }\n this.summaryIndex = await this.rebuild();\n await this.persist();\n return this.summaryIndex;\n };\n\n private rebuild = async (): Promise<Map<string, NcpSessionSummary>> => {\n const records = new Map<string, NcpSessionSummary>();\n let entries: string[] = [];\n try {\n entries = await readdir(this.journalDir);\n } catch {\n return records;\n }\n for (const entry of entries) {\n if (!entry.endsWith(\".jsonl\")) {\n continue;\n }\n const sessionId = entry.replace(/\\.jsonl$/, \"\").replace(/_/g, \":\");\n const loaded = await this.loadSession(sessionId);\n if (loaded) {\n records.set(sessionId, stripSummaryMetadata(createNcpAgentSessionSummary(loaded.record)));\n }\n }\n return records;\n };\n\n private persist = async (): Promise<void> => {\n const records = [...(this.summaryIndex?.values() ?? [])]\n .map((summary) => stripSummaryMetadata(structuredClone(summary)))\n .sort((left, right) => readNcpSessionSummaryActivityAt(right).localeCompare(readNcpSessionSummaryActivityAt(left)));\n await mkdir(this.journalDir, { recursive: true });\n await writeFile(\n this.indexPath(),\n `${JSON.stringify({ version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION, records })}\\n`,\n \"utf-8\",\n );\n };\n\n private indexPath = (): string => resolve(this.journalDir, NCP_AGENT_SESSION_JOURNAL_INDEX_FILE);\n}\n","import { appendFile, mkdir, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AgentSessionRecord } from \"@nextclaw/ncp-toolkit\";\nimport type { NcpMessage, NcpSessionSummary } from \"@nextclaw/ncp\";\nimport {\n createNcpAgentSessionSummary,\n isRecord,\n type LoadedNcpAgentJournalSession,\n NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE,\n type NcpAgentSessionJournalEventEntry,\n type NcpAgentSessionJournalReplayEvent,\n normalizeNcpAgentId,\n normalizeNcpSessionId,\n replayNcpAgentSessionEvents,\n safeNcpSessionFilename,\n toIsoString,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\nimport { NcpAgentSessionMetadataStore } from \"./ncp-agent-session-metadata.store.js\";\nimport { NcpAgentSessionSummaryIndexStore } from \"./ncp-agent-session-summary-index.store.js\";\n\ntype ParsedNcpAgentSessionJournal = {\n metadata: Record<string, unknown>;\n agentId?: string;\n createdAt: string;\n updatedAt: string;\n nextSeq: number;\n events: NcpAgentSessionJournalReplayEvent[];\n};\n\nfunction serializeJournalEntry(entry: NcpAgentSessionJournalEventEntry): string {\n const serialized = JSON.stringify(entry);\n if (!serialized) {\n throw new Error(\"ncp agent session journal entry serialization produced empty output\");\n }\n const parsed = JSON.parse(serialized) as unknown;\n if (!isRecord(parsed)) {\n throw new Error(\"ncp agent session journal entry serialization produced a non-object entry\");\n }\n return serialized;\n}\n\nexport class NcpAgentSessionJournalStore {\n private readonly sessions = new Map<string, LoadedNcpAgentJournalSession>();\n private readonly nextSeqBySession = new Map<string, number>();\n private readonly writeChains = new Map<string, Promise<void>>();\n private readonly metadataStore: NcpAgentSessionMetadataStore;\n private readonly summaryIndexStore: NcpAgentSessionSummaryIndexStore;\n\n constructor(private readonly journalDir: string) {\n this.metadataStore = new NcpAgentSessionMetadataStore(journalDir);\n this.summaryIndexStore = new NcpAgentSessionSummaryIndexStore(\n journalDir,\n async (sessionId) => this.loadSession(sessionId),\n );\n }\n\n appendSessionEvent = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n }): Promise<void> => {\n const sessionId = normalizeNcpSessionId(params.sessionId);\n if (!sessionId) {\n return;\n }\n const previous = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.appendSessionEventNow({\n ...params,\n sessionId,\n }));\n this.writeChains.set(sessionId, next.catch(() => undefined));\n await next;\n };\n\n getSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const normalizedSessionId = normalizeNcpSessionId(sessionId);\n if (!normalizedSessionId) {\n return null;\n }\n const cached = this.sessions.get(normalizedSessionId);\n if (cached) {\n return structuredClone(cached.record);\n }\n const loaded = await this.loadSession(normalizedSessionId);\n if (!loaded) {\n return null;\n }\n this.sessions.set(normalizedSessionId, loaded);\n return structuredClone(loaded.record);\n };\n\n listSessionSummaries = async (): Promise<NcpSessionSummary[]> => {\n const summaries = await this.summaryIndexStore.list();\n return await Promise.all(summaries.map(this.withMetadata));\n };\n\n listSessionMessages = async (sessionId: string): Promise<NcpMessage[]> => {\n const session = await this.getSession(sessionId);\n return session ? session.messages.map((message) => structuredClone(message)) : [];\n };\n\n setSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const sessionId = normalizeNcpSessionId(params.sessionId);\n if (!sessionId) {\n return false;\n }\n const previous = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.setSessionMetadataNow({\n ...params,\n sessionId,\n }));\n this.writeChains.set(sessionId, next.then(() => undefined, () => undefined));\n return await next;\n };\n\n updateSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const sessionId = normalizeNcpSessionId(params.sessionId);\n if (!sessionId) {\n return false;\n }\n const previous = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.updateSessionMetadataNow({\n ...params,\n sessionId,\n }));\n this.writeChains.set(sessionId, next.then(() => undefined, () => undefined));\n return await next;\n };\n\n private setSessionMetadataNow = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const { metadata, sessionId } = params;\n const loaded = this.sessions.get(sessionId) ?? await this.loadSession(sessionId);\n if (!loaded) {\n return false;\n }\n const nextRecord: AgentSessionRecord = {\n ...loaded.record,\n metadata: structuredClone(metadata),\n };\n await this.metadataStore.write(nextRecord);\n this.sessions.set(sessionId, {\n record: nextRecord,\n nextSeq: loaded.nextSeq,\n });\n this.nextSeqBySession.set(sessionId, loaded.nextSeq);\n await this.summaryIndexStore.upsert(createNcpAgentSessionSummary(nextRecord));\n return true;\n };\n\n private updateSessionMetadataNow = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const loaded = this.sessions.get(params.sessionId) ?? await this.loadSession(params.sessionId);\n if (!loaded) {\n return false;\n }\n return await this.setSessionMetadataNow({\n ...params,\n metadata: {\n ...(loaded.record.metadata ? structuredClone(loaded.record.metadata) : {}),\n ...structuredClone(params.metadata),\n },\n });\n };\n\n importSessionSnapshot = async (record: AgentSessionRecord): Promise<void> => {\n const sessionId = normalizeNcpSessionId(record.sessionId);\n if (!sessionId) {\n return;\n }\n await this.ensureJournalDir();\n const nextRecord = structuredClone({ ...record, sessionId });\n await this.metadataStore.write(nextRecord);\n const entries = nextRecord.messages.map((message, index): NcpAgentSessionJournalEventEntry => ({\n _type: \"event\",\n version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n seq: index + 1,\n timestamp: message.timestamp ?? nextRecord.updatedAt,\n event: {\n type: NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE,\n payload: {\n sessionId,\n message: structuredClone(message),\n },\n },\n }));\n await writeFile(\n this.sessionPath(sessionId),\n entries.length > 0 ? `${entries.map(serializeJournalEntry).join(\"\\n\")}\\n` : \"\",\n \"utf-8\",\n );\n const nextSeq = nextRecord.messages.length + 1;\n this.sessions.set(sessionId, {\n record: nextRecord,\n nextSeq,\n });\n this.nextSeqBySession.set(sessionId, nextSeq);\n await this.summaryIndexStore.upsert(createNcpAgentSessionSummary(nextRecord));\n };\n\n deleteSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const normalizedSessionId = normalizeNcpSessionId(sessionId);\n if (!normalizedSessionId) {\n return null;\n }\n const existing = await this.getSession(normalizedSessionId);\n this.sessions.delete(normalizedSessionId);\n this.nextSeqBySession.delete(normalizedSessionId);\n try {\n await unlink(this.sessionPath(normalizedSessionId));\n } catch {\n // The journal may already be absent when deleting a legacy-only session.\n }\n await this.metadataStore.delete(normalizedSessionId);\n await this.summaryIndexStore.remove(normalizedSessionId);\n return existing;\n };\n\n hasSession = async (sessionId: string): Promise<boolean> => {\n const normalizedSessionId = normalizeNcpSessionId(sessionId);\n if (!normalizedSessionId) {\n return false;\n }\n return this.summaryIndexStore.has(normalizedSessionId);\n };\n\n private appendSessionEventNow = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n }): Promise<void> => {\n const { event, sessionId } = params;\n const updatedAt = new Date().toISOString();\n await this.ensureJournalDir();\n const existing = this.sessions.get(sessionId)\n ?? (this.nextSeqBySession.has(sessionId) ? null : await this.loadSession(sessionId));\n const nextSeq = this.nextSeqBySession.get(sessionId) ?? existing?.nextSeq ?? 1;\n const path = this.sessionPath(sessionId);\n const entry: NcpAgentSessionJournalEventEntry = {\n _type: \"event\",\n version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n seq: nextSeq,\n timestamp: updatedAt,\n event: structuredClone(event),\n };\n await this.appendJournalEntry(path, entry);\n this.nextSeqBySession.set(sessionId, nextSeq + 1);\n this.sessions.delete(sessionId);\n await this.summaryIndexStore.upsertForEvent({\n sessionId,\n event,\n updatedAt,\n });\n };\n\n private withMetadata = async (summary: NcpSessionSummary): Promise<NcpSessionSummary> => {\n const snapshot = await this.metadataStore.read(summary.sessionId, {\n ...(summary.agentId ? { agentId: summary.agentId } : {}),\n createdAt: summary.createdAt ?? summary.updatedAt,\n updatedAt: summary.updatedAt,\n metadata: {},\n });\n return {\n ...summary,\n ...(!summary.agentId && snapshot.agentId ? { agentId: snapshot.agentId } : {}),\n ...(Object.keys(snapshot.metadata).length > 0 ? { metadata: snapshot.metadata } : {}),\n };\n };\n\n private loadSession = async (sessionId: string): Promise<LoadedNcpAgentJournalSession | null> => {\n let raw: string;\n try {\n raw = await readFile(this.sessionPath(sessionId), \"utf-8\");\n } catch {\n return null;\n }\n\n const parsedJournal = this.parseSessionJournal(raw);\n const sessionMetadata = await this.metadataStore.read(sessionId, parsedJournal);\n const { agentId, createdAt, updatedAt, metadata } = sessionMetadata;\n const { events, nextSeq } = parsedJournal;\n const messages = await replayNcpAgentSessionEvents(events);\n const record: AgentSessionRecord = {\n sessionId,\n ...(agentId ? { agentId } : {}),\n messages,\n createdAt,\n updatedAt,\n metadata,\n };\n this.nextSeqBySession.set(sessionId, nextSeq);\n return {\n record,\n nextSeq,\n };\n };\n\n private parseSessionJournal = (raw: string): ParsedNcpAgentSessionJournal => {\n let metadata: Record<string, unknown> = {};\n let agentId: string | undefined;\n let createdAt = new Date().toISOString();\n let updatedAt = createdAt;\n let nextSeq = 1;\n const events: NcpAgentSessionJournalReplayEvent[] = [];\n for (const [index, line] of raw.split(\"\\n\").entries()) {\n if (!line.trim()) {\n continue;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(line) as unknown;\n } catch (error) {\n console.warn(\n `[ncp-agent-session-journal] skipped corrupted journal line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`\n );\n continue;\n }\n if (!isRecord(parsed)) {\n continue;\n }\n if (parsed._type === \"metadata\") {\n metadata = isRecord(parsed.metadata) ? structuredClone(parsed.metadata) : {};\n agentId = normalizeNcpAgentId(typeof parsed.agent_id === \"string\" ? parsed.agent_id : undefined);\n createdAt = toIsoString(parsed.created_at, createdAt);\n updatedAt = toIsoString(parsed.updated_at, updatedAt);\n continue;\n }\n if (parsed._type === \"event\" && isRecord(parsed.event)) {\n const seq = Number(parsed.seq);\n nextSeq = Math.max(nextSeq, Number.isFinite(seq) ? Math.trunc(seq) + 1 : nextSeq);\n updatedAt = toIsoString(parsed.timestamp, updatedAt);\n const event = structuredClone(parsed.event) as NcpAgentSessionJournalReplayEvent;\n events.push(event);\n }\n }\n return { metadata, ...(agentId ? { agentId } : {}), createdAt, updatedAt, nextSeq, events };\n };\n\n private appendJournalEntry = async (\n path: string,\n entry: NcpAgentSessionJournalEventEntry,\n ): Promise<void> => {\n await appendFile(path, `${serializeJournalEntry(entry)}\\n`, \"utf-8\");\n };\n\n private ensureJournalDir = async (): Promise<void> => {\n await mkdir(this.journalDir, { recursive: true });\n };\n\n private sessionPath = (sessionId: string): string => {\n return join(this.journalDir, `${safeNcpSessionFilename(sessionId.replace(/:/g, \"_\"))}.jsonl`);\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n buildSessionRequestToolResult,\n readOptionalString,\n readParentSessionId,\n summarizeSessionRequestTask,\n createCompletedSessionRequest,\n createFailedSessionRequest,\n createRunningSessionRequest,\n type DispatchRequestParams,\n type RequestSessionParams,\n type SessionRequestDispatcher,\n type SessionRequestPayload,\n type SessionRequestRecord,\n type SessionRequestResultContext,\n type SessionRequestToolResult,\n type SpawnSessionAndRequestParams,\n} from \"@nextclaw/core\";\nimport type { AgentSessionRecord } from \"@nextclaw/ncp-toolkit\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport {\n NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE,\n NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE,\n NCP_SESSION_REQUEST_FAILED_EVENT_TYPE,\n type NcpSessionRequestJournalEvent,\n type NcpSessionRequestJournalEventType,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\n\nexport type SessionRequestManagerOptions = {\n dispatcher: SessionRequestDispatcher;\n ncpSessionManager: NcpSessionManager;\n};\n\nfunction readRecordLabel(record: AgentSessionRecord): string | undefined {\n return readOptionalString(record.metadata?.label) ?? undefined;\n}\n\nexport class SessionRequestManager {\n constructor(private readonly options: SessionRequestManagerOptions) {}\n\n spawnSessionAndRequest = async (\n params: SpawnSessionAndRequestParams,\n ): Promise<SessionRequestToolResult> => {\n const {\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n sourceSessionMetadata,\n metadataOverrides,\n task,\n title,\n model,\n runtime,\n handoffDepth,\n sessionType,\n thinkingLevel,\n projectRoot,\n agentId,\n parentSessionId,\n notify,\n } = params;\n const requestId = randomUUID();\n const createdSession = await this.options.ncpSessionManager.createSession({\n sourceSessionId,\n ...(parentSessionId ? { parentSessionId } : {}),\n task,\n title,\n sourceSessionMetadata,\n ...(metadataOverrides ? { metadataOverrides } : {}),\n agentId,\n model,\n runtime,\n thinkingLevel,\n sessionType,\n projectRoot,\n requestId,\n });\n\n return this.dispatchRequest({\n requestId,\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId: createdSession.sessionId,\n task,\n title: createdSession.title ?? summarizeSessionRequestTask(task),\n handoffDepth: handoffDepth ?? 0,\n notify,\n agentId: createdSession.agentId,\n isChildSession: Boolean(parentSessionId),\n ...(parentSessionId ? { parentSessionId } : {}),\n spawnedByRequestId: requestId,\n });\n };\n\n requestSession = async (\n params: RequestSessionParams,\n ): Promise<SessionRequestToolResult> => {\n const {\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId,\n task,\n title,\n notify,\n handoffDepth,\n } = params;\n const normalizedTargetSessionId = targetSessionId.trim();\n\n if (normalizedTargetSessionId === sourceSessionId.trim()) {\n throw new Error(\"sessions_request cannot target the current session.\");\n }\n const targetSession = await this.options.ncpSessionManager.getSessionRecord(normalizedTargetSessionId);\n if (!targetSession) {\n throw new Error(`Target session not found: ${targetSessionId}`);\n }\n const parentSessionId = readParentSessionId(targetSession.metadata);\n\n return this.dispatchRequest({\n requestId: randomUUID(),\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId: normalizedTargetSessionId,\n task,\n title:\n readOptionalString(title) ??\n readRecordLabel(targetSession) ??\n summarizeSessionRequestTask(task),\n handoffDepth: handoffDepth ?? 0,\n notify,\n agentId: targetSession.agentId,\n isChildSession: Boolean(parentSessionId),\n parentSessionId: parentSessionId ?? undefined,\n spawnedByRequestId: undefined,\n });\n };\n\n private dispatchRequest = async (\n params: DispatchRequestParams,\n ): Promise<SessionRequestToolResult> => {\n const {\n requestId,\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId,\n task,\n title,\n handoffDepth,\n notify,\n agentId,\n isChildSession,\n parentSessionId,\n spawnedByRequestId,\n } = params;\n const request = createRunningSessionRequest({\n requestId,\n sourceSessionId,\n targetSessionId,\n sourceToolCallId,\n handoffDepth,\n notify,\n title,\n task,\n isChildSession,\n parentSessionId,\n });\n const resultContext: SessionRequestResultContext = {\n task,\n title,\n updateToolCallResult,\n agentId,\n isChildSession,\n parentSessionId,\n spawnedByRequestId,\n };\n const payload = this.toSessionRequestPayload(request, resultContext);\n\n if (notify === \"final_reply\") {\n return await this.runRequest(payload);\n }\n\n void this.runRequestAndUpdateToolCallResult(payload);\n\n return this.buildToolResult({\n ...payload,\n message: `Session request started. You'll receive the final reply when it finishes.`,\n });\n };\n\n private toSessionRequestPayload = (\n request: SessionRequestRecord,\n resultContext: SessionRequestResultContext,\n ): SessionRequestPayload => ({\n request,\n resultContext,\n });\n\n private buildToolResult = (\n payload: SessionRequestPayload & { message?: string },\n ): SessionRequestToolResult => {\n const {\n task,\n title,\n agentId,\n isChildSession,\n parentSessionId,\n spawnedByRequestId,\n } = payload.resultContext;\n return buildSessionRequestToolResult({\n request: payload.request,\n task,\n title,\n isChildSession,\n ...(agentId ? { agentId } : {}),\n ...(parentSessionId ? { parentSessionId } : {}),\n ...(spawnedByRequestId ? { spawnedByRequestId } : {}),\n ...(payload.message ? { message: payload.message } : {}),\n });\n };\n\n private appendRequestEvents = async (\n request: SessionRequestRecord,\n type: NcpSessionRequestJournalEventType,\n ): Promise<void> => {\n await this.appendRequestEvent(request.sourceSessionId, type, request);\n await this.appendRequestEvent(request.targetSessionId, type, request);\n };\n\n private runRequest = async (\n payload: SessionRequestPayload,\n ): Promise<SessionRequestToolResult> => {\n const { request, resultContext } = payload;\n const acceptedWrites: Promise<void>[] = [];\n try {\n const dispatchResult = await this.options.dispatcher.dispatch({\n request,\n task: resultContext.task,\n onAccepted: (messageId) => {\n acceptedWrites.push(this.appendAcceptedRequestEvent(request, messageId));\n },\n });\n await Promise.all(acceptedWrites);\n const completedRequest = createCompletedSessionRequest({\n request,\n finalResponseMessageId: dispatchResult.finalResponseMessageId,\n finalResponseText: dispatchResult.finalResponseText,\n });\n await this.appendRequestEvents(completedRequest, NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE);\n return this.buildToolResult(this.toSessionRequestPayload(completedRequest, resultContext));\n } catch (error) {\n await Promise.all(acceptedWrites);\n const failedRequest = createFailedSessionRequest({\n request,\n error,\n });\n await this.appendRequestEvents(failedRequest, NCP_SESSION_REQUEST_FAILED_EVENT_TYPE);\n return this.buildToolResult(this.toSessionRequestPayload(failedRequest, resultContext));\n }\n };\n\n private runRequestAndUpdateToolCallResult = async (\n payload: SessionRequestPayload,\n ): Promise<void> => {\n try {\n const result = await this.runRequest(payload);\n await payload.resultContext.updateToolCallResult(result);\n } catch (error) {\n console.error(\n `[session-request] Background request ${payload.request.requestId} crashed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n };\n\n private appendAcceptedRequestEvent = async (\n request: SessionRequestRecord,\n messageId: string,\n ): Promise<void> => {\n const acceptedRequest: SessionRequestRecord = {\n ...request,\n targetMessageId: messageId,\n };\n await this.appendRequestEvent(request.sourceSessionId, NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE, acceptedRequest);\n await this.appendRequestEvent(request.targetSessionId, NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE, acceptedRequest);\n };\n\n private appendRequestEvent = async (\n sessionId: string,\n type: NcpSessionRequestJournalEventType,\n request: SessionRequestRecord,\n ): Promise<void> => {\n const event: NcpSessionRequestJournalEvent = {\n type,\n payload: {\n sessionId,\n request: structuredClone(request),\n },\n };\n await this.options.ncpSessionManager.appendSessionEvent({\n sessionId,\n event,\n });\n };\n}\n","import { NcpEventType, type NcpMessage } from \"@nextclaw/ncp\";\nimport {\n eventKeys,\n ingressKeys,\n type EventBus,\n type Ingress,\n type Unsubscribe,\n} from \"@nextclaw/shared\";\nimport type {\n SessionRequestDispatcher,\n SessionRequestRecord,\n} from \"@nextclaw/core\";\n\nexport type AgentRuntimeSessionRequestDispatcherOptions = {\n eventBus: EventBus;\n ingress: Ingress;\n};\n\nfunction extractSessionMessageText(message: NcpMessage): string | undefined {\n const parts = message.parts\n .flatMap((part) => part.type === \"text\" || part.type === \"rich-text\" ? [part.text] : [])\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n return parts.length > 0 ? parts.join(\"\\n\\n\") : undefined;\n}\n\nexport function waitForAgentRuntimeSessionReply(input: {\n eventBus: EventBus;\n onAccepted: (messageId: string) => void;\n requestId: string;\n}): { dispose: Unsubscribe; promise: Promise<NcpMessage> } {\n let acceptedMessageId: string | null = null;\n const completedMessagesById = new Map<string, NcpMessage>();\n let unsubscribe: Unsubscribe = () => undefined;\n const promise = new Promise<NcpMessage>((resolve, reject) => {\n unsubscribe = input.eventBus.on(eventKeys.ncpEvent, (event) => {\n switch (event.type) {\n case NcpEventType.MessageAccepted:\n if (event.payload.correlationId === input.requestId) {\n acceptedMessageId = event.payload.messageId;\n input.onAccepted(event.payload.messageId);\n }\n return;\n case NcpEventType.MessageCompleted:\n if (event.payload.correlationId === input.requestId || event.payload.message.id === acceptedMessageId) {\n unsubscribe();\n resolve(event.payload.message);\n return;\n }\n completedMessagesById.set(event.payload.message.id, event.payload.message);\n return;\n case NcpEventType.RunFinished:\n if (\n ((event.payload as typeof event.payload & { correlationId?: string }).correlationId === input.requestId ||\n event.payload.messageId === acceptedMessageId) &&\n event.payload.messageId\n ) {\n acceptedMessageId = event.payload.messageId;\n input.onAccepted(event.payload.messageId);\n const completedMessage = completedMessagesById.get(event.payload.messageId);\n if (completedMessage) {\n unsubscribe();\n resolve(completedMessage);\n }\n }\n return;\n case NcpEventType.MessageFailed:\n if (event.payload.correlationId === input.requestId || event.payload.messageId === acceptedMessageId) {\n unsubscribe();\n reject(new Error(event.payload.error.message));\n }\n return;\n case NcpEventType.RunError:\n if (\n (event.payload as typeof event.payload & { correlationId?: string }).correlationId === input.requestId ||\n event.payload.messageId === acceptedMessageId\n ) {\n unsubscribe();\n reject(new Error(event.payload.error ?? \"Session request failed.\"));\n }\n return;\n }\n });\n });\n return {\n dispose: unsubscribe,\n promise,\n };\n}\n\nexport async function dispatchAgentRuntimeSessionRequest(input: {\n ingress: Ingress;\n request: SessionRequestRecord;\n task: string;\n}): Promise<void> {\n await input.ingress.handle({\n type: ingressKeys.agentRun.sessionMessageRequest,\n payload: {\n message: {\n id: `${input.request.targetSessionId}:user:session-request:${input.request.requestId}`,\n sessionId: input.request.targetSessionId,\n role: \"user\",\n status: \"final\",\n timestamp: new Date().toISOString(),\n parts: [{ type: \"text\", text: input.task }],\n metadata: { session_request_id: input.request.requestId },\n },\n requestId: input.request.requestId,\n sessionId: input.request.targetSessionId,\n },\n }, { source: \"session-request\" });\n}\n\nexport function createAgentRuntimeSessionRequestDispatcher(\n options: AgentRuntimeSessionRequestDispatcherOptions,\n): SessionRequestDispatcher {\n return {\n dispatch: async (input) => {\n const reply = waitForAgentRuntimeSessionReply({\n eventBus: options.eventBus,\n onAccepted: input.onAccepted,\n requestId: input.request.requestId,\n });\n try {\n await dispatchAgentRuntimeSessionRequest({\n ingress: options.ingress,\n request: input.request,\n task: input.task,\n });\n const message = await reply.promise;\n return {\n finalResponseMessageId: message.id,\n finalResponseText: extractSessionMessageText(message),\n };\n } catch (error) {\n reply.dispose();\n throw error;\n }\n },\n };\n}\n","import { access } from \"node:fs/promises\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport {\n ProviderRegistry,\n resolveProviderRuntime,\n type Config,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { BUILTIN_PROVIDER_PLUGINS } from \"@nextclaw/runtime\";\nimport type { NcpAgentRunInput, NcpProviderRuntimeRoute } from \"@nextclaw/ncp\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\nimport {\n HttpRuntimeConfigResolver,\n HttpRuntimeNcpAgentRuntime,\n} from \"@nextclaw/nextclaw-ncp-runtime-http-client\";\nimport {\n probeStdioRuntime,\n StdioRuntimeConfigResolver,\n StdioRuntimeNcpAgentRuntime,\n} from \"@nextclaw/nextclaw-ncp-runtime-stdio-client\";\nimport type {\n AgentRuntimeEntry,\n AgentRuntimeProviderRegistration,\n AgentRuntimeSessionTypeDescribeParams,\n AgentRuntimeSessionTypeOption,\n} from \"@kernel/features/runtime-registry/index.js\";\n\nconst NARP_API_MODE_HEADER = \"x-nextclaw-narp-api-mode\";\nexport const NARP_HTTP_RUNTIME_KIND = \"narp-http\";\nexport const NARP_STDIO_RUNTIME_KIND = \"narp-stdio\";\nconst BUILTIN_PROVIDER_REGISTRY = new ProviderRegistry(BUILTIN_PROVIDER_PLUGINS);\n\ntype SessionTypeDescriptor = Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\">;\n\nfunction readRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction resolveEntryIcon(\n entry: AgentRuntimeEntry,\n): SessionTypeDescriptor[\"icon\"] {\n return entry.icon ?? null;\n}\n\nfunction resolveRequestedModel(params: {\n input: NcpAgentRunInput;\n sessionMetadata: Record<string, unknown>;\n defaultModel?: string;\n configuredModel?: string;\n}): string | undefined {\n const { configuredModel, defaultModel, input, sessionMetadata } = params;\n const runMetadata = readRecord(input.metadata);\n return (\n readString(runMetadata?.preferred_model) ??\n readString(runMetadata?.preferredModel) ??\n readString(runMetadata?.model) ??\n readString(sessionMetadata.preferred_model) ??\n readString(sessionMetadata.preferredModel) ??\n readString(sessionMetadata.model) ??\n configuredModel ??\n defaultModel\n );\n}\n\nfunction resolveProviderApiMode(\n resolution: ReturnType<typeof resolveProviderRuntime>,\n): \"chat_completions\" | \"codex_responses\" | \"anthropic_messages\" {\n const wireApi = resolution.provider?.wireApi?.trim().toLowerCase();\n if (wireApi === \"responses\") {\n return \"codex_responses\";\n }\n if (wireApi === \"chat\") {\n return \"chat_completions\";\n }\n const providerName = resolution.providerName?.trim().toLowerCase();\n const apiBase = resolution.apiBase?.trim().toLowerCase() ?? \"\";\n if (providerName === \"anthropic\" || apiBase.includes(\"anthropic.com\")) {\n return \"anthropic_messages\";\n }\n return \"chat_completions\";\n}\n\nfunction buildProviderRoute(params: {\n config: Config;\n input: NcpAgentRunInput;\n sessionMetadata: Record<string, unknown>;\n defaultModel?: string;\n configuredModel?: string;\n}): NcpProviderRuntimeRoute | undefined {\n const model = resolveRequestedModel(params);\n if (!model) {\n return undefined;\n }\n const resolution = resolveProviderRuntime(params.config, model);\n if (!resolution.provider) {\n return undefined;\n }\n const apiBase =\n resolution.apiBase ??\n (resolution.providerName\n ? BUILTIN_PROVIDER_REGISTRY.findProviderByName(resolution.providerName)?.defaultApiBase ?? null\n : null);\n return {\n model: resolution.providerLocalModel,\n apiKey: resolution.apiKey,\n apiBase,\n headers: {\n ...(resolution.provider.extraHeaders ?? {}),\n [NARP_API_MODE_HEADER]: resolveProviderApiMode(resolution),\n },\n };\n}\n\nclass BuiltinHttpRuntimeSessionTypeService {\n private readonly pendingDescribeByMode = new Map<\n \"observation\" | \"probe\",\n Promise<SessionTypeDescriptor>\n >();\n\n constructor(private readonly entry: AgentRuntimeEntry, private readonly defaultModel?: string) {}\n\n describe = async (\n describeParams?: AgentRuntimeSessionTypeDescribeParams,\n ): Promise<SessionTypeDescriptor> => {\n const describeMode =\n describeParams?.describeMode === \"probe\" ? \"probe\" : \"observation\";\n const pending = this.pendingDescribeByMode.get(describeMode);\n if (pending) {\n return await pending;\n }\n const nextDescribe = this.describeInternal();\n this.pendingDescribeByMode.set(describeMode, nextDescribe);\n try {\n return await nextDescribe;\n } finally {\n this.pendingDescribeByMode.delete(describeMode);\n }\n };\n\n private describeInternal = async (): Promise<SessionTypeDescriptor> => {\n const resolver = new HttpRuntimeConfigResolver(this.entry.config ?? {});\n const config = resolver.resolve({\n defaultModel: this.defaultModel,\n });\n\n if (!config.baseUrl) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"base_url_missing\",\n reasonMessage: \"Configure the runtime entry baseUrl before starting an HTTP runtime session.\",\n recommendedModel: config.recommendedModel ?? null,\n cta: {\n kind: \"settings\",\n label: \"Configure HTTP Runtime\",\n },\n };\n }\n\n const shouldProbe = (config.capabilityProbe ?? true) && Boolean(config.healthcheckUrl);\n if (!shouldProbe) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: true,\n reason: null,\n reasonMessage: null,\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n }\n\n const controller = new AbortController();\n const timeoutMs = config.healthcheckTimeoutMs ?? 3000;\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(config.healthcheckUrl ?? \"\", {\n method: \"GET\",\n headers: config.headers,\n signal: controller.signal,\n });\n if (!response.ok) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"healthcheck_failed\",\n reasonMessage: `HTTP runtime healthcheck returned HTTP ${response.status}.`,\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n }\n return {\n icon: resolveEntryIcon(this.entry),\n ready: true,\n reason: null,\n reasonMessage: null,\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n } catch (error) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"healthcheck_unreachable\",\n reasonMessage:\n error instanceof Error\n ? error.message\n : \"Failed to reach the configured HTTP runtime healthcheck.\",\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n } finally {\n clearTimeout(timeout);\n }\n };\n}\n\nclass BuiltinStdioRuntimeSessionTypeService {\n private readonly pendingDescribeByMode = new Map<\n \"observation\" | \"probe\",\n Promise<SessionTypeDescriptor>\n >();\n\n constructor(private readonly entry: AgentRuntimeEntry) {}\n\n describe = async (\n describeParams?: AgentRuntimeSessionTypeDescribeParams,\n ): Promise<SessionTypeDescriptor> => {\n const describeMode =\n describeParams?.describeMode === \"probe\" ? \"probe\" : \"observation\";\n const pending = this.pendingDescribeByMode.get(describeMode);\n if (pending) {\n return await pending;\n }\n const nextDescribe = this.describeInternal(describeMode);\n this.pendingDescribeByMode.set(describeMode, nextDescribe);\n try {\n return await nextDescribe;\n } finally {\n this.pendingDescribeByMode.delete(describeMode);\n }\n };\n\n private describeInternal = async (\n describeMode: \"observation\" | \"probe\",\n ): Promise<SessionTypeDescriptor> => {\n const resolver = new StdioRuntimeConfigResolver(this.entry.config ?? {});\n try {\n const config = resolver.resolve();\n const executablePath = await resolveExecutablePath(config.command);\n if (!executablePath) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"command_missing\",\n reasonMessage: `Configured stdio command \"${config.command}\" is not available. Update the runtime entry command or install the required launcher first.`,\n cta: {\n kind: \"settings\",\n label: \"Configure Stdio Runtime\",\n },\n };\n }\n if (describeMode === \"probe\") {\n try {\n await probeStdioRuntime(config);\n } catch (error) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"probe_failed\",\n reasonMessage:\n error instanceof Error\n ? error.message\n : \"Configured stdio runtime could not complete the ACP probe.\",\n cta: {\n kind: \"settings\",\n label: \"Repair Stdio Runtime\",\n },\n };\n }\n }\n return {\n icon: resolveEntryIcon(this.entry),\n ready: true,\n reason: null,\n reasonMessage: null,\n cta: null,\n };\n } catch (error) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"command_missing\",\n reasonMessage:\n error instanceof Error\n ? error.message\n : \"Configure a stdio command before starting this runtime.\",\n cta: {\n kind: \"settings\",\n label: \"Configure Stdio Runtime\",\n },\n };\n }\n };\n}\n\nasync function resolveExecutablePath(command: string): Promise<string | null> {\n if (command.includes(\"/\") || command.includes(\"\\\\\")) {\n return (await isExecutable(command)) ? command : null;\n }\n const searchPath = process.env.PATH ?? \"\";\n for (const directory of searchPath.split(delimiter)) {\n const trimmed = directory.trim();\n if (!trimmed) {\n continue;\n }\n const candidate = `${trimmed}/${command}`;\n if (await isExecutable(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n\nasync function isExecutable(filePath: string): Promise<boolean> {\n try {\n await access(filePath, fsConstants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport class BuiltinNarpRuntimeProviderService {\n constructor(\n private readonly configManager: Pick<ConfigManager, \"loadConfig\">,\n ) {}\n\n createProviders = (): AgentRuntimeProviderRegistration[] => {\n return [\n {\n kind: NARP_HTTP_RUNTIME_KIND,\n label: \"NARP HTTP\",\n createRuntime: this.createUnavailableRuntime,\n createRuntimeForEntry: ({ entry, runtimeParams }) =>\n this.createHttpRuntime(entry, runtimeParams),\n describeSessionTypeForEntry: ({ entry, describeParams }) =>\n new BuiltinHttpRuntimeSessionTypeService(\n entry,\n this.configManager.loadConfig().agents.defaults.model,\n ).describe(describeParams),\n },\n {\n kind: NARP_STDIO_RUNTIME_KIND,\n label: \"NARP Stdio\",\n createRuntime: this.createUnavailableRuntime,\n createRuntimeForEntry: ({ entry, runtimeParams }) =>\n this.createStdioRuntime(entry, runtimeParams),\n describeSessionTypeForEntry: ({ entry, describeParams }) =>\n new BuiltinStdioRuntimeSessionTypeService(entry).describe(describeParams),\n },\n ];\n };\n\n private createUnavailableRuntime = (): never => {\n throw new Error(\"[narp] runtime entry is required before creating this runtime\");\n };\n\n private createHttpRuntime = (\n entry: AgentRuntimeEntry,\n runtimeParams: RuntimeFactoryParams,\n ): HttpRuntimeNcpAgentRuntime => {\n const config = readRecord(entry.config) ?? {};\n const resolver = new HttpRuntimeConfigResolver(config);\n const resolvedConfig = resolver.resolve({\n defaultModel: this.configManager.loadConfig().agents.defaults.model,\n });\n return new HttpRuntimeNcpAgentRuntime({\n baseUrl: resolver.requireBaseUrl(),\n ...(resolvedConfig.basePath ? { basePath: resolvedConfig.basePath } : {}),\n ...(resolvedConfig.endpointId ? { endpointId: resolvedConfig.endpointId } : {}),\n ...(resolvedConfig.headers ? { headers: resolvedConfig.headers } : {}),\n stateManager: runtimeParams.stateManager,\n resolveProviderRoute: (input) =>\n buildProviderRoute({\n config: this.configManager.loadConfig(),\n input,\n sessionMetadata: runtimeParams.sessionMetadata,\n defaultModel: this.configManager.loadConfig().agents.defaults.model,\n configuredModel: readString(config.model),\n }),\n });\n };\n\n private createStdioRuntime = (\n entry: AgentRuntimeEntry,\n runtimeParams: RuntimeFactoryParams,\n ): StdioRuntimeNcpAgentRuntime => {\n const config = readRecord(entry.config) ?? {};\n const resolver = new StdioRuntimeConfigResolver(config);\n const resolvedConfig = resolver.resolve();\n return new StdioRuntimeNcpAgentRuntime({\n ...resolvedConfig,\n sessionId: runtimeParams.sessionId,\n stateManager: runtimeParams.stateManager,\n resolveProviderRoute: (input: NcpAgentRunInput) =>\n buildProviderRoute({\n config: this.configManager.loadConfig(),\n input,\n sessionMetadata: runtimeParams.sessionMetadata,\n defaultModel: this.configManager.loadConfig().agents.defaults.model,\n configuredModel: readString(config.model),\n }),\n });\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { BuiltinNarpRuntimeProviderService } from \"@kernel/features/narp-runtime/index.js\";\nimport { NativeAgentRuntimeFactory } from \"@kernel/features/native-runtime/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\n\nexport class AgentRuntimeContribution implements KernelContribution {\n private cleanups: Array<() => void> = [];\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.cleanups.length > 0) {\n return;\n }\n const nativeRuntimeFactory = new NativeAgentRuntimeFactory({\n providerManager: this.kernel.llmProviders,\n configManager: this.kernel.configManager,\n llmUsage: this.kernel.llmUsage,\n assetStore: this.kernel.assetStore,\n updateToolCallResult: this.kernel.sessionRunManager.updateToolCallResult,\n toolManager: this.kernel.toolManager,\n });\n const builtinNarpRuntimeProviders = new BuiltinNarpRuntimeProviderService(\n this.kernel.configManager,\n ).createProviders();\n const nativeRegistration = this.kernel.agentRuntimeManager.registerRuntimeProvider({\n kind: \"native\",\n label: \"Native\",\n createRuntime: nativeRuntimeFactory.create,\n });\n this.cleanups = [\n () => nativeRegistration.dispose(),\n ...builtinNarpRuntimeProviders.map((provider) => {\n const registration = this.kernel.agentRuntimeManager.registerRuntimeProvider(provider);\n return () => registration.dispose();\n }),\n ];\n };\n\n dispose = (): void => {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups = [];\n };\n}\n","import type { Config } from \"@nextclaw/core\";\n\nexport const LEARNING_LOOP_DISABLED_METADATA_KEY = \"learning_loop_disabled\";\nexport const LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY =\n \"learning_loop_last_tool_call_count\";\nexport const LEARNING_LOOP_LAST_REQUESTED_AT_METADATA_KEY =\n \"learning_loop_last_requested_at\";\nexport const LEARNING_LOOP_LAST_REVIEW_SESSION_ID_METADATA_KEY =\n \"learning_loop_last_review_session_id\";\nexport const LEARNING_LOOP_SOURCE_SESSION_ID_METADATA_KEY =\n \"learning_loop_source_session_id\";\nexport const LEARNING_LOOP_REQUESTED_SKILLS = [\"skill-creator\"];\nexport const DEFAULT_LEARNING_LOOP_TOOL_CALL_THRESHOLD = 15;\n\nexport type LearningLoopRuntimeConfig = {\n enabled: boolean;\n toolCallThreshold: number;\n};\n\nexport function readLearningLoopRuntimeConfig(\n config: Config,\n): LearningLoopRuntimeConfig {\n return {\n enabled: config.agents.learningLoop.enabled,\n toolCallThreshold:\n config.agents.learningLoop.toolCallThreshold ??\n DEFAULT_LEARNING_LOOP_TOOL_CALL_THRESHOLD,\n };\n}\n","function pluralizeToolCalls(value: number): string {\n return value === 1 ? \"1 tool call\" : `${value} tool calls`;\n}\n\nexport function buildLearningLoopTask(params: {\n sessionId: string;\n toolCallsSinceReview: number;\n currentToolCallCount: number;\n}): string {\n return [\n \"Run a background learning-loop review for the parent session.\",\n `Parent session id: ${params.sessionId}.`,\n `There have been ${pluralizeToolCalls(params.toolCallsSinceReview)} since the last learning-loop review (${params.currentToolCallCount} total so far).`,\n \"\",\n \"Your job is to extract only the reusable lesson.\",\n \"- Review the parent session history and, if helpful, use session_search to compare similar historical sessions.\",\n \"- Decide exactly one outcome: no_skill_change, patch_existing_skill, or create_new_skill.\",\n \"- Prefer patching an existing skill when the lesson extends an existing workflow.\",\n \"- Only create a new skill when the lesson is clearly reusable, repeatable, and likely to recur.\",\n \"- Do not create or patch a skill for one-off quirks, noisy transcripts, or narrow local accidents.\",\n \"\",\n \"If you decide to patch or create a skill:\",\n \"- Use the available file tools.\",\n \"- Keep the change minimal and maintainable.\",\n \"- Write the skill into the current workspace/project skills directory under skills/<slug>/SKILL.md.\",\n \"- Follow the built-in skill-creator guidance when it helps.\",\n \"\",\n \"If nothing reusable should be saved, stop without writing files.\",\n ].join(\"\\n\");\n}\n","import {\n readParentSessionId,\n type SessionRequestToolResult,\n type SpawnSessionAndRequestParams,\n} from \"@nextclaw/core\";\nimport { NcpEventType, type NcpEndpointEvent, type NcpMessage } from \"@nextclaw/ncp\";\nimport { eventKeys, type Unsubscribe } from \"@nextclaw/shared\";\nimport type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport {\n LEARNING_LOOP_DISABLED_METADATA_KEY,\n LEARNING_LOOP_LAST_REQUESTED_AT_METADATA_KEY,\n LEARNING_LOOP_LAST_REVIEW_SESSION_ID_METADATA_KEY,\n LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY,\n LEARNING_LOOP_REQUESTED_SKILLS,\n LEARNING_LOOP_SOURCE_SESSION_ID_METADATA_KEY,\n readLearningLoopRuntimeConfig,\n type LearningLoopRuntimeConfig,\n} from \"./config.js\";\nimport { buildLearningLoopTask } from \"./utils/learning-loop-prompt.utils.js\";\n\nexport type LearningLoopSessionRequester = {\n spawnSessionAndRequest: (\n params: SpawnSessionAndRequestParams,\n ) => Promise<SessionRequestToolResult>;\n};\n\ntype LearningLoopSessionStore = Pick<\n NcpSessionManager,\n \"getSessionRecord\" | \"updateSessionMetadata\"\n>;\n\nfunction countToolCallsFromMessage(message: NcpMessage): number {\n if (!Array.isArray(message.parts)) {\n return 0;\n }\n const seenIds = new Set<string>();\n let anonymousCount = 0;\n for (const part of message.parts) {\n if (!part || typeof part !== \"object\" || Array.isArray(part)) {\n continue;\n }\n const candidate = part as {\n type?: unknown;\n toolCallId?: unknown;\n };\n if (candidate.type !== \"tool-invocation\") {\n continue;\n }\n if (typeof candidate.toolCallId === \"string\" && candidate.toolCallId.trim()) {\n seenIds.add(candidate.toolCallId.trim());\n continue;\n }\n anonymousCount += 1;\n }\n return seenIds.size + anonymousCount;\n}\n\nfunction countSessionToolCalls(messages: readonly NcpMessage[]): number {\n return messages.reduce((count, message) => count + countToolCallsFromMessage(message), 0);\n}\n\nfunction readSessionLabel(metadata: Record<string, unknown>): string | undefined {\n const label = metadata.label;\n return typeof label === \"string\" && label.trim().length > 0 ? label.trim() : undefined;\n}\n\nfunction isLearningLoopDisabled(metadata: Record<string, unknown>): boolean {\n return metadata[LEARNING_LOOP_DISABLED_METADATA_KEY] === true;\n}\n\nfunction readLearningLoopLastToolCallCount(\n metadata: Record<string, unknown>,\n): number {\n const value = metadata[LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY];\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n}\n\nfunction readRunFinishedSessionId(event: NcpEndpointEvent): string | null {\n if (event.type !== NcpEventType.RunFinished) {\n return null;\n }\n return event.payload.sessionId?.trim() || null;\n}\n\nexport class LearningLoopContribution implements KernelContribution {\n private readonly sessionStore: LearningLoopSessionStore;\n private readonly sessionRequester: LearningLoopSessionRequester;\n private readonly inFlightSessionIds = new Set<string>();\n private unsubscribe: Unsubscribe | null = null;\n\n constructor(private readonly kernel: NextclawKernel) {\n this.sessionStore = kernel.ncpSessionManager;\n this.sessionRequester = kernel.sessionRequests;\n }\n\n start = (): void => {\n if (this.unsubscribe) {\n return;\n }\n this.unsubscribe = this.kernel.eventBus.on(eventKeys.ncpEvent, this.handleNcpEvent);\n };\n\n dispose = (): void => {\n this.unsubscribe?.();\n this.unsubscribe = null;\n this.inFlightSessionIds.clear();\n };\n\n private handleNcpEvent = (event: NcpEndpointEvent): void => {\n const sessionId = readRunFinishedSessionId(event);\n if (!sessionId) {\n return;\n }\n void this.handleRunFinishedInBackground(sessionId).catch((error) => {\n console.warn(\n `[learning-loop] Failed for ${sessionId}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n });\n };\n\n private handleRunFinishedInBackground = async (\n sessionId: string,\n ): Promise<void> => {\n if (this.inFlightSessionIds.has(sessionId)) {\n return;\n }\n const session = await this.sessionStore.getSessionRecord(sessionId);\n const metadata = session?.metadata ?? {};\n if (!session || readParentSessionId(metadata)) {\n return;\n }\n const runtimeConfig = this.readRuntimeConfig();\n if (!runtimeConfig.enabled || isLearningLoopDisabled(metadata)) {\n return;\n }\n const totalToolCalls = countSessionToolCalls(session.messages);\n const lastReviewedToolCallCount = readLearningLoopLastToolCallCount(\n metadata,\n );\n const toolCallsSinceReview = totalToolCalls - lastReviewedToolCallCount;\n if (toolCallsSinceReview < runtimeConfig.toolCallThreshold) {\n return;\n }\n\n this.inFlightSessionIds.add(sessionId);\n try {\n const reviewSession = await this.sessionRequester.spawnSessionAndRequest({\n sourceSessionId: sessionId,\n updateToolCallResult: async () => undefined,\n sourceSessionMetadata: metadata,\n metadataOverrides: {\n requested_skills: LEARNING_LOOP_REQUESTED_SKILLS,\n [LEARNING_LOOP_DISABLED_METADATA_KEY]: true,\n [LEARNING_LOOP_SOURCE_SESSION_ID_METADATA_KEY]: sessionId,\n },\n parentSessionId: sessionId,\n notify: \"none\",\n title: this.buildReviewTitle(metadata),\n task: buildLearningLoopTask({\n sessionId,\n toolCallsSinceReview,\n currentToolCallCount: totalToolCalls,\n }),\n });\n await this.sessionStore.updateSessionMetadata(sessionId, {\n [LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY]: totalToolCalls,\n [LEARNING_LOOP_LAST_REQUESTED_AT_METADATA_KEY]: new Date().toISOString(),\n [LEARNING_LOOP_LAST_REVIEW_SESSION_ID_METADATA_KEY]:\n reviewSession.sessionId,\n });\n } finally {\n this.inFlightSessionIds.delete(sessionId);\n }\n };\n\n private readRuntimeConfig = (): LearningLoopRuntimeConfig => {\n return readLearningLoopRuntimeConfig(this.kernel.configManager.loadConfig());\n };\n\n private buildReviewTitle = (metadata: Record<string, unknown>): string => {\n const label = readSessionLabel(metadata);\n return label ? `Learning loop: ${label}` : \"Learning loop\";\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { type NcpEndpointEvent, NcpEventType } from \"@nextclaw/ncp\";\nimport { eventKeys, type Unsubscribe } from \"@nextclaw/shared\";\n\nconst STREAM_REFRESH_DELAY_MS = 1500;\n\nfunction formatBackgroundError(error: unknown): string {\n if (error instanceof Error) {\n return error.stack ?? error.message;\n }\n return String(error);\n}\n\nfunction readEventSessionId(event: NcpEndpointEvent): string | null {\n const payload = \"payload\" in event ? event.payload : null;\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n return \"sessionId\" in payload && typeof payload.sessionId === \"string\"\n ? payload.sessionId.trim() || null\n : null;\n}\n\nfunction isContextWindow(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction createSignature(value: Record<string, unknown>): string {\n return JSON.stringify(value);\n}\n\nfunction shouldRefreshDuringStream(event: NcpEndpointEvent): boolean {\n switch (event.type) {\n case NcpEventType.MessageTextStart:\n case NcpEventType.MessageTextDelta:\n case NcpEventType.MessageTextEnd:\n case NcpEventType.MessageReasoningStart:\n case NcpEventType.MessageReasoningDelta:\n case NcpEventType.MessageReasoningEnd:\n case NcpEventType.MessageToolCallStart:\n case NcpEventType.MessageToolCallArgs:\n case NcpEventType.MessageToolCallArgsDelta:\n case NcpEventType.MessageToolCallEnd:\n case NcpEventType.MessageToolCallResult:\n return true;\n default:\n return false;\n }\n}\n\nfunction shouldRefreshImmediately(event: NcpEndpointEvent): boolean {\n switch (event.type) {\n case NcpEventType.MessageSent:\n case NcpEventType.MessageCompleted:\n case NcpEventType.MessageFailed:\n case NcpEventType.MessageAbort:\n case NcpEventType.RunFinished:\n case NcpEventType.RunError:\n return true;\n default:\n return false;\n }\n}\n\nexport class SessionContextWindowContribution implements KernelContribution {\n private unsubscribeNcpEvent: Unsubscribe | null = null;\n private stopped = true;\n private readonly pendingTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly lastPublishedSignatureBySession = new Map<string, string>();\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.unsubscribeNcpEvent) {\n return;\n }\n this.stopped = false;\n this.unsubscribeNcpEvent = this.kernel.eventBus.on(eventKeys.ncpEvent, this.handleNcpEvent);\n };\n\n dispose = (): void => {\n this.unsubscribeNcpEvent?.();\n this.unsubscribeNcpEvent = null;\n this.stopped = true;\n for (const timer of this.pendingTimers.values()) {\n clearTimeout(timer);\n }\n this.pendingTimers.clear();\n this.lastPublishedSignatureBySession.clear();\n };\n\n private handleNcpEvent = (event: NcpEndpointEvent): void => {\n const sessionId = readEventSessionId(event);\n if (!sessionId) {\n return;\n }\n if (event.type === NcpEventType.ContextWindowUpdated) {\n this.rememberPublishedContextWindow(sessionId, event.payload.contextWindow);\n return;\n }\n if (shouldRefreshImmediately(event)) {\n this.refreshNow(sessionId);\n return;\n }\n if (shouldRefreshDuringStream(event)) {\n this.refreshSoon(sessionId);\n }\n };\n\n private refreshSoon = (sessionId: string): void => {\n if (this.pendingTimers.has(sessionId)) {\n return;\n }\n const timer = setTimeout(() => {\n this.pendingTimers.delete(sessionId);\n this.refreshNow(sessionId);\n }, STREAM_REFRESH_DELAY_MS);\n this.pendingTimers.set(sessionId, timer);\n };\n\n private refreshNow = (sessionId: string): void => {\n const timer = this.pendingTimers.get(sessionId);\n if (timer) {\n clearTimeout(timer);\n this.pendingTimers.delete(sessionId);\n }\n void this.publishContextWindow(sessionId).catch((error: unknown) => {\n console.error(`[session-context-window] failed to refresh ${sessionId}: ${formatBackgroundError(error)}`);\n });\n };\n\n private publishContextWindow = async (sessionId: string): Promise<void> => {\n if (this.stopped) {\n return;\n }\n const contextWindow = await this.kernel.ncpSessionManager.getContextWindow(\n sessionId,\n this.kernel.sessionRunManager.getLiveSessionRecord(sessionId),\n );\n if (!isContextWindow(contextWindow) || this.stopped) {\n return;\n }\n const signature = createSignature(contextWindow);\n if (this.lastPublishedSignatureBySession.get(sessionId) === signature) {\n return;\n }\n this.lastPublishedSignatureBySession.set(sessionId, signature);\n this.kernel.eventBus.emit(eventKeys.ncpEvent, {\n type: NcpEventType.ContextWindowUpdated,\n payload: {\n sessionId,\n contextWindow,\n },\n }, {\n emittedAt: new Date().toISOString(),\n source: \"session-context-window\",\n });\n };\n\n private rememberPublishedContextWindow = (\n sessionId: string,\n contextWindow: Record<string, unknown>,\n ): void => {\n this.lastPublishedSignatureBySession.set(sessionId, createSignature(contextWindow));\n };\n}\n","import { NcpEventType, type NcpEndpointEvent, type NcpMessage } from \"@nextclaw/ncp\";\nimport type {\n SessionActivityPreviewMetadata,\n SessionActivityPreviewProjection,\n} from \"@kernel/contributions/session-activity-preview/types/session-activity-preview.types.js\";\n\nconst PREVIEW_TEXT_MAX_LENGTH = 160;\n\nfunction readSessionId(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction compactPreviewText(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nfunction truncatePreviewText(value: string): string {\n const compacted = compactPreviewText(value);\n if (compacted.length <= PREVIEW_TEXT_MAX_LENGTH) {\n return compacted;\n }\n return compacted.slice(0, PREVIEW_TEXT_MAX_LENGTH - 1).trimEnd();\n}\n\nfunction readMessagePreviewText(message: NcpMessage): string | null {\n const chunks: string[] = [];\n for (const part of message.parts) {\n if ((part.type === \"text\" || part.type === \"rich-text\") && part.text.trim()) {\n chunks.push(part.text);\n }\n }\n const previewText = truncatePreviewText(chunks.join(\" \"));\n return previewText.length > 0 ? previewText : null;\n}\n\nfunction createProjection(\n sessionId: string | null,\n preview: SessionActivityPreviewMetadata,\n): SessionActivityPreviewProjection | null {\n if (!sessionId) {\n return null;\n }\n return { sessionId, preview };\n}\n\nfunction formatErrorStatus(error: unknown): string {\n if (typeof error === \"string\" && error.trim()) {\n return `运行出错:${truncatePreviewText(error)}`;\n }\n if (error && typeof error === \"object\" && \"message\" in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\" && message.trim()) {\n return `运行出错:${truncatePreviewText(message)}`;\n }\n }\n return \"运行出错\";\n}\n\nexport function createSessionActivityPreviewFromNcpEvent(\n event: NcpEndpointEvent,\n timestamp: string,\n): SessionActivityPreviewProjection | null {\n switch (event.type) {\n case NcpEventType.RunStarted:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: \"正在处理...\",\n timestamp,\n });\n case NcpEventType.RunFinished:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"completed\",\n timestamp,\n });\n case NcpEventType.RunError:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"failed\",\n statusText: formatErrorStatus(event.payload.error),\n timestamp,\n });\n case NcpEventType.MessageSent: {\n const text = readMessagePreviewText(event.payload.message);\n if (!text || event.payload.message.role !== \"user\") {\n return null;\n }\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: text,\n timestamp: event.payload.message.timestamp || timestamp,\n });\n }\n case NcpEventType.MessageCompleted: {\n const text = readMessagePreviewText(event.payload.message);\n if (!text || event.payload.message.role !== \"assistant\") {\n return null;\n }\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"completed\",\n replyText: text,\n timestamp: event.payload.message.timestamp || timestamp,\n });\n }\n case NcpEventType.MessageFailed:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"failed\",\n statusText: formatErrorStatus(event.payload.error),\n timestamp,\n });\n case NcpEventType.MessageToolCallStart:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: `正在调用工具:${event.payload.toolName}`,\n timestamp,\n });\n case NcpEventType.MessageToolCallEnd:\n case NcpEventType.MessageToolCallResult:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: \"工具调用完成\",\n timestamp,\n });\n default:\n return null;\n }\n}\n","import type {\n SessionActivityPreviewMetadata,\n SessionActivityPreviewProjection,\n SessionActivityPreviewState,\n} from \"@kernel/contributions/session-activity-preview/types/session-activity-preview.types.js\";\n\nexport const SESSION_ACTIVITY_PREVIEW_METADATA_KEY = \"last_activity_preview\";\n\nconst SESSION_ACTIVITY_PREVIEW_STATES = new Set<SessionActivityPreviewState>([\n \"running\",\n \"completed\",\n \"failed\",\n \"idle\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction readOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction readSessionActivityPreviewMetadata(value: unknown): SessionActivityPreviewMetadata | null {\n if (!isRecord(value)) {\n return null;\n }\n const state = value.state;\n const timestamp = readOptionalString(value.timestamp);\n if (!SESSION_ACTIVITY_PREVIEW_STATES.has(state as SessionActivityPreviewState) || !timestamp) {\n return null;\n }\n return {\n state: state as SessionActivityPreviewState,\n timestamp,\n ...(readOptionalString(value.statusText) ? { statusText: readOptionalString(value.statusText) } : {}),\n ...(readOptionalString(value.replyText) ? { replyText: readOptionalString(value.replyText) } : {}),\n };\n}\n\nfunction compareIsoTimestamp(left: string, right: string): number {\n const leftTime = Date.parse(left);\n const rightTime = Date.parse(right);\n if (!Number.isFinite(leftTime) || !Number.isFinite(rightTime)) {\n return left.localeCompare(right);\n }\n return leftTime - rightTime;\n}\n\nfunction mergeSessionActivityPreview(\n current: SessionActivityPreviewMetadata | null,\n incoming: SessionActivityPreviewMetadata,\n): SessionActivityPreviewMetadata {\n if (current && compareIsoTimestamp(incoming.timestamp, current.timestamp) < 0) {\n return incoming.replyText && !current.replyText ? { ...current, replyText: incoming.replyText } : current;\n }\n return {\n state: incoming.state,\n timestamp: incoming.timestamp,\n ...(incoming.statusText ?? (incoming.state === \"completed\" ? current?.statusText : undefined)\n ? { statusText: incoming.statusText ?? current?.statusText }\n : {}),\n ...(incoming.replyText ?? current?.replyText ? { replyText: incoming.replyText ?? current?.replyText } : {}),\n };\n}\n\nfunction areSessionActivityPreviewsEqual(\n left: SessionActivityPreviewMetadata | null,\n right: SessionActivityPreviewMetadata,\n): boolean {\n return Boolean(left) &&\n left?.state === right.state &&\n left.timestamp === right.timestamp &&\n left.statusText === right.statusText &&\n left.replyText === right.replyText;\n}\n\nexport function writeSessionActivityPreviewMetadata(\n metadata: Record<string, unknown> | undefined,\n projection: SessionActivityPreviewProjection,\n): Record<string, unknown> | null {\n const current = readSessionActivityPreviewMetadata(metadata?.[SESSION_ACTIVITY_PREVIEW_METADATA_KEY]);\n const next = mergeSessionActivityPreview(current, projection.preview);\n if (areSessionActivityPreviewsEqual(current, next)) {\n return null;\n }\n return {\n ...(metadata ?? {}),\n [SESSION_ACTIVITY_PREVIEW_METADATA_KEY]: next,\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { eventKeys, type Unsubscribe } from \"@nextclaw/shared\";\nimport type { SessionActivityPreviewProjection } from \"./types/session-activity-preview.types.js\";\nimport { createSessionActivityPreviewFromNcpEvent } from \"./utils/session-activity-preview-ncp-event.utils.js\";\nimport { writeSessionActivityPreviewMetadata } from \"./utils/session-activity-preview-metadata.utils.js\";\n\nexport class SessionActivityPreviewContribution implements KernelContribution {\n private unsubscribeNcpEvent: Unsubscribe | null = null;\n private readonly metadataWriteChains = new Map<string, Promise<void>>();\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.unsubscribeNcpEvent) {\n return;\n }\n this.unsubscribeNcpEvent = this.kernel.eventBus.on(eventKeys.ncpEvent, (event) => {\n const projection = createSessionActivityPreviewFromNcpEvent(event, new Date().toISOString());\n if (!projection) {\n return;\n }\n this.updatePreview(projection);\n });\n };\n\n dispose = (): void => {\n this.unsubscribeNcpEvent?.();\n this.unsubscribeNcpEvent = null;\n this.metadataWriteChains.clear();\n };\n\n private updatePreview = (projection: SessionActivityPreviewProjection): void => {\n const previous = this.metadataWriteChains.get(projection.sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.updatePreviewMetadata(projection));\n this.metadataWriteChains.set(projection.sessionId, next.catch(() => undefined));\n void next\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(\n `[session-activity-preview] failed to update ${projection.sessionId}: ${message}`,\n );\n });\n };\n\n private updatePreviewMetadata = async (projection: SessionActivityPreviewProjection): Promise<void> => {\n const session = await this.kernel.ncpSessionManager.getSessionRecord(projection.sessionId);\n const nextMetadata = writeSessionActivityPreviewMetadata(session?.metadata, projection);\n if (!nextMetadata) {\n return;\n }\n await this.kernel.ncpSessionManager.updateSessionMetadata(projection.sessionId, nextMetadata);\n };\n}\n","import { Tool, type ToolExecutionContext } from \"@nextclaw/core\";\nimport type { SessionRequestManager } from \"@kernel/features/session-request/index.js\";\n\nfunction readRequiredString(params: Record<string, unknown>, key: string): string {\n const value = params[key];\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(`${key} must be a non-empty string.`);\n }\n return value.trim();\n}\n\nfunction readOptionalString(params: Record<string, unknown>, key: string): string | undefined {\n const value = params[key];\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport class SessionRequestTool extends Tool {\n private sourceSessionId = \"\";\n private handoffDepth = 0;\n\n constructor(private readonly manager: SessionRequestManager) {\n super();\n }\n\n get name(): string {\n return \"sessions_request\";\n }\n\n get description(): string {\n return \"Send one task to another session. Use notify to control whether this session should continue after the target session finishes.\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n target: {\n type: \"object\",\n description: \"Target session reference. Pass an object like {\\\"session_id\\\":\\\"...\\\"}, not a bare string.\",\n properties: {\n session_id: {\n type: \"string\",\n description: \"Existing target session id.\",\n },\n },\n required: [\"session_id\"],\n },\n task: {\n type: \"string\",\n description: \"Task to send to the target session.\",\n },\n notify: {\n type: \"string\",\n enum: [\"none\", \"final_reply\"],\n description: \"Whether the current session should continue after the target session finishes. Use \\\"final_reply\\\" to continue after the target session reaches its final reply.\",\n },\n title: {\n type: \"string\",\n description: \"Optional card title override.\",\n },\n },\n required: [\"target\", \"task\", \"notify\"],\n };\n }\n\n setContext = (params: {\n sourceSessionId: string;\n handoffDepth?: number;\n }): void => {\n this.sourceSessionId = params.sourceSessionId;\n this.handoffDepth = params.handoffDepth ?? 0;\n };\n\n execute = async (\n params: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<unknown> => {\n const target = params.target;\n if (!target || typeof target !== \"object\" || Array.isArray(target)) {\n throw new Error(\"target must be an object.\");\n }\n const task = readRequiredString(params, \"task\");\n const notifyMode = readOptionalString(params, \"notify\")?.toLowerCase();\n if (notifyMode !== \"none\" && notifyMode !== \"final_reply\") {\n throw new Error('notify must be \"none\" or \"final_reply\".');\n }\n const { toolCallId, updateToolCallResult } = context;\n\n return this.manager.requestSession({\n sourceSessionId: this.sourceSessionId,\n ...(toolCallId ? { sourceToolCallId: toolCallId } : {}),\n updateToolCallResult,\n targetSessionId: readRequiredString(target as Record<string, unknown>, \"session_id\"),\n task,\n title: readOptionalString(params, \"title\"),\n notify: notifyMode,\n handoffDepth: this.handoffDepth,\n });\n };\n}\n","import { Tool } from \"@nextclaw/core\";\nimport type { NcpMessage, NcpSessionSummary } from \"@nextclaw/ncp\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\n\nconst DEFAULT_LIMIT = 20;\nconst MAX_MESSAGE_LIMIT = 20;\nconst HISTORY_MAX_BYTES = 80 * 1024;\nconst HISTORY_TEXT_MAX_CHARS = 4000;\n\nfunction toInt(value: unknown, fallback: number): number {\n const parsed = typeof value === \"number\" || typeof value === \"string\" ? Number(value) : NaN;\n return Number.isFinite(parsed) ? Math.max(0, Math.trunc(parsed)) : fallback;\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction messageText(message: NcpMessage): string {\n const text = message.parts\n .map((part) => (part.type === \"text\" || part.type === \"rich-text\" || part.type === \"reasoning\" ? part.text : \"\"))\n .filter(Boolean)\n .join(\"\\n\");\n if (text) return text;\n return JSON.stringify(message.parts, null, 2);\n}\n\nfunction sanitizeMessage(message: NcpMessage) {\n const content = messageText(message);\n const truncated = content.length > HISTORY_TEXT_MAX_CHARS;\n return {\n role: message.role,\n content: truncated ? `${content.slice(0, HISTORY_TEXT_MAX_CHARS)}\\n...(truncated)...` : content,\n timestamp: message.timestamp,\n ...(truncated ? { truncated: true } : {}),\n };\n}\n\nfunction capHistory(items: unknown[]): unknown[] {\n const text = JSON.stringify(items);\n if (Buffer.byteLength(text, \"utf8\") <= HISTORY_MAX_BYTES) return items;\n const last = items.at(-1);\n return last && Buffer.byteLength(JSON.stringify([last]), \"utf8\") <= HISTORY_MAX_BYTES\n ? [last]\n : [{ role: \"assistant\", content: \"[sessions_history omitted: message too large]\" }];\n}\n\nfunction sessionLabel(summary: NcpSessionSummary): string | undefined {\n return readString(summary.metadata?.label) ?? readString(summary.metadata?.session_label);\n}\n\nexport class SessionsListTool extends Tool {\n constructor(private readonly sessions: NcpSessionManager) {\n super();\n }\n\n get name(): string {\n return \"sessions_list\";\n }\n\n get description(): string {\n return \"List available sessions with timestamps.\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n sessionKey: { type: \"string\", description: \"Only include the exact session key\" },\n limit: { type: \"integer\", minimum: 1, description: \"Maximum number of sessions to return\" },\n messageLimit: { type: \"integer\", minimum: 0, description: \"Include last N messages (max 20)\" },\n },\n };\n }\n\n execute = async (params: Record<string, unknown>): Promise<string> => {\n const { limit, messageLimit, sessionKey } = params;\n const exactSessionKey = readString(sessionKey);\n const summaries = exactSessionKey\n ? [await this.sessions.getSession(exactSessionKey)].filter((summary): summary is NcpSessionSummary => Boolean(summary))\n : await this.sessions.listSessions();\n const maxSessions = toInt(limit, DEFAULT_LIMIT);\n const maxMessages = Math.min(toInt(messageLimit, 0), MAX_MESSAGE_LIMIT);\n const result: Record<string, unknown>[] = [];\n\n for (const summary of summaries) {\n const entry: Record<string, unknown> = {\n key: summary.sessionId,\n sessionId: summary.sessionId,\n agentId: summary.agentId,\n label: sessionLabel(summary),\n createdAt: summary.createdAt,\n updatedAt: summary.updatedAt,\n status: summary.status,\n };\n if (maxMessages > 0) {\n entry.messages = (await this.sessions.listSessionMessages(summary.sessionId))\n .filter((message) => message.role !== \"tool\")\n .slice(-maxMessages)\n .map(sanitizeMessage);\n }\n result.push(entry);\n if (result.length >= maxSessions) break;\n }\n return JSON.stringify({ sessions: result }, null, 2);\n };\n}\n\nexport class SessionsHistoryTool extends Tool {\n constructor(private readonly sessions: NcpSessionManager) {\n super();\n }\n\n get name(): string {\n return \"sessions_history\";\n }\n\n get description(): string {\n return \"Fetch recent messages from a session\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n sessionKey: { type: \"string\", description: \"Session id\" },\n limit: { type: \"integer\", minimum: 1, description: \"Maximum number of messages to return\" },\n includeTools: { type: \"boolean\", description: \"Include tool messages\" },\n },\n required: [\"sessionKey\"],\n };\n }\n\n execute = async (params: Record<string, unknown>): Promise<string> => {\n const { includeTools, limit, sessionKey: rawSessionKey } = params;\n const sessionKey = readString(rawSessionKey);\n if (!sessionKey) return \"Error: sessionKey is required\";\n const session = await this.resolveSession(sessionKey);\n if (!session) return `Error: session '${sessionKey}' not found`;\n const messages = await this.sessions.listSessionMessages(session.sessionId);\n const filtered = includeTools === true ? messages : messages.filter((message) => message.role !== \"tool\");\n return JSON.stringify({\n sessionKey: session.sessionId,\n messages: capHistory(filtered.slice(-toInt(limit, DEFAULT_LIMIT)).map(sanitizeMessage)),\n }, null, 2);\n };\n\n private resolveSession = async (sessionKey: string): Promise<NcpSessionSummary | null> => {\n const exact = await this.sessions.getSession(sessionKey);\n if (exact) return exact;\n const summaries = await this.sessions.listSessions();\n return summaries.find((summary) =>\n summary.sessionId.endsWith(`:${sessionKey}`) || sessionLabel(summary) === sessionKey\n ) ?? null;\n };\n}\n","import type { NcpTool } from \"@nextclaw/ncp\";\nimport {\n DEFAULT_SESSION_SEARCH_LIMIT,\n MAX_SESSION_SEARCH_LIMIT,\n type SessionSearchRequest,\n type SessionSearchResult,\n} from \"@nextclaw/core\";\nimport { normalizeString } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction readOptionalInteger(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return undefined;\n }\n return Math.trunc(value);\n}\n\nfunction readOptionalBoolean(value: unknown): boolean | undefined {\n return typeof value === \"boolean\" ? value : undefined;\n}\n\nexport class SessionSearchTool implements NcpTool {\n readonly name = \"session_search\";\n readonly description =\n \"Search prior sessions by keyword and return structured hits with snippets. Use it to recall earlier discussions before creating new plans or summaries.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"Keyword search query for prior session text or labels.\",\n },\n limit: {\n type: \"integer\",\n minimum: 1,\n maximum: MAX_SESSION_SEARCH_LIMIT,\n description: `Optional max hit count. Defaults to ${DEFAULT_SESSION_SEARCH_LIMIT}.`,\n },\n includeCurrentSession: {\n type: \"boolean\",\n description: \"Set true to include the current session in results. Defaults to false.\",\n },\n },\n required: [\"query\"],\n additionalProperties: false,\n };\n\n constructor(\n private readonly queryService: {\n search: (request: SessionSearchRequest) => Promise<SessionSearchResult>;\n },\n private readonly context: {\n currentSessionId?: string;\n },\n ) {}\n\n validateArgs = (args: Record<string, unknown>): string[] => {\n const issues: string[] = [];\n const query = normalizeString(args.query);\n const limit = readOptionalInteger(args.limit);\n const includeCurrentSession = readOptionalBoolean(args.includeCurrentSession);\n\n if (!query) {\n issues.push(\"query must be a non-empty string.\");\n }\n if (typeof args.limit !== \"undefined\" && typeof limit === \"undefined\") {\n issues.push(\"limit must be a finite integer.\");\n }\n if (typeof limit === \"number\" && (limit < 1 || limit > MAX_SESSION_SEARCH_LIMIT)) {\n issues.push(`limit must be between 1 and ${MAX_SESSION_SEARCH_LIMIT}.`);\n }\n if (\n typeof args.includeCurrentSession !== \"undefined\" &&\n typeof includeCurrentSession === \"undefined\"\n ) {\n issues.push(\"includeCurrentSession must be a boolean.\");\n }\n\n return issues;\n };\n\n execute = async (args: unknown): Promise<unknown> => {\n if (!isRecord(args)) {\n throw new Error(\"session_search requires an object argument.\");\n }\n\n const issues = this.validateArgs(args);\n if (issues.length > 0) {\n throw new Error(issues.join(\" \"));\n }\n\n return this.queryService.search({\n query: normalizeString(args.query) ?? \"\",\n limit: readOptionalInteger(args.limit),\n includeCurrentSession: readOptionalBoolean(args.includeCurrentSession),\n currentSessionId: this.context.currentSessionId,\n });\n };\n}\n","import {\n Tool,\n type SessionRequestNotifyMode,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport type { SessionRequestManager } from \"@kernel/features/session-request/index.js\";\n\nfunction readRequiredString(value: unknown, key: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(`${key} must be a non-empty string.`);\n }\n return value.trim();\n}\n\nfunction readOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\ntype SessionSpawnScope = \"standalone\" | \"child\";\n\nfunction readSpawnScope(value: unknown): SessionSpawnScope {\n const normalized = readOptionalString(value)?.toLowerCase();\n if (!normalized || normalized === \"standalone\") {\n return \"standalone\";\n }\n if (normalized === \"child\") {\n return \"child\";\n }\n throw new Error('scope must be \"standalone\" or \"child\".');\n}\n\nfunction readSpawnNotify(value: unknown): SessionRequestNotifyMode | undefined {\n const notifyMode = readOptionalString(value)?.toLowerCase();\n if (!notifyMode && typeof value === \"undefined\") {\n return undefined;\n }\n if (notifyMode === \"none\" || notifyMode === \"final_reply\") {\n return notifyMode;\n }\n throw new Error('notify must be \"none\" or \"final_reply\".');\n}\n\nexport class SessionSpawnTool extends Tool {\n private sourceSessionId = \"\";\n private sourceSessionMetadata: Record<string, unknown> = {};\n private handoffDepth = 0;\n\n constructor(\n private readonly ncpSessionManager: NcpSessionManager,\n private readonly sessionRequestManager: SessionRequestManager,\n ) {\n super();\n }\n\n get name(): string {\n return \"sessions_spawn\";\n }\n\n get description(): string {\n return \"Create a new session. Use scope=\\\"child\\\" to create a child session of the current flow, and add notify when the new session should start immediately.\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description: \"Seed text used to title the new session. If notify is provided, this same task is also sent as the first request to that new session.\",\n },\n scope: {\n type: \"string\",\n enum: [\"standalone\", \"child\"],\n description: \"Whether the new session should be a standalone thread or a child session of the current session.\",\n },\n title: {\n type: \"string\",\n description: \"Optional explicit session title.\",\n },\n model: {\n type: \"string\",\n description: \"Optional model override for the new session.\",\n },\n runtime: {\n type: \"string\",\n description: \"Optional runtime override for the new session, for example native or codex.\",\n },\n agentId: {\n type: \"string\",\n description: \"Optional target agent id for the new session. Omit to use the default agent.\",\n },\n notify: {\n type: \"string\",\n enum: [\"none\", \"final_reply\"],\n description: \"Optional. Starts the new session immediately. Use \\\"final_reply\\\" to continue this session after the new session reaches its final reply, or \\\"none\\\" to let it run independently.\",\n },\n },\n required: [\"task\"],\n additionalProperties: false,\n };\n }\n\n setContext = (params: {\n sourceSessionId: string;\n sourceSessionMetadata: Record<string, unknown>;\n handoffDepth?: number;\n }): void => {\n this.sourceSessionId = params.sourceSessionId;\n this.sourceSessionMetadata = structuredClone(params.sourceSessionMetadata);\n this.handoffDepth = params.handoffDepth ?? 0;\n };\n\n execute = async (params: Record<string, unknown>, context: ToolExecutionContext): Promise<unknown> => {\n const {\n agentId: rawAgentId,\n model: rawModel,\n notify: rawNotify,\n runtime: rawRuntime,\n scope: rawScope,\n task: rawTask,\n title: rawTitle\n } = params;\n const task = readRequiredString(rawTask, \"task\");\n const scope = readSpawnScope(rawScope);\n const notify = readSpawnNotify(rawNotify);\n const parentSessionId = scope === \"child\" ? this.readParentSessionIdOrThrow() : undefined;\n const { toolCallId, updateToolCallResult } = context;\n\n if (notify) {\n return this.sessionRequestManager.spawnSessionAndRequest({\n sourceSessionId: this.sourceSessionId,\n ...(toolCallId ? { sourceToolCallId: toolCallId } : {}),\n updateToolCallResult,\n sourceSessionMetadata: this.sourceSessionMetadata,\n task,\n title: readOptionalString(rawTitle),\n agentId: readOptionalString(rawAgentId),\n model: readOptionalString(rawModel),\n runtime: readOptionalString(rawRuntime),\n handoffDepth: this.handoffDepth,\n ...(parentSessionId ? { parentSessionId } : {}),\n notify,\n });\n }\n\n const session = await this.ncpSessionManager.createSession({\n sourceSessionId: this.sourceSessionId,\n task,\n title: readOptionalString(rawTitle),\n sourceSessionMetadata: this.sourceSessionMetadata,\n agentId: readOptionalString(rawAgentId),\n model: readOptionalString(rawModel),\n runtime: readOptionalString(rawRuntime),\n ...(parentSessionId ? { parentSessionId } : {}),\n });\n\n return {\n kind: \"nextclaw.session\",\n sessionId: session.sessionId,\n ...(session.agentId ? { agentId: session.agentId } : {}),\n ...(session.parentSessionId ? { parentSessionId: session.parentSessionId } : {}),\n isChildSession: Boolean(session.parentSessionId),\n lifecycle: session.lifecycle,\n title: session.title,\n sessionType: session.sessionType,\n createdAt: session.createdAt,\n };\n };\n\n private readParentSessionIdOrThrow = (): string => {\n const sourceSessionId = this.sourceSessionId.trim();\n if (!sourceSessionId) {\n throw new Error('scope=\"child\" requires an active source session.');\n }\n return sourceSessionId;\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport {\n CronTool,\n EditFileTool,\n ExecTool,\n ExtensionToolAdapter,\n GatewayTool,\n ListDirTool,\n MemoryGetTool,\n MemorySearchTool,\n MessageTool,\n ReadFileTool,\n WebFetchTool,\n WebSearchTool,\n WriteFileTool,\n} from \"@nextclaw/core\";\nimport type {\n ToolRegistrationContext,\n ToolRunContext,\n} from \"@kernel/managers/tool.manager.js\";\nimport { createAssetTools } from \"@kernel/features/native-runtime/index.js\";\nimport { SessionRequestTool } from \"@kernel/tools/session-request.tools.js\";\nimport { SessionsHistoryTool, SessionsListTool } from \"@kernel/tools/session-history.tools.js\";\nimport { SessionSearchTool } from \"@kernel/tools/session-search.tools.js\";\nimport { SessionSpawnTool } from \"@kernel/tools/session-spawn.tools.js\";\nimport { normalizeString } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nfunction readMetadataAccountId(metadata: Record<string, unknown>): string | undefined {\n const candidates = [metadata.accountId, metadata.account_id];\n for (const candidate of candidates) {\n const normalized = normalizeString(candidate);\n if (normalized) {\n return normalized;\n }\n }\n return undefined;\n}\n\nexport class ToolContribution implements KernelContribution {\n private registration: { dispose: () => void } | null = null;\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.registration) {\n return;\n }\n this.registration = this.kernel.toolManager.provideTools({\n id: \"nextclaw-core-tools\",\n registerTools: this.registerTools,\n });\n };\n\n dispose = (): void => {\n this.registration?.dispose();\n this.registration = null;\n };\n\n private registerTools = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n this.registerDefaultTools(context, registry);\n this.registerExtensionTools(context, registry);\n for (const tool of createAssetTools({ assetStore: this.kernel.assetStore })) {\n registry.registerNcpTool(tool);\n }\n for (const tool of this.kernel.mcpManager.listToolsForRun({ agentId: context.agentId })) {\n registry.registerNcpTool(tool);\n }\n this.registerSessionSearchTool(context, registry);\n };\n\n private registerDefaultTools = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n const {\n channel,\n chatId,\n execTimeoutSeconds,\n handoffDepth,\n metadata,\n restrictToWorkspace,\n searchConfig,\n sessionId,\n workspace,\n } = context;\n const allowedDir = restrictToWorkspace ? workspace : undefined;\n registry.registerTool(new ReadFileTool(allowedDir));\n registry.registerTool(new WriteFileTool(allowedDir));\n registry.registerTool(new EditFileTool(allowedDir));\n registry.registerTool(new ListDirTool(allowedDir));\n\n const execTool = new ExecTool({\n workingDir: workspace,\n timeout: execTimeoutSeconds,\n restrictToWorkspace,\n });\n execTool.setContext({\n sessionKey: sessionId,\n channel,\n chatId,\n });\n registry.registerTool(execTool);\n\n registry.registerTool(new WebSearchTool(searchConfig));\n registry.registerTool(new WebFetchTool());\n this.registerMessagingTools({ channel, chatId, metadata }, registry);\n\n const sessionsSpawnTool = new SessionSpawnTool(\n this.kernel.ncpSessionManager,\n this.kernel.sessionRequests,\n );\n sessionsSpawnTool.setContext({\n sourceSessionId: sessionId,\n sourceSessionMetadata: metadata,\n handoffDepth,\n });\n registry.registerTool(sessionsSpawnTool);\n\n const sessionsRequestTool = new SessionRequestTool(this.kernel.sessionRequests);\n sessionsRequestTool.setContext({\n sourceSessionId: sessionId,\n handoffDepth,\n });\n registry.registerTool(sessionsRequestTool);\n\n registry.registerTool(new SessionsListTool(this.kernel.ncpSessionManager));\n registry.registerTool(new SessionsHistoryTool(this.kernel.ncpSessionManager));\n\n registry.registerTool(new MemorySearchTool(workspace));\n registry.registerTool(new MemoryGetTool(workspace));\n\n const gatewayTool = new GatewayTool(this.kernel.getGatewayController());\n gatewayTool.setContext({ sessionKey: sessionId });\n registry.registerTool(gatewayTool);\n };\n\n private registerMessagingTools = (\n context: Pick<ToolRunContext, \"channel\" | \"chatId\" | \"metadata\">,\n registry: ToolRegistrationContext,\n ): void => {\n const { channel, chatId, metadata } = context;\n const accountId = readMetadataAccountId(metadata);\n const messageTool = new MessageTool(\n (message) => this.kernel.messageBus.publishOutbound(message),\n { resolveChannels: this.resolveMessageChannels },\n );\n messageTool.setContext(channel, chatId, accountId ?? null);\n registry.registerTool(messageTool);\n\n const cronTool = new CronTool(this.kernel.automation);\n cronTool.setContext(channel, chatId, accountId ?? null);\n registry.registerTool(cronTool);\n };\n\n private resolveMessageChannels = (): string[] => {\n const extensionRegistry = this.kernel.extensions.getExtensionRegistry();\n const channels = extensionRegistry?.channels ?? [];\n return [...new Set(channels.map((registration) => registration.channel.id.trim()).filter(Boolean))].sort();\n };\n\n private registerExtensionTools = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n const extensionRegistry = this.kernel.extensions.getExtensionRegistry();\n if (!extensionRegistry || extensionRegistry.tools.length === 0) {\n return;\n }\n\n const seen = new Set<string>();\n for (const registration of extensionRegistry.tools) {\n for (const alias of registration.names) {\n if (seen.has(alias) || registry.hasTool(alias)) {\n continue;\n }\n seen.add(alias);\n registry.registerTool(\n new ExtensionToolAdapter({\n registration,\n alias,\n config: context.config,\n workspaceDir: context.workspace,\n contextProvider: registry.getExtensionToolRunContext,\n diagnostics: extensionRegistry.diagnostics,\n }),\n );\n }\n }\n };\n\n private registerSessionSearchTool = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n if (!this.kernel.sessionSearch.isReady()) {\n return;\n }\n registry.registerNcpTool(\n new SessionSearchTool(\n { search: this.kernel.sessionSearch.search },\n { currentSessionId: context.sessionId },\n ),\n );\n };\n}\n","import { AgentManager } from \"@kernel/managers/agent.manager.js\";\nimport { AgentRunRequestManager } from \"@kernel/managers/agent-run-request.manager.js\";\nimport { AgentRuntimeManager } from \"@kernel/managers/agent-runtime.manager.js\";\nimport { AutomationManager } from \"@kernel/managers/automation.manager.js\";\nimport { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { ExtensionManager } from \"@kernel/managers/extension.manager.js\";\nimport { LlmProviderManager } from \"@kernel/managers/llm-provider.manager.js\";\nimport { LlmUsageManager } from \"@kernel/managers/llm-usage.manager.js\";\nimport { McpManager } from \"@kernel/managers/mcp.manager.js\";\nimport { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport { SkillManager } from \"@kernel/managers/skill.manager.js\";\nimport { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport { ToolManager } from \"@kernel/managers/tool.manager.js\";\nimport { NcpAgentSessionJournalStore } from \"@kernel/stores/ncp-agent-session-journal.store.js\";\nimport {\n createAgentRuntimeSessionRequestDispatcher,\n SessionRequestManager,\n} from \"@kernel/features/session-request/index.js\";\nimport { AgentRuntimeContribution } from \"@kernel/contributions/agent-runtime/index.js\";\nimport { LearningLoopContribution } from \"@kernel/contributions/learning-loop/index.js\";\nimport { SessionContextWindowContribution } from \"@kernel/contributions/session-context-window/index.js\";\nimport { SessionActivityPreviewContribution } from \"@kernel/contributions/session-activity-preview/index.js\";\nimport { ToolContribution } from \"@kernel/contributions/tool-contribution/index.js\";\nimport { ContextCompactionManager } from \"@kernel/features/context-compaction/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n ChannelManager,\n ensureDir,\n expandHome,\n type GatewayController,\n getDataDir,\n getSessionsPath,\n getWorkspacePath,\n MessageBus,\n SessionManager,\n SessionSearchManager,\n} from \"@nextclaw/core\";\nimport { EventBus, Ingress } from \"@nextclaw/shared\";\nimport { resolve } from \"node:path\";\n\nexport type NextclawKernelOptions = {\n homeDir?: string;\n configPath?: string;\n};\n\nfunction resolveKernelSessionsDir(options: NextclawKernelOptions): string {\n const homeDir = options.homeDir?.trim();\n if (homeDir) {\n return ensureDir(resolve(expandHome(homeDir), \"sessions\"));\n }\n return getSessionsPath();\n}\n\nfunction resolveKernelAutomationStorePath(options: NextclawKernelOptions): string {\n const homeDir = options.homeDir?.trim();\n if (homeDir) {\n return resolve(expandHome(homeDir), \"cron\", \"jobs.json\");\n }\n return resolve(getDataDir(), \"cron\", \"jobs.json\");\n}\n\ntype NextclawKernelRuntimeControl<\n TGatewayInput,\n TUiInput,\n TStartInput,\n> = {\n gateway: (input: TGatewayInput) => Promise<void>;\n ui: (input: TUiInput) => Promise<void>;\n start: (input: TStartInput) => Promise<void>;\n restart: (input: TStartInput) => Promise<void>;\n serve: (input: TStartInput) => Promise<void>;\n stop: () => Promise<void>;\n};\n\nclass NextclawKernelControlManager<\n TGatewayInput,\n TUiInput,\n TStartInput,\n> {\n private runtimeControl: NextclawKernelRuntimeControl<\n TGatewayInput,\n TUiInput,\n TStartInput\n > | null = null;\n\n installRuntimeControl = (\n runtimeControl: NextclawKernelRuntimeControl<\n TGatewayInput,\n TUiInput,\n TStartInput\n >,\n ) => {\n this.runtimeControl = runtimeControl;\n };\n\n requireRuntimeControl = () => {\n if (!this.runtimeControl) {\n throw new Error(\"Kernel runtime control is not installed.\");\n }\n return this.runtimeControl;\n };\n}\n\nexport class NextclawKernel {\n readonly eventBus: EventBus = new EventBus();\n readonly ingress: Ingress = new Ingress();\n readonly messageBus: MessageBus = new MessageBus();\n readonly llmProviders: LlmProviderManager = new LlmProviderManager();\n readonly llmUsage: LlmUsageManager = new LlmUsageManager();\n readonly configManager: ConfigManager;\n readonly agents: AgentManager;\n readonly sessions: SessionManager;\n readonly control: NextclawKernelControlManager<\n unknown,\n unknown,\n unknown\n >;\n readonly toolManager: ToolManager;\n readonly skills: SkillManager;\n readonly automation: AutomationManager;\n readonly channels: ChannelManager;\n readonly sessionRequests: SessionRequestManager;\n readonly sessionSearch: SessionSearchManager;\n readonly assetStore: LocalAssetStore;\n readonly mcpManager: McpManager;\n readonly ncpSessionManager: NcpSessionManager;\n readonly extensions: ExtensionManager;\n readonly agentRunRequestManager: AgentRunRequestManager;\n readonly sessionRunManager: SessionRunManager;\n readonly agentRuntimeManager: AgentRuntimeManager;\n private readonly ncpAgentSessionJournalStore: NcpAgentSessionJournalStore;\n private readonly contributions: KernelContribution[];\n private gatewayController: GatewayController | undefined;\n\n constructor(options: NextclawKernelOptions = {}) {\n const sessionsDir = resolveKernelSessionsDir(options);\n this.sessions = new SessionManager({\n sessionsDir,\n });\n this.sessionSearch = new SessionSearchManager({\n databasePath: resolve(getDataDir(), \"session-search.db\"),\n sessionsDir,\n });\n this.ncpAgentSessionJournalStore = new NcpAgentSessionJournalStore(\n resolve(sessionsDir, \".ncp-agent-journal\"),\n );\n this.automation = new AutomationManager({\n storePath: resolveKernelAutomationStorePath(options),\n });\n this.assetStore = new LocalAssetStore({\n rootDir: resolve(getDataDir(), \"assets\"),\n });\n this.agents = new AgentManager();\n this.control = new NextclawKernelControlManager<\n unknown,\n unknown,\n unknown\n >();\n this.toolManager = new ToolManager();\n this.channels = new ChannelManager({\n bus: this.messageBus,\n sessionManager: this.sessions,\n });\n this.configManager = new ConfigManager({\n configPath: options.configPath,\n channels: this.channels,\n providerManager: this.llmProviders,\n });\n this.extensions = new ExtensionManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n ingress: this.ingress,\n messageBus: this.messageBus,\n });\n this.skills = new SkillManager({\n workspace: getWorkspacePath(this.configManager.config.agents.defaults.workspace),\n });\n this.mcpManager = new McpManager(this.configManager.loadConfig);\n this.configManager.installRuntimeHooks({\n resolveChannelConfig: this.extensions.toConfigView,\n getExtensionChannels: () => this.extensions.getExtensionRegistry().channels,\n reloadMcp: async ({ config }) => await this.mcpManager.applyConfig(config),\n });\n this.agentRuntimeManager = new AgentRuntimeManager({\n configManager: this.configManager,\n assetStore: this.assetStore,\n });\n this.ncpSessionManager = new NcpSessionManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n journalStore: this.ncpAgentSessionJournalStore,\n sessionSearch: this.sessionSearch,\n });\n this.sessionRequests = new SessionRequestManager({\n ncpSessionManager: this.ncpSessionManager,\n dispatcher: createAgentRuntimeSessionRequestDispatcher({\n eventBus: this.eventBus,\n ingress: this.ingress,\n }),\n });\n this.sessionRunManager = new SessionRunManager({\n agentRuntimeManager: this.agentRuntimeManager,\n eventBus: this.eventBus,\n ncpSessionManager: this.ncpSessionManager,\n });\n this.agentRunRequestManager = new AgentRunRequestManager({\n contextCompactionManager: new ContextCompactionManager({\n configManager: this.configManager,\n providerManager: this.llmProviders,\n sessionRunManager: this.sessionRunManager,\n }),\n ingress: this.ingress,\n ncpSessionManager: this.ncpSessionManager,\n sessionRunManager: this.sessionRunManager,\n });\n this.contributions = [\n new AgentRuntimeContribution(this),\n new ToolContribution(this),\n new SessionActivityPreviewContribution(this),\n new SessionContextWindowContribution(this),\n new LearningLoopContribution(this),\n ];\n }\n\n provideGatewayController = (gatewayController: GatewayController): void => {\n this.gatewayController = gatewayController;\n };\n\n getGatewayController = (): GatewayController | undefined => this.gatewayController;\n\n start = async (): Promise<void> => {\n void this.sessionSearch.start();\n this.mcpManager.start();\n for (const contribution of this.contributions) {\n contribution.start();\n }\n this.agentRunRequestManager.start();\n };\n\n dispose = async (): Promise<void> => {\n await this.agentRunRequestManager.dispose();\n await this.sessionRunManager.dispose();\n this.ncpSessionManager.dispose();\n for (const contribution of this.contributions) {\n contribution.dispose();\n }\n await this.agentRuntimeManager.dispose();\n await this.mcpManager.dispose();\n await this.sessionSearch.dispose();\n };\n\n}\n","import type { InboundAttachment } from \"@nextclaw/core\";\nimport {\n NcpEventType,\n type NcpAgentRunSendOptions,\n type NcpEndpointEvent,\n type NcpMessage,\n type NcpMessagePart,\n type NcpRequestEnvelope,\n} from \"@nextclaw/ncp\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\nimport { extractTextFromNcpMessage } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\ntype AssetApi = {\n put: (input: {\n fileName: string;\n mimeType?: string | null;\n bytes: Uint8Array;\n createdAt?: Date;\n }) => Promise<{ uri: string }>;\n resolveContentPath?: (uri: string) => string | null;\n};\n\nexport type NcpRunnerAgent = {\n run: (\n envelope: NcpRequestEnvelope,\n options?: NcpAgentRunSendOptions,\n ) => AsyncIterable<NcpEndpointEvent>;\n assetApi?: AssetApi;\n};\n\nexport type RunPromptOverNcpParams = {\n agent: NcpRunnerAgent;\n sessionId: string;\n content: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n abortSignal?: AbortSignal;\n onAssistantDelta?: (delta: string) => void;\n onEvent?: (event: NcpEndpointEvent) => void;\n missingCompletedMessageError?: string;\n runErrorMessage?: string;\n};\n\nexport type StreamPromptOverNcpParams = Omit<\n RunPromptOverNcpParams,\n \"onAssistantDelta\" | \"missingCompletedMessageError\" | \"runErrorMessage\"\n>;\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction resolveAttachmentName(attachment: InboundAttachment): string {\n const explicitName = normalizeOptionalString(attachment.name);\n if (explicitName) {\n return explicitName;\n }\n const explicitPath = normalizeOptionalString(attachment.path);\n if (explicitPath) {\n return basename(explicitPath);\n }\n const explicitUrl = normalizeOptionalString(attachment.url);\n if (explicitUrl) {\n try {\n const parsed = new URL(explicitUrl);\n return basename(parsed.pathname) || \"asset.bin\";\n } catch {\n return basename(explicitUrl) || \"asset.bin\";\n }\n }\n return \"asset.bin\";\n}\n\nasync function attachmentToPart(\n attachment: InboundAttachment,\n assetApi?: AssetApi,\n): Promise<NcpMessagePart> {\n const assetUri = normalizeOptionalString(attachment.assetUri);\n if (assetUri) {\n return createFilePartFromAssetUri(attachment, assetUri);\n }\n\n const remoteUrl = normalizeOptionalString(attachment.url);\n const localPath = normalizeOptionalString(attachment.path);\n if (localPath) {\n return await createFilePartFromLocalPath(attachment, localPath, assetApi);\n }\n\n if (remoteUrl) {\n return createFilePartFromRemoteUrl(attachment, remoteUrl);\n }\n\n throw new Error(\n `Unsupported attachment payload for \"${resolveAttachmentName(attachment)}\".`,\n );\n}\n\nfunction createBaseFilePart(attachment: InboundAttachment): {\n name?: string;\n mimeType?: string;\n sizeBytes?: number;\n} {\n return {\n ...(attachment.name ? { name: attachment.name } : {}),\n ...(attachment.mimeType ? { mimeType: attachment.mimeType } : {}),\n ...(typeof attachment.size === \"number\"\n ? { sizeBytes: attachment.size }\n : {}),\n };\n}\n\nfunction createFilePartFromAssetUri(\n attachment: InboundAttachment,\n assetUri: string,\n): NcpMessagePart {\n return {\n type: \"file\",\n assetUri,\n ...createBaseFilePart(attachment),\n };\n}\n\nasync function createFilePartFromLocalPath(\n attachment: InboundAttachment,\n localPath: string,\n assetApi?: AssetApi,\n): Promise<NcpMessagePart> {\n if (!assetApi) {\n throw new Error(\"NCP asset api is unavailable for local attachments.\");\n }\n\n const fileName = resolveAttachmentName(attachment);\n const bytes = await readFile(localPath);\n const stored = await assetApi.put({\n fileName,\n mimeType: attachment.mimeType ?? null,\n bytes,\n });\n return {\n type: \"file\",\n assetUri: stored.uri,\n name: attachment.name ?? fileName,\n ...(attachment.mimeType ? { mimeType: attachment.mimeType } : {}),\n ...(typeof attachment.size === \"number\"\n ? { sizeBytes: attachment.size }\n : {}),\n };\n}\n\nfunction createFilePartFromRemoteUrl(\n attachment: InboundAttachment,\n remoteUrl: string,\n): NcpMessagePart {\n return {\n type: \"file\",\n url: remoteUrl,\n name: attachment.name ?? resolveAttachmentName(attachment),\n ...(attachment.mimeType ? { mimeType: attachment.mimeType } : {}),\n ...(typeof attachment.size === \"number\"\n ? { sizeBytes: attachment.size }\n : {}),\n };\n}\n\nexport async function buildUserMessageParts(params: {\n content: string;\n attachments?: InboundAttachment[];\n assetApi?: AssetApi;\n}): Promise<NcpMessagePart[]> {\n const { assetApi, attachments, content } = params;\n const parts: NcpMessagePart[] = [];\n if (content.length > 0) {\n parts.push({\n type: \"text\",\n text: content,\n });\n }\n\n for (const attachment of attachments ?? []) {\n parts.push(await attachmentToPart(attachment, assetApi));\n }\n\n return parts;\n}\n\nexport async function buildNcpUserMessage(params: {\n sessionId: string;\n content: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n assetApi?: AssetApi;\n}): Promise<NcpMessage> {\n const { assetApi, attachments, content, metadata, sessionId } = params;\n const timestamp = new Date().toISOString();\n return {\n id: `${sessionId}:user:${timestamp}`,\n sessionId,\n role: \"user\",\n status: \"final\",\n timestamp,\n parts: await buildUserMessageParts({\n content,\n attachments,\n assetApi,\n }),\n metadata: structuredClone(metadata ?? {}),\n };\n}\n\nexport async function* streamPromptOverNcp(\n params: StreamPromptOverNcpParams,\n): AsyncGenerator<NcpEndpointEvent> {\n const {\n abortSignal,\n agent,\n attachments,\n content,\n metadata,\n onEvent,\n sessionId,\n } = params;\n const message = await buildNcpUserMessage({\n sessionId,\n content,\n attachments,\n metadata,\n assetApi: agent.assetApi,\n });\n for await (const event of agent.run(\n {\n sessionId,\n message,\n metadata,\n },\n {\n ...(abortSignal ? { signal: abortSignal } : {}),\n },\n )) {\n onEvent?.(event);\n yield event;\n }\n}\n\nexport async function runPromptOverNcp(\n params: RunPromptOverNcpParams,\n): Promise<{\n text: string;\n completedMessage: NcpMessage;\n}> {\n let completedMessage: NcpMessage | undefined;\n\n for await (const event of streamPromptOverNcp(params)) {\n if (event.type === NcpEventType.MessageTextDelta) {\n params.onAssistantDelta?.(event.payload.delta);\n continue;\n }\n\n if (event.type === NcpEventType.MessageFailed) {\n throw new Error(event.payload.error.message);\n }\n\n if (event.type === NcpEventType.RunError) {\n throw new Error(event.payload.error ?? params.runErrorMessage ?? \"NCP run failed.\");\n }\n\n if (event.type === NcpEventType.MessageCompleted) {\n completedMessage = event.payload.message;\n }\n }\n\n if (!completedMessage) {\n throw new Error(\n params.missingCompletedMessageError ?? \"NCP run completed without a final assistant message.\",\n );\n }\n\n return {\n text: extractTextFromNcpMessage(completedMessage),\n completedMessage,\n };\n}\n","import type {\n BaseChannel,\n InboundAttachment,\n InboundMessage,\n} from \"@nextclaw/core\";\nimport type {\n ChatTarget,\n NcpReplyInput,\n} from \"@nextclaw/ncp-toolkit\";\nimport type { NcpEndpointEvent } from \"@nextclaw/ncp\";\nimport { streamPromptOverNcp, type NcpRunnerAgent } from \"./nextclaw-ncp-runner.utils.js\";\n\ntype ReplyCapableChannel = BaseChannel<Record<string, unknown>> & {\n consumeNcpReply(input: NcpReplyInput): Promise<void>;\n};\n\ntype ChannelReplyRoute = {\n target: ChatTarget;\n channel: ReplyCapableChannel;\n};\n\ntype ResolvedInboundRoute = {\n accountId?: string | null;\n};\n\nexport type ChannelReplyRouterDispatchParams = {\n agent: NcpRunnerAgent;\n route: ChannelReplyRoute;\n sessionId: string;\n content: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n abortSignal?: AbortSignal;\n onEvent?: (event: NcpEndpointEvent) => void;\n};\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nexport function isReplyCapableChannel(\n channel: BaseChannel<Record<string, unknown>> | null | undefined,\n): channel is ReplyCapableChannel {\n return (\n Boolean(channel) &&\n typeof (channel as Partial<ReplyCapableChannel>).consumeNcpReply === \"function\"\n );\n}\n\nexport function resolveChannelReplyRoute(params: {\n channel: BaseChannel<Record<string, unknown>> | null | undefined;\n message: InboundMessage;\n route: ResolvedInboundRoute;\n}): ChannelReplyRoute | null {\n const { channel, message, route } = params;\n if (!isReplyCapableChannel(channel)) {\n return null;\n }\n\n const metadata = structuredClone(message.metadata ?? {});\n const accountId =\n readString(route.accountId) ??\n readString(metadata.accountId) ??\n readString(metadata.account_id);\n\n return {\n target: {\n conversationId: message.chatId,\n ...(accountId ? { accountId } : {}),\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n },\n channel,\n };\n}\n\nexport async function dispatchChannelReplyRoute(\n params: ChannelReplyRouterDispatchParams,\n): Promise<void> {\n const {\n abortSignal,\n agent,\n attachments,\n content,\n metadata,\n onEvent,\n route,\n sessionId,\n } = params;\n const input: NcpReplyInput = {\n target: {\n ...route.target,\n ...(agent.assetApi?.resolveContentPath\n ? {\n resolveAssetContentPath:\n agent.assetApi.resolveContentPath,\n }\n : {}),\n },\n eventStream: streamPromptOverNcp({\n agent,\n sessionId,\n content,\n attachments,\n metadata,\n abortSignal,\n onEvent,\n }),\n };\n await route.channel.consumeNcpReply(input);\n}\n","import type { AgentRouteResolver, InboundMessage } from \"@nextclaw/core\";\n\nexport function buildRunMetadata(params: {\n message: Pick<InboundMessage, \"channel\" | \"chatId\" | \"metadata\" | \"senderId\">;\n route: ReturnType<AgentRouteResolver[\"resolveInbound\"]>;\n metadata?: Record<string, unknown>;\n}): Record<string, unknown> {\n const { message, metadata, route } = params;\n return {\n ...(message.metadata ?? {}),\n ...(metadata ?? {}),\n channel: message.channel,\n chatId: message.chatId,\n chat_id: message.chatId,\n accountId: route.accountId,\n account_id: route.accountId,\n agentId: route.agentId,\n agent_id: route.agentId,\n sessionKey: route.sessionKey,\n session_key: route.sessionKey,\n senderId: message.senderId,\n sender_id: message.senderId,\n };\n}\n","import {\n AgentRouteResolver,\n createAssistantStreamDeltaControlMessage,\n createAssistantStreamResetControlMessage,\n createTypingStopControlMessage,\n type ChannelManager,\n type Config,\n type InboundMessage,\n type MessageBus,\n} from \"@nextclaw/core\";\nimport { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport {\n dispatchChannelReplyRoute,\n resolveChannelReplyRoute,\n} from \"@kernel/features/ncp-dispatch/utils/channel-reply.utils.js\";\nimport { buildRunMetadata } from \"@kernel/features/ncp-dispatch/utils/ncp-run-metadata.utils.js\";\nimport {\n runPromptOverNcp,\n type NcpRunnerAgent,\n} from \"@kernel/features/ncp-dispatch/utils/nextclaw-ncp-runner.utils.js\";\n\nexport type GatewayInboundLoopRuntime = {\n kernel: {\n channels: ChannelManager;\n agentRunRequestManager: NcpRunnerAgent;\n };\n messageBus: MessageBus;\n configManager: {\n loadConfig: () => Config;\n };\n appEventBus?: EventBus;\n};\n\ntype GatewayRoute = ReturnType<AgentRouteResolver[\"resolveInbound\"]>;\n\nfunction formatUserFacingError(error: unknown, maxChars = 320): string {\n const raw = error instanceof Error ? error.message || error.name : String(error ?? \"Unknown error\");\n const normalized = raw.replace(/\\s+/g, \" \").trim();\n if (!normalized) {\n return \"Unknown error\";\n }\n return normalized.length <= maxChars\n ? normalized\n : `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;\n}\n\nexport class GatewayInboundProcessor {\n constructor(private runtime: GatewayInboundLoopRuntime) {}\n\n process = async (message: InboundMessage): Promise<void> => {\n try {\n const route = this.resolveRoute(message);\n const runMetadata = buildRunMetadata({\n message,\n route,\n });\n if (await this.dispatchChannelReplyRouteMaybe(message, route, runMetadata)) {\n return;\n }\n if (message.channel !== \"system\") {\n await this.runtime.messageBus.publishOutbound(\n createAssistantStreamResetControlMessage(message),\n );\n }\n const result = await runPromptOverNcp({\n agent: this.runtime.kernel.agentRunRequestManager,\n sessionId: route.sessionKey,\n content: message.content,\n attachments: message.attachments,\n metadata: runMetadata,\n onAssistantDelta:\n message.channel !== \"system\"\n ? (delta) => {\n if (!delta) {\n return;\n }\n void this.runtime.messageBus.publishOutbound(\n createAssistantStreamDeltaControlMessage(message, delta),\n );\n }\n : undefined,\n missingCompletedMessageError: `session \"${route.sessionKey}\" completed without a final assistant message`,\n runErrorMessage: `session \"${route.sessionKey}\" failed`,\n });\n await this.publishLegacyReply(message, route, result);\n } catch (error) {\n await this.runtime.messageBus.publishOutbound({\n channel: message.channel,\n chatId: message.chatId,\n content: `Sorry, I encountered an error: ${formatUserFacingError(error)}`,\n media: [],\n metadata: {},\n });\n }\n };\n\n private resolveRoute = (message: InboundMessage): GatewayRoute => {\n const normalize = (value: unknown) =>\n typeof value === \"string\" ? value.trim() || undefined : undefined;\n return new AgentRouteResolver(this.runtime.configManager.loadConfig()).resolveInbound({\n message,\n forcedAgentId: normalize(message.metadata.target_agent_id),\n sessionKeyOverride: normalize(message.metadata.session_key_override),\n });\n };\n\n private dispatchChannelReplyRouteMaybe = async (\n message: InboundMessage,\n route: GatewayRoute,\n runMetadata: Record<string, unknown>,\n ): Promise<boolean> => {\n if (message.channel === \"system\") {\n return false;\n }\n\n const replyRoute = resolveChannelReplyRoute({\n channel: this.runtime.kernel.channels.getChannel(message.channel),\n message,\n route,\n });\n if (!replyRoute) {\n return false;\n }\n\n await dispatchChannelReplyRoute({\n agent: this.runtime.kernel.agentRunRequestManager,\n route: replyRoute,\n sessionId: route.sessionKey,\n content: message.content,\n attachments: message.attachments,\n metadata: runMetadata,\n });\n return true;\n };\n\n private publishLegacyReply = async (\n message: InboundMessage,\n route: GatewayRoute,\n result: Awaited<ReturnType<typeof runPromptOverNcp>>,\n ): Promise<void> => {\n if (message.channel === \"system\") {\n this.runtime.appEventBus?.emit(eventKeys.sessionUpdated, { sessionKey: route.sessionKey }, {\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n });\n return;\n }\n\n const replyText = result.text.trim();\n if (!replyText) {\n await this.runtime.messageBus.publishOutbound(\n createTypingStopControlMessage(message),\n );\n return;\n }\n\n await this.runtime.messageBus.publishOutbound({\n channel: message.channel,\n chatId: message.chatId,\n content: result.text,\n media: [],\n metadata: buildRunMetadata({\n message,\n route,\n metadata: result.completedMessage.metadata,\n }),\n });\n };\n}\n\nexport async function runGatewayInboundLoop(\n runtime: GatewayInboundLoopRuntime,\n): Promise<void> {\n const processor = new GatewayInboundProcessor(runtime);\n while (true) {\n await processor.process(await runtime.messageBus.consumeInbound());\n }\n}\n","import {\n AgentRouteResolver,\n CommandRegistry,\n parseAgentScopedSessionKey,\n type Config,\n type InboundAttachment,\n type InboundMessage,\n} from \"@nextclaw/core\";\nimport { buildRunMetadata } from \"./ncp-run-metadata.utils.js\";\nimport { runPromptOverNcp, type NcpRunnerAgent } from \"./nextclaw-ncp-runner.utils.js\";\nexport type DirectPromptDispatchParams = {\n config: Config;\n agentRunRequests: NcpRunnerAgent;\n content: string;\n sessionKey?: string;\n channel?: string;\n chatId?: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n agentId?: string;\n abortSignal?: AbortSignal;\n onAssistantDelta?: (delta: string) => void;\n};\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction createDirectInboundMessage(params: {\n content: string;\n channel?: string;\n chatId?: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n}): InboundMessage {\n const { attachments, channel, chatId, content, metadata } = params;\n return {\n channel: channel ?? \"cli\",\n senderId: \"user\",\n chatId: chatId ?? \"direct\",\n content,\n timestamp: new Date(),\n attachments: attachments ?? [],\n metadata: structuredClone(metadata ?? {}),\n };\n}\n\nasync function executeSlashCommandMaybe(params: {\n config: Config;\n rawContent: string;\n channel: string;\n chatId: string;\n sessionKey: string;\n}): Promise<string | null> {\n const { channel, chatId, config, rawContent, sessionKey } = params;\n const trimmed = rawContent.trim();\n if (!trimmed.startsWith(\"/\")) {\n return null;\n }\n const registry = new CommandRegistry(config);\n const result = await registry.executeText(rawContent, {\n channel,\n chatId,\n senderId: \"user\",\n sessionKey,\n });\n return result?.content ?? null;\n}\n\nfunction resolveDirectRoute(params: {\n config: Config;\n content: string;\n sessionKey?: string;\n channel?: string;\n chatId?: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n agentId?: string;\n}): {\n message: InboundMessage;\n route: ReturnType<AgentRouteResolver[\"resolveInbound\"]>;\n} {\n const { agentId, config, sessionKey } = params;\n const message = createDirectInboundMessage(params);\n const forcedAgentId =\n normalizeOptionalString(agentId) ??\n parseAgentScopedSessionKey(sessionKey)?.agentId ??\n undefined;\n const routeResolver = new AgentRouteResolver(config);\n const route = routeResolver.resolveInbound({\n message,\n forcedAgentId,\n sessionKeyOverride: sessionKey,\n });\n return {\n message,\n route,\n };\n}\n\nexport async function dispatchPromptOverNcp(\n params: DirectPromptDispatchParams,\n): Promise<string> {\n const {\n abortSignal,\n agentId,\n attachments,\n channel,\n chatId,\n config,\n content,\n metadata,\n onAssistantDelta,\n agentRunRequests,\n sessionKey,\n } = params;\n const { message, route } = resolveDirectRoute({\n config,\n content,\n sessionKey,\n channel,\n chatId,\n attachments,\n metadata,\n agentId,\n });\n const commandResult = await executeSlashCommandMaybe({\n config,\n rawContent: content,\n channel: message.channel,\n chatId: message.chatId,\n sessionKey: route.sessionKey,\n });\n if (commandResult) {\n return commandResult;\n }\n\n const result = await runPromptOverNcp({\n agent: agentRunRequests,\n sessionId: route.sessionKey,\n content,\n attachments,\n metadata: buildRunMetadata({\n message,\n route,\n }),\n abortSignal,\n onAssistantDelta,\n missingCompletedMessageError: `session \"${route.sessionKey}\" completed without a final assistant message`,\n runErrorMessage: `session \"${route.sessionKey}\" failed`,\n });\n return result.text;\n}\n","import type { SessionMessage } from \"@nextclaw/core\";\nimport { type NcpMessage, type NcpMessagePart, sanitizeAssistantReplyTags } from \"@nextclaw/ncp\";\nimport {\n ensureIsoTimestamp,\n normalizeString,\n} from \"./ncp-message-bridge.utils.js\";\n\ntype LegacyToolCall = {\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n};\n\nfunction tryParseJson(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nfunction toTextPart(text: string): NcpMessagePart | null {\n return text.length > 0 ? { type: \"text\", text } : null;\n}\n\nfunction contentToParts(content: unknown): NcpMessagePart[] {\n if (typeof content === \"string\") {\n const textPart = toTextPart(content);\n return textPart ? [textPart] : [];\n }\n if (Array.isArray(content)) {\n return content.length > 0\n ? [\n {\n type: \"extension\",\n extensionType: \"nextclaw.legacy.content-array\",\n data: structuredClone(content)\n }\n ]\n : [];\n }\n if (content && typeof content === \"object\") {\n return [\n {\n type: \"extension\",\n extensionType: \"nextclaw.legacy.content-object\",\n data: structuredClone(content)\n }\n ];\n }\n return [];\n}\n\nfunction normalizeToolResultPayload(value: unknown): unknown {\n if (typeof value !== \"string\") {\n return structuredClone(value);\n }\n const trimmed = value.trim();\n if (!trimmed) {\n return value;\n }\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return value;\n }\n return tryParseJson(trimmed);\n}\n\nfunction parseLegacyToolCalls(value: unknown): LegacyToolCall[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((entry) => {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n return null;\n }\n const toolCall = entry as Record<string, unknown>;\n const id = normalizeString(toolCall.id);\n const rawFunction = toolCall.function;\n if (!id || !rawFunction || typeof rawFunction !== \"object\" || Array.isArray(rawFunction)) {\n return null;\n }\n const fn = rawFunction as Record<string, unknown>;\n const name = normalizeString(fn.name);\n const args = typeof fn.arguments === \"string\" ? fn.arguments : JSON.stringify(fn.arguments ?? {});\n if (!name) {\n return null;\n }\n return {\n id,\n type: \"function\" as const,\n function: {\n name,\n arguments: args\n }\n };\n })\n .filter((entry): entry is LegacyToolCall => entry !== null);\n}\n\nfunction createMessageId(sessionId: string, index: number, role: string, timestamp: string): string {\n return `${sessionId}:${role.trim().toLowerCase() || \"message\"}:${index}:${timestamp}`;\n}\n\nfunction resolveMessageId(params: {\n sessionId: string;\n index: number;\n role: string;\n timestamp: string;\n message: SessionMessage;\n}): string {\n const { index, message, role, sessionId, timestamp } = params;\n return normalizeString(message.ncp_message_id) ??\n createMessageId(sessionId, index, role, timestamp);\n}\n\nfunction isNcpMessagePart(value: unknown): value is NcpMessagePart {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value) && typeof (value as { type?: unknown }).type === \"string\";\n}\n\nfunction readStoredNcpParts(message: SessionMessage): NcpMessagePart[] | null {\n const rawParts = message.ncp_parts;\n if (!Array.isArray(rawParts)) {\n return null;\n }\n const parts = rawParts.filter((part): part is NcpMessagePart => isNcpMessagePart(part));\n if (parts.length !== rawParts.length) {\n return null;\n }\n return structuredClone(parts);\n}\n\nfunction readStoredNcpMetadata(message: SessionMessage): Record<string, unknown> | undefined {\n const rawMetadata = message.ncp_metadata;\n if (!rawMetadata || typeof rawMetadata !== \"object\" || Array.isArray(rawMetadata)) {\n return undefined;\n }\n return structuredClone(rawMetadata as Record<string, unknown>);\n}\n\nfunction buildAssistantMessage(params: { sessionId: string; index: number; message: SessionMessage }): NcpMessage {\n const { index, message, sessionId } = params;\n const timestamp = ensureIsoTimestamp(message.timestamp, new Date().toISOString());\n const replyTo =\n typeof message.reply_to === \"string\" && message.reply_to.trim().length > 0\n ? message.reply_to.trim()\n : undefined;\n const storedParts = readStoredNcpParts(message);\n if (storedParts) {\n return sanitizeAssistantReplyTags({\n id: resolveMessageId({ index, message, role: \"assistant\", sessionId, timestamp }),\n sessionId,\n role: \"assistant\",\n status: \"final\",\n timestamp,\n parts: storedParts,\n metadata: replyTo ? { reply_to: replyTo } : undefined,\n });\n }\n\n const toolCalls = parseLegacyToolCalls(message.tool_calls);\n const parts: NcpMessagePart[] = [...contentToParts(message.content)];\n if (typeof message.reasoning_content === \"string\") {\n parts.push({\n type: \"reasoning\",\n text: message.reasoning_content\n });\n }\n\n for (const toolCall of toolCalls) {\n parts.push({\n type: \"tool-invocation\",\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n state: \"call\",\n args: tryParseJson(toolCall.function.arguments)\n });\n }\n\n return sanitizeAssistantReplyTags({\n id: resolveMessageId({ index, message, role: \"assistant\", sessionId, timestamp }),\n sessionId,\n role: \"assistant\",\n status: \"final\",\n timestamp,\n parts,\n metadata: replyTo ? { reply_to: replyTo } : undefined,\n });\n}\n\nfunction buildGenericMessage(\n params: { sessionId: string; index: number; role: NcpMessage[\"role\"]; message: SessionMessage },\n): NcpMessage {\n const { index, message, role, sessionId } = params;\n const timestamp = ensureIsoTimestamp(message.timestamp, new Date().toISOString());\n const storedParts = readStoredNcpParts(message);\n const storedMetadata = readStoredNcpMetadata(message);\n if (storedParts) {\n return {\n id: resolveMessageId({ index, message, role, sessionId, timestamp }),\n sessionId,\n role,\n status: \"final\",\n timestamp,\n parts: storedParts,\n ...(storedMetadata ? { metadata: storedMetadata } : {}),\n };\n }\n return {\n id: resolveMessageId({ index, message, role, sessionId, timestamp }),\n sessionId,\n role,\n status: \"final\",\n timestamp,\n parts: contentToParts(message.content),\n ...(storedMetadata ? { metadata: storedMetadata } : {}),\n };\n}\n\nfunction attachToolResult(\n target: NcpMessage,\n toolCallId: string,\n result: unknown,\n toolName?: string,\n resultContentItems?: unknown,\n): NcpMessage {\n const normalizedResult = normalizeToolResultPayload(result);\n const normalizedContentItems = Array.isArray(resultContentItems)\n ? structuredClone(resultContentItems)\n : undefined;\n return {\n ...target,\n parts: target.parts.map((part) => {\n if (part.type !== \"tool-invocation\" || part.toolCallId !== toolCallId) {\n return part;\n }\n const alreadyHasResolvedResult =\n part.state === \"result\" && Object.prototype.hasOwnProperty.call(part, \"result\");\n if (alreadyHasResolvedResult) {\n return {\n ...part,\n ...(toolName ? { toolName } : {}),\n };\n }\n return {\n ...part,\n toolName: toolName ?? part.toolName,\n state: \"result\",\n result: normalizedResult,\n ...(normalizedContentItems ? { resultContentItems: normalizedContentItems } : {})\n };\n }),\n };\n}\n\nexport function toNcpMessages(sessionId: string, messages: SessionMessage[]): NcpMessage[] {\n const ncpMessages: NcpMessage[] = [];\n const assistantIndexByToolCallId = new Map<string, number>();\n\n messages.forEach((message, index) => {\n const role = normalizeString(message.role)?.toLowerCase() ?? \"assistant\";\n if (role === \"tool\") {\n const toolCallId = normalizeString(message.tool_call_id);\n if (toolCallId) {\n const assistantIndex = assistantIndexByToolCallId.get(toolCallId);\n if (assistantIndex !== undefined) {\n ncpMessages[assistantIndex] = attachToolResult(\n ncpMessages[assistantIndex] as NcpMessage,\n toolCallId,\n structuredClone(message.content),\n normalizeString(message.name) ?? undefined,\n message.ncp_tool_result_content_items\n );\n return;\n }\n }\n ncpMessages.push(\n buildGenericMessage({\n sessionId,\n index,\n role: \"tool\",\n message\n })\n );\n return;\n }\n\n if (role === \"assistant\") {\n const assistant = buildAssistantMessage({ sessionId, index, message });\n const assistantPosition = ncpMessages.push(assistant) - 1;\n for (const part of assistant.parts) {\n if (part.type === \"tool-invocation\" && part.toolCallId) {\n assistantIndexByToolCallId.set(part.toolCallId, assistantPosition);\n }\n }\n return;\n }\n\n const normalizedRole = (role === \"system\" || role === \"user\" || role === \"service\" ? role : \"user\") as NcpMessage[\"role\"];\n ncpMessages.push(\n buildGenericMessage({\n sessionId,\n index,\n role: normalizedRole,\n message\n })\n );\n });\n\n return ncpMessages;\n}\n\nexport function resolveLegacyEventType(message: SessionMessage): string {\n const role = normalizeString(message.role)?.toLowerCase() ?? \"\";\n if (role === \"assistant\" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0) {\n return \"assistant.tool_call\";\n }\n if (role === \"tool\") {\n return \"tool.result\";\n }\n if (role === \"assistant\") {\n return \"message.assistant\";\n }\n if (role === \"user\") {\n return \"message.user\";\n }\n if (role === \"system\") {\n return \"message.system\";\n }\n return `message.${role || \"other\"}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["readString","resolveAutoSessionLabel","normalizeString","isRecord","isTextLikePart","readRequestedAgentId","normalizeString","isRecord","isRecord","isRecord","readOptionalString","readString","readString","readRecord","readString","readRecord","readString","readRecord","readRequiredString","isRecord","isRecord","readOptionalString","readString","parseYaml","isRecord","isDurableSessionEvent","readString","isRecord","isRecord","AgentRunRequestManager","AgentRuntimeManager","SessionRunManager","readString","readEventSessionId","readString","fsConstants","DefaultNcpAgentRuntime","STREAM_REFRESH_DELAY_MS","formatBackgroundError","AgentRuntimeManager","SessionRunManager","AgentRunRequestManager","isRecord","readOptionalString","readRequiredString","readOptionalString","readString","normalizeString","readOptionalString","normalizeString","ChannelManager","normalizeOptionalString","normalizeOptionalString","normalizeString"],"sources":["../src/managers/agent.manager.ts","../src/utils/session-run.utils.ts","../src/types/llm-usage.types.ts","../src/stores/llm-usage.store.ts","../src/managers/llm-usage.manager.ts","../src/utils/ncp-message-bridge.utils.ts","../src/features/native-runtime/utils/nextclaw-ncp-current-turn.utils.ts","../src/features/context-compaction/utils/context-compaction-timeline-message.utils.ts","../src/features/context-compaction/utils/context-compaction-projection.utils.ts","../src/features/context-compaction/services/context-compaction-preflight.service.ts","../src/features/context-compaction/managers/context-compaction.manager.ts","../src/features/context-compaction/utils/context-window-event.utils.ts","../src/managers/tool.manager.ts","../src/features/native-runtime/utils/nextclaw-ncp-session-preferences.utils.ts","../src/features/native-runtime/utils/nextclaw-ncp-run-context.utils.ts","../src/features/native-runtime/services/nextclaw-ncp-context-builder.service.ts","../src/features/native-runtime/services/provider-manager-ncp-llm-api.service.ts","../src/features/native-runtime/services/native-agent-runtime-factory.service.ts","../src/features/native-runtime/tools/ncp-asset.tools.ts","../src/managers/agent-run-request.manager.ts","../src/configs/agent-runtime.config.ts","../src/features/runtime-registry/services/agent-runtime-registry.service.ts","../src/managers/agent-runtime.manager.ts","../src/managers/automation.manager.ts","../src/managers/config.manager.ts","../src/features/extension-runtime/services/extension-lifecycle.service.ts","../src/features/extension-runtime/services/extension-manifest-discovery.service.ts","../src/features/extension-runtime/utils/extension-channel-catalog.utils.ts","../src/services/extension-runtime.service.ts","../src/managers/extension.manager.ts","../src/utils/model-message-vision.utils.ts","../src/managers/llm-provider.manager.ts","../src/managers/mcp.manager.ts","../src/utils/ncp-agent-session-journal.utils.ts","../src/managers/ncp-session.manager.ts","../src/utils/skill-frontmatter.utils.ts","../src/managers/skill.manager.ts","../src/managers/session-run.manager.ts","../src/stores/ncp-agent-session-metadata.store.ts","../src/stores/ncp-agent-session-summary-index.store.ts","../src/stores/ncp-agent-session-journal.store.ts","../src/features/session-request/managers/session-request.manager.ts","../src/features/session-request/utils/agent-runtime-session-request-dispatcher.utils.ts","../src/features/agent-run/managers/agent-run-context-compaction.manager.ts","../src/features/agent-run/managers/agent-run-request.manager.ts","../src/features/agent-run/managers/agent-runtime.manager.ts","../src/features/agent-run/managers/context-provider.manager.ts","../src/features/agent-run/managers/session-run.manager.ts","../src/features/agent-run/managers/tool-provider.manager.ts","../src/features/agent-run/repositories/session.repository.ts","../src/features/agent-run/services/agent-run-message-projector.service.ts","../src/features/agent-run/services/agent-run-model-input-budgeter.service.ts","../src/features/agent-run/services/agent-run-model-input-builder.service.ts","../src/features/agent-run/services/ncp-agent-runtime-wrapper.service.ts","../src/features/agent-run/utils/agent-run-request-metadata.utils.ts","../src/features/narp-runtime/services/builtin-narp-runtime-provider.service.ts","../src/contributions/kernel-branch/contributions/agent-run-runtime/index.ts","../src/contributions/kernel-branch/contributions/context-window/index.ts","../src/contributions/kernel-branch/contributions/context-provider/providers/kernel-context.provider.ts","../src/contributions/kernel-branch/contributions/context-provider/index.ts","../src/contributions/kernel-branch/contributions/tool-provider/providers/kernel-tool.provider.ts","../src/contributions/kernel-branch/contributions/tool-provider/index.ts","../src/contributions/kernel-branch/index.ts","../src/contributions/agent-runtime/index.ts","../src/contributions/session-context-window/index.ts","../src/contributions/legacy-agent-run/index.ts","../src/contributions/learning-loop/config.ts","../src/contributions/learning-loop/utils/learning-loop-prompt.utils.ts","../src/contributions/learning-loop/index.ts","../src/contributions/session-activity-preview/utils/session-activity-preview-ncp-event.utils.ts","../src/contributions/session-activity-preview/utils/session-activity-preview-metadata.utils.ts","../src/contributions/session-activity-preview/index.ts","../src/tools/session-request.tools.ts","../src/tools/session-history.tools.ts","../src/tools/session-search.tools.ts","../src/tools/session-spawn.tools.ts","../src/contributions/tool-contribution/index.ts","../src/app/nextclaw-kernel.ts","../src/features/ncp-dispatch/utils/nextclaw-ncp-runner.utils.ts","../src/features/ncp-dispatch/utils/channel-reply.utils.ts","../src/features/ncp-dispatch/utils/ncp-run-metadata.utils.ts","../src/features/ncp-dispatch/services/gateway-inbound-processor.service.ts","../src/features/ncp-dispatch/utils/nextclaw-ncp-dispatch.utils.ts","../src/utils/ncp-session-message-adapter.utils.ts"],"sourcesContent":["import type { AgentRecord } from \"@kernel/types/agent.types.js\";\nimport type { AgentId, SkillId, ToolId } from \"@kernel/types/entity-ids.types.js\";\n\nexport class AgentManager {\n listAgents = () => {\n throw new Error(\"AgentManager.listAgents is not implemented.\");\n };\n\n getAgent = (agentId: AgentId) => {\n void agentId;\n throw new Error(\"AgentManager.getAgent is not implemented.\");\n };\n\n requireAgent = (agentId: AgentId) => {\n void agentId;\n throw new Error(\"AgentManager.requireAgent is not implemented.\");\n };\n\n saveAgent = (agent: AgentRecord) => {\n void agent;\n throw new Error(\"AgentManager.saveAgent is not implemented.\");\n };\n\n removeAgent = (agentId: AgentId) => {\n void agentId;\n throw new Error(\"AgentManager.removeAgent is not implemented.\");\n };\n\n attachSkill = (agentId: AgentId, skillId: SkillId) => {\n void agentId;\n void skillId;\n throw new Error(\"AgentManager.attachSkill is not implemented.\");\n };\n\n detachSkill = (agentId: AgentId, skillId: SkillId) => {\n void agentId;\n void skillId;\n throw new Error(\"AgentManager.detachSkill is not implemented.\");\n };\n\n attachTool = (agentId: AgentId, toolId: ToolId) => {\n void agentId;\n void toolId;\n throw new Error(\"AgentManager.attachTool is not implemented.\");\n };\n\n detachTool = (agentId: AgentId, toolId: ToolId) => {\n void agentId;\n void toolId;\n throw new Error(\"AgentManager.detachTool is not implemented.\");\n };\n}\n","import {\n NcpEventType,\n type NcpAgentConversationStateManager,\n type NcpAgentRuntime,\n type NcpAgentSendEnvelope,\n type NcpEndpointEvent,\n type NcpMessage,\n type NcpRequestEnvelope,\n type NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport type {\n AgentSessionRecord,\n} from \"@nextclaw/ncp-toolkit\";\n\nexport type LiveSessionExecution = {\n runId: string;\n controller: AbortController;\n requestEnvelope: MaterializedAgentRunRequest;\n abortHandled: boolean;\n closed: boolean;\n};\n\nexport type MaterializedAgentRunRequest = NcpRequestEnvelope & {\n runId: string;\n};\n\nexport type LiveSession = {\n sessionId: string;\n agentId?: string;\n stateManager: NcpAgentConversationStateManager;\n runtime: NcpAgentRuntime;\n activeExecution: LiveSessionExecution | null;\n};\n\nexport type PublishSessionEventOptions = {\n dispatchToStateManager?: boolean;\n persistSession?: boolean;\n};\n\nexport class AsyncEventQueue<T> {\n private readonly items: T[] = [];\n private readonly waiters: Array<(value: IteratorResult<T>) => void> = [];\n private closed = false;\n\n push = (item: T): void => {\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter({ value: item, done: false });\n return;\n }\n this.items.push(item);\n };\n\n close = (): void => {\n if (this.closed) {\n return;\n }\n this.closed = true;\n while (this.waiters.length > 0) {\n this.waiters.shift()?.({ value: undefined, done: true });\n }\n };\n\n iterate = (): AsyncGenerator<T> => {\n const nextItem = this.next;\n return (async function* iterateQueuedEvents() {\n while (true) {\n const next = await nextItem();\n if (next.done) {\n return;\n }\n yield next.value;\n }\n })();\n };\n\n private next = async (): Promise<IteratorResult<T>> => {\n const item = this.items.shift();\n if (item) {\n return { value: item, done: false };\n }\n if (this.closed) {\n return { value: undefined, done: true };\n }\n return new Promise((resolve) => {\n this.waiters.push(resolve);\n });\n };\n}\n\nexport function readString(value: unknown): string | undefined {\n const trimmed = typeof value === \"string\" ? value.trim() : \"\";\n return trimmed || undefined;\n}\n\nexport function readAgentId(metadata: Record<string, unknown> | null | undefined): string | undefined {\n return readString(metadata?.agent_id)?.toLowerCase() ?? readString(metadata?.agentId)?.toLowerCase();\n}\n\nexport function readMessageTask(message: NcpAgentSendEnvelope[\"message\"]): string {\n return message.parts.flatMap((part) => (\n (part.type === \"text\" || part.type === \"rich-text\" || part.type === \"reasoning\") &&\n part.text.trim() ? [part.text.trim()] : []\n ))[0] ?? \"Session\";\n}\n\nexport function readMetadataString(\n metadata: Record<string, unknown> | undefined,\n ...keys: string[]\n): string | undefined {\n return keys.map((key) => readString(metadata?.[key])).find(Boolean);\n}\n\nexport function withSession(envelope: NcpAgentSendEnvelope, sessionId: string): NcpRequestEnvelope {\n return { ...envelope, sessionId, message: { ...envelope.message, sessionId } };\n}\n\nexport function isTerminalRunEvent(event: NcpEndpointEvent): boolean {\n return event.type === NcpEventType.MessageCompleted || event.type === NcpEventType.MessageFailed || event.type === NcpEventType.RunError;\n}\n\nfunction readMessages(session: LiveSession): NcpMessage[] {\n const snapshot = session.stateManager.getSnapshot();\n const messages = snapshot.messages.map((message) => structuredClone(message));\n if (snapshot.streamingMessage && !messages.some((message) => message.id === snapshot.streamingMessage?.id)) {\n messages.push(structuredClone(snapshot.streamingMessage));\n }\n return messages;\n}\n\nfunction resolveAutoSessionLabel(messages: readonly NcpMessage[]): string | null {\n for (const message of messages) {\n if (message.role !== \"user\") {\n continue;\n }\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"rich-text\") {\n const text = readString(part.text);\n if (text) {\n return text.length > 64 ? `${text.slice(0, 64)}...` : text;\n }\n }\n }\n }\n return null;\n}\n\nfunction withAutoSessionLabel(params: {\n metadata: Record<string, unknown>;\n messages: readonly NcpMessage[];\n}): Record<string, unknown> {\n const { metadata, messages } = params;\n if (readString(metadata.label)) {\n return metadata;\n }\n const label = resolveAutoSessionLabel(messages);\n return label ? { ...metadata, label } : metadata;\n}\n\nexport function buildSessionRecord(session: LiveSession, updatedAt: string): AgentSessionRecord {\n const messages = readMessages(session);\n const requestMetadata = session.activeExecution?.requestEnvelope.metadata;\n const metadata = withAutoSessionLabel({\n metadata: {\n ...(requestMetadata ? structuredClone(requestMetadata) : {}),\n },\n messages,\n });\n const agentId = readString(session.agentId) ?? readAgentId(metadata);\n return {\n sessionId: session.sessionId,\n ...(agentId ? { agentId } : {}),\n messages,\n createdAt: updatedAt,\n updatedAt,\n metadata,\n };\n}\n\nexport function normalizeRunEvent(\n event: NcpEndpointEvent,\n envelope: NcpRequestEnvelope & { runId?: string },\n): NcpEndpointEvent {\n if (!(\"payload\" in event) || !event.payload || typeof event.payload !== \"object\") {\n return structuredClone(event);\n }\n const shouldAddRunId = Boolean(envelope.runId) &&\n (event.type === NcpEventType.RunStarted ||\n event.type === NcpEventType.RunFinished ||\n event.type === NcpEventType.RunError ||\n event.type === NcpEventType.RunMetadata);\n return structuredClone({\n ...event,\n payload: {\n ...event.payload,\n sessionId:\n \"sessionId\" in event.payload && typeof event.payload.sessionId === \"string\"\n ? event.payload.sessionId\n : envelope.sessionId,\n ...(envelope.correlationId &&\n (!(\"correlationId\" in event.payload) || typeof event.payload.correlationId !== \"string\")\n ? { correlationId: envelope.correlationId }\n : {}),\n ...(shouldAddRunId ? { runId: envelope.runId } : {}),\n },\n } as NcpEndpointEvent);\n}\n\nfunction findFinalAssistantMessage(session: LiveSession, messageId: string): NcpMessage | null {\n const normalizedMessageId = messageId.trim();\n if (!normalizedMessageId) {\n return null;\n }\n const messages = session.stateManager.getSnapshot().messages;\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message?.id === normalizedMessageId && message.role === \"assistant\" && message.status === \"final\") {\n return structuredClone(message);\n }\n }\n return null;\n}\n\nexport function normalizeSendRunEvent(params: {\n session: LiveSession;\n event: NcpEndpointEvent;\n completedMessageSeen: boolean;\n}): {\n eventsToPublish: NcpEndpointEvent[];\n completedMessageSeen: boolean;\n} {\n const { event, session } = params;\n if (event.type === NcpEventType.MessageCompleted) {\n if (params.completedMessageSeen) {\n throw new Error(`Multiple final assistant messages were emitted for session \"${session.sessionId}\".`);\n }\n return { eventsToPublish: [event], completedMessageSeen: true };\n }\n if (event.type === NcpEventType.RunFinished) {\n if (params.completedMessageSeen) {\n return { eventsToPublish: [event], completedMessageSeen: true };\n }\n const messageId = event.payload.messageId?.trim();\n const message = messageId ? findFinalAssistantMessage(session, messageId) : null;\n if (!message) {\n throw new Error(`Run finished without a final assistant message for session \"${session.sessionId}\".`);\n }\n const correlationId = (event.payload as typeof event.payload & { correlationId?: string }).correlationId;\n return {\n eventsToPublish: [\n {\n type: NcpEventType.MessageCompleted,\n payload: {\n sessionId: session.sessionId,\n message,\n ...(correlationId ? { correlationId } : {}),\n },\n },\n event,\n ],\n completedMessageSeen: true,\n };\n }\n return {\n eventsToPublish: [event],\n completedMessageSeen: params.completedMessageSeen,\n };\n}\n\nexport function disposeRuntime(runtime: NcpAgentRuntime): Promise<void> | void {\n return (runtime as { dispose?: () => Promise<void> | void }).dispose?.();\n}\n\nexport function consumeRunHandle(\n events: AsyncIterable<NcpEndpointEvent>,\n fallback: NcpRunHandle,\n): Promise<NcpRunHandle> {\n let resolved = false;\n let handle = fallback;\n return new Promise<NcpRunHandle>((resolve, reject) => {\n const resolveOnce = (): void => {\n if (resolved) {\n return;\n }\n resolved = true;\n resolve(handle);\n };\n void (async () => {\n try {\n for await (const event of events) {\n if (event.type === NcpEventType.RunStarted) {\n handle = {\n ...handle,\n assistantMessageId: event.payload.messageId ?? null,\n runId: event.payload.runId ?? null,\n };\n resolveOnce();\n }\n }\n resolveOnce();\n } catch (error) {\n if (!resolved) {\n reject(error);\n }\n }\n })();\n });\n}\n","export type LlmUsageSummary = {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n cachedTokens: number;\n cacheHit: boolean;\n cacheMetricKeys: string[];\n};\n\nexport type LlmUsageRecord = {\n version: 1;\n observedAt: string;\n source: string;\n model: string | null;\n usage: Record<string, number>;\n summary: LlmUsageSummary;\n};\n\nexport type LlmUsageSnapshot = LlmUsageRecord;\n\nexport function createLlmUsageRecord(params: {\n observedAt?: string;\n source: string;\n model?: string | null;\n usage: Record<string, number>;\n}): LlmUsageRecord {\n const { observedAt, source, model, usage: rawUsage } = params;\n const usage = sanitizeLlmUsage(rawUsage);\n return {\n version: 1,\n observedAt: observedAt ?? new Date().toISOString(),\n source,\n model: normalizeLlmUsageModel(model),\n usage,\n summary: buildLlmUsageSummary(usage),\n };\n}\n\nexport function sanitizeLlmUsage(\n usage: Record<string, number>,\n): Record<string, number> {\n const next: Record<string, number> = {};\n for (const [key, value] of Object.entries(usage)) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n continue;\n }\n next[key] = Math.floor(value);\n }\n return next;\n}\n\nexport function hasLlmUsageTelemetry(usage: Record<string, number>): boolean {\n return Object.keys(usage).length > 0;\n}\n\nexport function buildLlmUsageSummary(\n usage: Record<string, number>,\n): LlmUsageSummary {\n const promptTokens = usage.prompt_tokens ?? usage.input_tokens ?? 0;\n const completionTokens = usage.completion_tokens ?? usage.output_tokens ?? 0;\n const totalTokens = usage.total_tokens ?? (promptTokens + completionTokens);\n const cacheMetricKeys = Object.keys(usage).filter((key) =>\n key.endsWith(\"cached_tokens\")\n );\n const cachedTokens = cacheMetricKeys.reduce(\n (max, key) => Math.max(max, usage[key] ?? 0),\n 0,\n );\n return {\n promptTokens,\n completionTokens,\n totalTokens,\n cachedTokens,\n cacheHit: cachedTokens > 0,\n cacheMetricKeys,\n };\n}\n\nexport function normalizeLlmUsageModel(\n value: string | null | undefined,\n): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n","import { appendFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { getDataDir } from \"@nextclaw/core\";\nimport type { LlmUsageRecord } from \"@kernel/types/llm-usage.types.js\";\n\nexport type LlmUsageStoreOptions = {\n snapshotPath?: string;\n historyPath?: string;\n};\n\nexport class LlmUsageStore {\n constructor(private readonly options: LlmUsageStoreOptions = {}) {}\n\n get snapshotPath(): string {\n return this.options.snapshotPath ?? resolve(getDataDir(), \"run\", \"llm-usage.json\");\n }\n\n get historyPath(): string {\n return this.options.historyPath ?? resolve(getDataDir(), \"logs\", \"llm-usage.jsonl\");\n }\n\n readSnapshot = (): LlmUsageRecord | null => {\n if (!existsSync(this.snapshotPath)) {\n return null;\n }\n try {\n const raw = readFileSync(this.snapshotPath, \"utf-8\");\n return JSON.parse(raw) as LlmUsageRecord;\n } catch {\n return null;\n }\n };\n\n writeSnapshot = (snapshot: LlmUsageRecord): void => {\n mkdirSync(dirname(this.snapshotPath), { recursive: true });\n writeFileSync(this.snapshotPath, JSON.stringify(snapshot, null, 2));\n };\n\n clearSnapshot = (): void => {\n if (existsSync(this.snapshotPath)) {\n rmSync(this.snapshotPath, { force: true });\n }\n };\n\n listHistory = (): LlmUsageRecord[] => {\n if (!existsSync(this.historyPath)) {\n return [];\n }\n try {\n const raw = readFileSync(this.historyPath, \"utf-8\");\n return raw\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .flatMap((line) => {\n try {\n return [JSON.parse(line) as LlmUsageRecord];\n } catch {\n return [];\n }\n });\n } catch {\n return [];\n }\n };\n\n appendHistory = (record: LlmUsageRecord): void => {\n mkdirSync(dirname(this.historyPath), { recursive: true });\n appendFileSync(this.historyPath, `${JSON.stringify(record)}\\n`);\n };\n\n clearHistory = (): void => {\n if (existsSync(this.historyPath)) {\n rmSync(this.historyPath, { force: true });\n }\n };\n}\n","import type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport {\n createLlmUsageRecord,\n hasLlmUsageTelemetry,\n type LlmUsageRecord,\n} from \"@kernel/types/llm-usage.types.js\";\nimport { LlmUsageStore } from \"@kernel/stores/llm-usage.store.js\";\n\ntype ProviderChatParams = Parameters<LlmProviderRuntime[\"chat\"]>[0];\n\nexport type LlmUsageStats = {\n totalRecords: number;\n usageRecordCount: number;\n emptyUsageRecordCount: number;\n promptTokenRecordCount: number;\n oldestObservedAt: string | null;\n latestObservedAt: string | null;\n totalPromptTokens: number;\n totalCompletionTokens: number;\n totalTokens: number;\n totalCachedTokens: number;\n cacheHitRecords: number;\n cacheHitRate: number;\n tokenCacheRate: number;\n sources: Array<{ value: string; count: number }>;\n models: Array<{ value: string; count: number }>;\n};\n\nexport type LlmUsageManagerOptions = {\n store?: LlmUsageStore;\n};\n\nclass ObservedLlmProviderRuntime implements LlmProviderRuntime {\n constructor(\n private readonly delegate: LlmProviderRuntime,\n private readonly manager: LlmUsageManager,\n private readonly source: string,\n ) {}\n\n get = (model?: string | null) => {\n return this.delegate.get(model);\n };\n\n chat = async (params: ProviderChatParams) => {\n const response = await this.delegate.chat(params);\n this.manager.record({\n source: this.source,\n model: params.model ?? null,\n usage: response.usage,\n });\n return response;\n };\n\n chatStream = async function* (\n this: ObservedLlmProviderRuntime,\n params: ProviderChatParams,\n ) {\n for await (const event of this.delegate.chatStream(params)) {\n if (event.type === \"done\") {\n this.manager.record({\n source: this.source,\n model: params.model ?? null,\n usage: event.response.usage,\n });\n }\n yield event;\n }\n };\n}\n\nexport class LlmUsageManager {\n private readonly store: LlmUsageStore;\n\n constructor(options: LlmUsageManagerOptions = {}) {\n this.store = options.store ?? new LlmUsageStore();\n }\n\n get snapshotPath(): string {\n return this.store.snapshotPath;\n }\n\n get historyPath(): string {\n return this.store.historyPath;\n }\n\n observeProviderManager = (\n providerManager: LlmProviderRuntime,\n source: string,\n ): LlmProviderRuntime => {\n return new ObservedLlmProviderRuntime(providerManager, this, source);\n };\n\n record = (params: {\n observedAt?: string;\n source: string;\n model?: string | null;\n usage: Record<string, number>;\n }): LlmUsageRecord | null => {\n const record = createLlmUsageRecord(params);\n if (!hasLlmUsageTelemetry(record.usage)) {\n return null;\n }\n this.store.writeSnapshot(record);\n this.store.appendHistory(record);\n return record;\n };\n\n getSnapshot = (): LlmUsageRecord | null => {\n return this.store.readSnapshot();\n };\n\n getHistory = (limit?: string | number): LlmUsageRecord[] => {\n const records = this.store.listHistory();\n const resolvedLimit = this.resolveHistoryLimit(limit);\n return records.slice(-resolvedLimit).reverse();\n };\n\n resolveHistoryLimit = (value?: string | number): number => {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return Math.floor(value);\n }\n if (typeof value === \"string\" && value.trim().length > 0) {\n const parsed = Number(value);\n if (Number.isFinite(parsed) && parsed > 0) {\n return Math.floor(parsed);\n }\n }\n return 10;\n };\n\n getStats = (): LlmUsageStats => {\n const records = this.store.listHistory();\n const sources = new Map<string, number>();\n const models = new Map<string, number>();\n let totalPromptTokens = 0;\n let totalCompletionTokens = 0;\n let totalTokens = 0;\n let totalCachedTokens = 0;\n let cacheHitRecords = 0;\n let usageRecordCount = 0;\n let promptTokenRecordCount = 0;\n\n for (const record of records) {\n const hasUsage = Object.keys(record.usage).length > 0;\n if (hasUsage) {\n usageRecordCount += 1;\n }\n totalPromptTokens += record.summary.promptTokens;\n totalCompletionTokens += record.summary.completionTokens;\n totalTokens += record.summary.totalTokens;\n totalCachedTokens += record.summary.cachedTokens;\n if (record.summary.promptTokens > 0) {\n promptTokenRecordCount += 1;\n }\n if (record.summary.cacheHit) {\n cacheHitRecords += 1;\n }\n this.bumpCounter(sources, record.source);\n this.bumpCounter(models, record.model ?? \"unknown\");\n }\n\n return {\n totalRecords: records.length,\n usageRecordCount,\n emptyUsageRecordCount: records.length - usageRecordCount,\n promptTokenRecordCount,\n oldestObservedAt: records[0]?.observedAt ?? null,\n latestObservedAt: records.at(-1)?.observedAt ?? null,\n totalPromptTokens,\n totalCompletionTokens,\n totalTokens,\n totalCachedTokens,\n cacheHitRecords,\n cacheHitRate: promptTokenRecordCount > 0 ? cacheHitRecords / promptTokenRecordCount : 0,\n tokenCacheRate: totalPromptTokens > 0 ? totalCachedTokens / totalPromptTokens : 0,\n sources: this.toSortedCounts(sources),\n models: this.toSortedCounts(models),\n };\n };\n\n private readonly bumpCounter = (map: Map<string, number>, value: string): void => {\n map.set(value, (map.get(value) ?? 0) + 1);\n };\n\n private readonly toSortedCounts = (map: Map<string, number>): Array<{ value: string; count: number }> => {\n return [...map.entries()]\n .map(([value, count]) => ({ value, count }))\n .sort((left, right) => {\n if (right.count !== left.count) {\n return right.count - left.count;\n }\n return left.value.localeCompare(right.value);\n });\n };\n}\n","import type { InboundAttachment, SessionMessage } from \"@nextclaw/core\";\nimport { buildNcpUserContent, type LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n type NcpMessage,\n type NcpMessagePart,\n type NcpToolInvocationPart,\n sanitizeAssistantReplyTags,\n} from \"@nextclaw/ncp\";\n\nexport function normalizeString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function cloneMetadata(value: unknown): Record<string, unknown> | undefined {\n return isRecord(value) ? structuredClone(value) : undefined;\n}\n\nexport function readStringArray(value: unknown): string[] | null {\n if (!Array.isArray(value)) {\n return null;\n }\n const deduped = new Set<string>();\n for (const item of value) {\n const normalized = normalizeString(item);\n if (normalized) {\n deduped.add(normalized);\n }\n }\n return [...deduped];\n}\n\nexport function mergeSessionMetadata(\n currentMetadata: Record<string, unknown>,\n inputMetadata?: Record<string, unknown>,\n): Record<string, unknown> {\n if (!inputMetadata) {\n return currentMetadata;\n }\n\n const nextMetadata = {\n ...currentMetadata,\n ...structuredClone(inputMetadata),\n };\n const model =\n normalizeString(inputMetadata.model) ??\n normalizeString(inputMetadata.preferred_model) ??\n normalizeString(inputMetadata.preferredModel);\n if (model) {\n nextMetadata.model = model;\n nextMetadata.preferred_model = model;\n }\n\n const thinking =\n normalizeString(inputMetadata.thinking) ??\n normalizeString(inputMetadata.preferred_thinking) ??\n normalizeString(inputMetadata.thinking_level) ??\n normalizeString(inputMetadata.thinkingLevel);\n if (thinking) {\n nextMetadata.thinking = thinking;\n nextMetadata.preferred_thinking = thinking;\n }\n\n const sessionType =\n normalizeString(inputMetadata.session_type) ?? normalizeString(inputMetadata.sessionType);\n if (sessionType) {\n nextMetadata.session_type = sessionType;\n }\n\n const label =\n normalizeString(inputMetadata.label) ?? normalizeString(inputMetadata.session_label);\n if (label) {\n nextMetadata.label = label;\n }\n\n const requestedSkills =\n readStringArray(inputMetadata.requested_skills) ??\n readStringArray(inputMetadata.requestedSkills);\n if (requestedSkills) {\n nextMetadata.requested_skills = requestedSkills;\n }\n\n return nextMetadata;\n}\n\nexport function extractMessageMetadata(messages: NcpMessage[]): Record<string, unknown> | undefined {\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index];\n if (message?.role !== \"user\") {\n continue;\n }\n const metadata = cloneMetadata(message.metadata);\n if (metadata) {\n return metadata;\n }\n }\n return undefined;\n}\n\nexport function ensureIsoTimestamp(value: unknown, fallback: string): string {\n if (typeof value !== \"string\") {\n return fallback;\n }\n const timestamp = Date.parse(value);\n if (!Number.isFinite(timestamp)) {\n return fallback;\n }\n return new Date(timestamp).toISOString();\n}\n\nfunction serializeToolArgs(args: unknown): string {\n if (typeof args === \"string\") {\n return args;\n }\n return JSON.stringify(args ?? {});\n}\n\nfunction serializeLegacyContent(parts: NcpMessagePart[]): unknown {\n const text = parts\n .filter(isTextLikePart)\n .map((part) => part.text)\n .join(\"\");\n if (text.length > 0) {\n return text;\n }\n if (parts.length === 0) {\n return \"\";\n }\n return structuredClone(parts);\n}\n\nexport function extractTextFromNcpMessage(message: NcpMessage | undefined): string {\n if (!message) {\n return \"\";\n }\n const normalizedMessage = message.role === \"assistant\" ? sanitizeAssistantReplyTags(message) : message;\n return normalizedMessage.parts\n .filter(isTextLikePart)\n .map((part) => part.text)\n .join(\"\");\n}\n\nfunction isTextLikePart(part: NcpMessagePart): part is Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }> {\n return part.type === \"text\" || part.type === \"rich-text\";\n}\n\nfunction guessImageMime(pathOrUrl: string | null): string | null {\n if (!pathOrUrl) {\n return null;\n }\n const normalized = pathOrUrl.trim().toLowerCase();\n if (normalized.endsWith(\".png\")) return \"image/png\";\n if (normalized.endsWith(\".jpg\") || normalized.endsWith(\".jpeg\")) return \"image/jpeg\";\n if (normalized.endsWith(\".gif\")) return \"image/gif\";\n if (normalized.endsWith(\".webp\")) return \"image/webp\";\n if (normalized.endsWith(\".bmp\")) return \"image/bmp\";\n if (normalized.endsWith(\".tif\") || normalized.endsWith(\".tiff\")) return \"image/tiff\";\n return null;\n}\n\nfunction isRenderableImageFilePart(part: NcpMessagePart): part is Extract<NcpMessagePart, { type: \"file\" }> {\n if (part.type !== \"file\") {\n return false;\n }\n const mimeType = normalizeString(part.mimeType);\n if (mimeType?.startsWith(\"image/\")) {\n return true;\n }\n return Boolean(guessImageMime(normalizeString(part.url) ?? normalizeString(part.name)));\n}\n\nfunction resolveImageUrl(part: Extract<NcpMessagePart, { type: \"file\" }>): string | null {\n const url = normalizeString(part.url);\n if (url) {\n return url;\n }\n const mimeType = normalizeString(part.mimeType);\n const contentBase64 = normalizeString(part.contentBase64);\n if (!mimeType || !contentBase64) {\n return null;\n }\n return `data:${mimeType};base64,${contentBase64}`;\n}\n\ntype LegacyContentBuildOptions = {\n assetStore?: LocalAssetStore | null;\n serviceRole?: \"service\" | \"system\";\n};\n\nexport function buildLegacyUserContent(\n parts: NcpMessagePart[],\n options: LegacyContentBuildOptions = {},\n): unknown {\n const content = buildNcpUserContent(parts, {\n assetStore: options.assetStore,\n });\n if (content === \"\") {\n return serializeLegacyContent(parts);\n }\n return content;\n}\n\nexport function extractAttachmentsFromNcpMessage(message: NcpMessage | undefined): InboundAttachment[] {\n if (!message) {\n return [];\n }\n\n const attachments: InboundAttachment[] = [];\n for (const part of message.parts) {\n if (!isRenderableImageFilePart(part)) {\n continue;\n }\n const imageUrl = resolveImageUrl(part);\n if (!imageUrl) {\n continue;\n }\n attachments.push({\n name: normalizeString(part.name) ?? undefined,\n url: imageUrl,\n mimeType: normalizeString(part.mimeType) ?? guessImageMime(normalizeString(part.url) ?? normalizeString(part.name)) ?? undefined,\n size: typeof part.sizeBytes === \"number\" ? part.sizeBytes : undefined,\n source: \"ncp\",\n status: \"remote-only\",\n });\n }\n return attachments;\n}\n\nfunction buildLegacyAssistantMessages(message: NcpMessage, timestamp: string): SessionMessage[] {\n const textContent = extractTextFromNcpMessage(message);\n const reasoningParts = message.parts.filter(\n (part): part is Extract<NcpMessagePart, { type: \"reasoning\" }> => part.type === \"reasoning\"\n );\n const reasoningContent = reasoningParts.map((part) => part.text).join(\"\");\n const toolInvocations = message.parts.filter(\n (part): part is NcpToolInvocationPart => part.type === \"tool-invocation\"\n );\n\n const assistantMessage: SessionMessage = {\n role: \"assistant\",\n content: textContent,\n timestamp,\n ncp_message_id: message.id,\n ncp_parts: structuredClone(message.parts),\n };\n if (typeof message.metadata?.reply_to === \"string\" && message.metadata.reply_to.trim().length > 0) {\n assistantMessage.reply_to = message.metadata.reply_to.trim();\n }\n if (reasoningParts.length > 0) {\n assistantMessage.reasoning_content = reasoningContent;\n }\n if (toolInvocations.length > 0) {\n assistantMessage.tool_calls = toolInvocations.map((toolInvocation, index) => ({\n id: toolInvocation.toolCallId ?? `${message.id}:tool:${index}`,\n type: \"function\",\n function: {\n name: toolInvocation.toolName,\n arguments: serializeToolArgs(toolInvocation.args),\n },\n }));\n }\n\n const messages: SessionMessage[] = [assistantMessage];\n for (const toolInvocation of toolInvocations) {\n if (toolInvocation.state !== \"result\") {\n continue;\n }\n messages.push({\n role: \"tool\",\n name: toolInvocation.toolName,\n tool_call_id: toolInvocation.toolCallId,\n content:\n typeof toolInvocation.result === \"string\"\n ? toolInvocation.result\n : JSON.stringify(toolInvocation.result ?? null),\n ...(toolInvocation.resultContentItems\n ? { ncp_tool_result_content_items: structuredClone(toolInvocation.resultContentItems) }\n : {}),\n timestamp,\n ncp_message_id: message.id,\n });\n }\n return messages;\n}\n\nfunction buildLegacyNonAssistantMessage(\n message: NcpMessage,\n timestamp: string,\n options: LegacyContentBuildOptions,\n): SessionMessage {\n const role = message.role === \"service\" && options.serviceRole === \"system\" ? \"system\" : message.role;\n return {\n role,\n content: buildLegacyUserContent(message.parts, options),\n timestamp,\n ncp_message_id: message.id,\n ncp_parts: structuredClone(message.parts),\n ...(message.metadata ? { ncp_metadata: structuredClone(message.metadata) } : {}),\n };\n}\n\nexport function toLegacyMessages(\n messages: NcpMessage[],\n options: LegacyContentBuildOptions = {},\n): SessionMessage[] {\n const legacyMessages: SessionMessage[] = [];\n\n for (const rawMessage of messages) {\n const message = rawMessage.role === \"assistant\" ? sanitizeAssistantReplyTags(rawMessage) : rawMessage;\n const timestamp = ensureIsoTimestamp(message.timestamp, new Date().toISOString());\n\n if (message.role === \"assistant\") {\n legacyMessages.push(...buildLegacyAssistantMessages(message, timestamp));\n continue;\n }\n\n legacyMessages.push(buildLegacyNonAssistantMessage(message, timestamp, options));\n }\n\n return legacyMessages;\n}\n","import type { NcpAgentRunInput, NcpMessage, NcpMessagePart } from \"@nextclaw/ncp\";\nimport type { LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n buildLegacyUserContent,\n ensureIsoTimestamp,\n extractTextFromNcpMessage,\n} from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nfunction isTextLikePart(part: NcpMessagePart): part is Extract<NcpMessagePart, { type: \"text\" | \"rich-text\" }> {\n return part.type === \"text\" || part.type === \"rich-text\";\n}\n\nfunction collectTextPartIndexes(parts: NcpMessagePart[]): number[] {\n return parts\n .map((part, index) => (isTextLikePart(part) ? index : -1))\n .filter((index) => index >= 0);\n}\n\nfunction replaceTextPartsWithSingleFormattedText(\n parts: NcpMessagePart[],\n textPartIndexes: number[],\n formattedText: string,\n): NcpMessagePart[] {\n const nextParts = structuredClone(parts);\n const firstTextIndex = textPartIndexes[0];\n const firstTextPart = nextParts[firstTextIndex];\n if (firstTextPart && isTextLikePart(firstTextPart)) {\n firstTextPart.text = formattedText;\n }\n\n return nextParts.filter((part, index) => {\n if (!isTextLikePart(part)) {\n return true;\n }\n return index === firstTextIndex && part.text.length > 0;\n });\n}\n\nfunction wrapTextPartsWithFormattedEdges(params: {\n parts: NcpMessagePart[];\n textPartIndexes: number[];\n prefix: string;\n suffix: string;\n}): NcpMessagePart[] {\n const { parts, prefix, suffix, textPartIndexes } = params;\n const nextParts = structuredClone(parts);\n const firstTextIndex = textPartIndexes[0];\n const lastTextIndex = textPartIndexes[textPartIndexes.length - 1];\n\n for (const index of textPartIndexes) {\n const part = nextParts[index];\n if (!part || !isTextLikePart(part)) {\n continue;\n }\n if (index === firstTextIndex) {\n part.text = `${prefix}${part.text}`;\n }\n if (index === lastTextIndex) {\n part.text = `${part.text}${suffix}`;\n }\n }\n\n return nextParts;\n}\n\nfunction buildFormattedCurrentParts(params: {\n message: NcpMessage | undefined;\n formattedText: string;\n originalText: string;\n}): NcpMessagePart[] {\n const { formattedText, message, originalText } = params;\n const parts = message?.parts ?? [];\n if (parts.length === 0) {\n return formattedText.length > 0 ? [{ type: \"text\", text: formattedText }] : [];\n }\n\n const textPartIndexes = collectTextPartIndexes(parts);\n if (textPartIndexes.length === 0) {\n return formattedText.length > 0\n ? [{ type: \"text\", text: formattedText }, ...structuredClone(parts)]\n : structuredClone(parts);\n }\n\n if (formattedText === originalText) {\n return structuredClone(parts);\n }\n\n const originalTextIndex = formattedText.indexOf(originalText);\n if (originalText.length === 0 || originalTextIndex < 0) {\n return replaceTextPartsWithSingleFormattedText(parts, textPartIndexes, formattedText);\n }\n\n return wrapTextPartsWithFormattedEdges({\n parts,\n textPartIndexes,\n prefix: formattedText.slice(0, originalTextIndex),\n suffix: formattedText.slice(originalTextIndex + originalText.length),\n });\n}\n\nexport function findLatestUserMessage(input: NcpAgentRunInput): NcpMessage | undefined {\n return (\n input.messages\n .slice()\n .reverse()\n .find((message) => message.role === \"user\") ??\n input.messages[input.messages.length - 1]\n );\n}\n\nexport function buildCurrentTurnState(params: {\n input: NcpAgentRunInput;\n currentModel: string;\n formatPrompt: (params: { text: string; timestamp: Date }) => string;\n assetStore?: LocalAssetStore | null;\n}): {\n currentRole: \"user\" | \"system\";\n currentUserContent: unknown;\n effectiveModel: string;\n} {\n const { assetStore, currentModel, formatPrompt, input } = params;\n const latestUserMessage = findLatestUserMessage(input);\n const originalText = extractTextFromNcpMessage(latestUserMessage);\n const formattedText = formatPrompt({\n text: originalText,\n timestamp: new Date(\n ensureIsoTimestamp(\n latestUserMessage?.timestamp,\n new Date().toISOString(),\n ),\n ),\n });\n const currentParts = buildFormattedCurrentParts({\n message: latestUserMessage,\n formattedText,\n originalText,\n });\n\n return {\n currentRole: latestUserMessage?.role === \"system\" ? \"system\" : \"user\",\n currentUserContent: buildLegacyUserContent(currentParts, {\n assetStore,\n }),\n effectiveModel: currentModel,\n };\n}\n","import type { Session, SessionEvent, SessionMessage } from \"@nextclaw/core\";\nimport type { NcpMessage } from \"@nextclaw/ncp\";\n\nexport const NEXTCLAW_TIMELINE_KIND_METADATA_KEY = \"nextclaw_timeline_kind\";\nexport const CONTEXT_COMPACTION_TIMELINE_KIND = \"context_compaction\";\n\nexport type ContextCompactionTimelineCheckpoint = {\n version: 1;\n id: string;\n status: \"compressing\" | \"compressed\";\n summary: string;\n coveredMessageCount: number;\n coveredSessionMessageCount: number;\n originalEstimatedTokens: number;\n projectedEstimatedTokens: number;\n createdAt: string;\n updatedAt: string;\n};\n\ntype ContextCompactionTimelineMetadata = {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: typeof CONTEXT_COMPACTION_TIMELINE_KIND;\n checkpoint: ContextCompactionTimelineCheckpoint;\n};\n\nfunction readTimelineMetadata(message: SessionMessage | null | undefined): ContextCompactionTimelineMetadata | null {\n const rawMetadata = message?.ncp_metadata;\n if (!rawMetadata || typeof rawMetadata !== \"object\" || Array.isArray(rawMetadata)) {\n return null;\n }\n const metadata = rawMetadata as Record<string, unknown>;\n if (metadata[NEXTCLAW_TIMELINE_KIND_METADATA_KEY] !== CONTEXT_COMPACTION_TIMELINE_KIND) {\n return null;\n }\n const checkpoint =\n metadata.checkpoint && typeof metadata.checkpoint === \"object\" && !Array.isArray(metadata.checkpoint)\n ? (metadata.checkpoint as ContextCompactionTimelineCheckpoint)\n : null;\n if (!checkpoint) {\n return null;\n }\n return {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: CONTEXT_COMPACTION_TIMELINE_KIND,\n checkpoint,\n };\n}\n\nfunction buildTimelineMessage(checkpoint: ContextCompactionTimelineCheckpoint): SessionMessage {\n return {\n role: \"service\",\n content:\n checkpoint.status === \"compressing\"\n ? \"正在压缩较早上下文\"\n : \"较早上下文已自动压缩\",\n timestamp: checkpoint.updatedAt,\n ncp_parts: [\n {\n type: \"text\",\n text:\n checkpoint.status === \"compressing\"\n ? \"正在压缩较早上下文\"\n : \"较早上下文已自动压缩\",\n },\n ],\n ncp_metadata: {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: CONTEXT_COMPACTION_TIMELINE_KIND,\n checkpoint,\n },\n };\n}\n\nexport function buildContextCompactionTimelineNcpMessage(params: {\n sessionId: string;\n checkpoint: ContextCompactionTimelineCheckpoint;\n}): NcpMessage {\n const { checkpoint, sessionId } = params;\n const text =\n checkpoint.status === \"compressing\"\n ? \"正在压缩较早上下文\"\n : \"较早上下文已自动压缩\";\n return {\n id: `${sessionId}:service:context-compaction:${checkpoint.id}`,\n sessionId,\n role: \"service\",\n status: \"final\",\n timestamp: checkpoint.updatedAt,\n parts: [{ type: \"text\", text }],\n metadata: {\n [NEXTCLAW_TIMELINE_KIND_METADATA_KEY]: CONTEXT_COMPACTION_TIMELINE_KIND,\n checkpoint,\n },\n };\n}\n\nexport function upsertContextCompactionTimelineMessage(params: {\n session: Session;\n checkpoint: ContextCompactionTimelineCheckpoint;\n insertBeforeMessageIds?: readonly string[];\n}): void {\n const { checkpoint, insertBeforeMessageIds = [], session } = params;\n const nextMessage = buildTimelineMessage(checkpoint);\n for (let index = session.events.length - 1; index >= 0; index -= 1) {\n const event = session.events[index];\n const message =\n event?.data?.message && typeof event.data.message === \"object\" && !Array.isArray(event.data.message)\n ? (event.data.message as SessionMessage)\n : null;\n const metadata = readTimelineMetadata(message);\n if (!metadata) {\n continue;\n }\n event.timestamp = checkpoint.updatedAt;\n event.data.message = nextMessage;\n session.messages = session.messages.map((item) => {\n const itemMetadata = readTimelineMetadata(item);\n return itemMetadata?.checkpoint.id === metadata.checkpoint.id ? nextMessage : item;\n });\n session.updatedAt = new Date(checkpoint.updatedAt);\n return;\n }\n\n const event: SessionEvent = {\n seq: session.nextSeq,\n type: \"message.service\",\n timestamp: checkpoint.updatedAt,\n data: {\n message: nextMessage,\n },\n };\n session.nextSeq += 1;\n const insertionIds = new Set(insertBeforeMessageIds);\n const messageIndex = session.messages.findIndex(\n (message) => typeof message.ncp_message_id === \"string\" && insertionIds.has(message.ncp_message_id),\n );\n if (messageIndex >= 0) {\n session.messages.splice(messageIndex, 0, nextMessage);\n } else {\n session.messages.push(nextMessage);\n }\n const eventIndex = session.events.findIndex((candidateEvent) => {\n const message =\n candidateEvent?.data?.message && typeof candidateEvent.data.message === \"object\" && !Array.isArray(candidateEvent.data.message)\n ? (candidateEvent.data.message as SessionMessage)\n : null;\n return typeof message?.ncp_message_id === \"string\" && insertionIds.has(message.ncp_message_id);\n });\n if (eventIndex >= 0) {\n session.events.splice(eventIndex, 0, event);\n } else {\n session.events.push(event);\n }\n session.updatedAt = new Date(checkpoint.updatedAt);\n}\n\nexport function isContextCompactionTimelineMessage(message: { metadata?: Record<string, unknown> | undefined } | null | undefined): boolean {\n return message?.metadata?.[NEXTCLAW_TIMELINE_KIND_METADATA_KEY] === CONTEXT_COMPACTION_TIMELINE_KIND;\n}\n","import type { NcpMessage } from \"@nextclaw/ncp\";\nimport { readCompressedContextCompactionCheckpoint } from \"@nextclaw/core\";\nimport { CONTEXT_COMPACTION_TIMELINE_KIND, NEXTCLAW_TIMELINE_KIND_METADATA_KEY } from \"./context-compaction-timeline-message.utils.js\";\n\nfunction readCompactionSummary(message: NcpMessage): string | null {\n const metadata = message.metadata;\n if (metadata?.[NEXTCLAW_TIMELINE_KIND_METADATA_KEY] !== CONTEXT_COMPACTION_TIMELINE_KIND) {\n return null;\n }\n const checkpoint = readCompressedContextCompactionCheckpoint(metadata.checkpoint);\n return checkpoint?.summary ?? null;\n}\n\nexport function projectNcpMessagesWithContextCompaction(params: {\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n}): NcpMessage[] {\n const { sessionId, sessionMessages } = params;\n let checkpointIndex = -1;\n let summary = \"\";\n for (let index = sessionMessages.length - 1; index >= 0; index -= 1) {\n const candidateSummary = readCompactionSummary(sessionMessages[index] as NcpMessage);\n if (!candidateSummary) {\n continue;\n }\n checkpointIndex = index;\n summary = candidateSummary;\n break;\n }\n\n if (checkpointIndex < 0) {\n return sessionMessages\n .filter((message) => !readCompactionSummary(message))\n .map((message) => structuredClone(message));\n }\n\n return [\n {\n id: `${sessionId}:context-compaction-summary:${sessionMessages[checkpointIndex]?.id ?? \"latest\"}`,\n sessionId,\n role: \"user\",\n status: \"final\",\n timestamp: sessionMessages[checkpointIndex]?.timestamp ?? new Date().toISOString(),\n parts: [{ type: \"text\", text: summary }],\n },\n ...sessionMessages\n .slice(checkpointIndex + 1)\n .filter((message) => !readCompactionSummary(message))\n .map((message) => structuredClone(message)),\n ];\n}\n","import {\n CONTEXT_COMPACTION_METADATA_KEY,\n ContextCompactionService,\n ContextWindowBudgetService,\n buildCompressingCompactionCheckpoint,\n buildContextWindowSnapshot,\n findEffectiveAgentProfile,\n readCompressedContextCompactionCheckpoint,\n resolveDefaultAgentProfileId,\n type Config,\n type ContextCompactionCheckpoint,\n type ContextCompactionPlan,\n type ContextWindowBudgetEvaluation,\n type ContextWindowSnapshot,\n} from \"@nextclaw/core\";\nimport type { NcpMessage } from \"@nextclaw/ncp\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport {\n normalizeString,\n toLegacyMessages,\n} from \"@kernel/utils/ncp-message-bridge.utils.js\";\nimport { projectNcpMessagesWithContextCompaction } from \"@kernel/features/context-compaction/utils/context-compaction-projection.utils.js\";\nimport {\n buildContextCompactionTimelineNcpMessage,\n isContextCompactionTimelineMessage,\n} from \"@kernel/features/context-compaction/utils/context-compaction-timeline-message.utils.js\";\n\nexport type ContextCompactionPreflightResult = {\n contextWindow: ContextWindowSnapshot;\n metadataPatch: Record<string, unknown>;\n sessionMessages: NcpMessage[];\n timelineMessage: NcpMessage | null;\n};\n\nexport type ContextCompactionPreflightBeginResult = ContextCompactionPreflightResult & {\n pendingCompaction: ContextCompactionPendingWork | null;\n};\n\ntype ContextCompactionPendingWork = {\n checkpoint: ReturnType<typeof buildCompressingCompactionCheckpoint>;\n contextTokens: number;\n model: string;\n plan: ContextCompactionPlan;\n reservedContextTokens: number;\n sessionId: string;\n sessionMessages: NcpMessage[];\n};\n\ntype ResolvedCompactionProfile = {\n contextTokens: number;\n model: string;\n reservedContextTokens: number;\n};\n\nconst SUMMARY_MAX_TOKENS = 4000;\nconst SUMMARY_SOURCE_MAX_CHARS = 120_000;\n\nfunction readRequestedAgentId(metadata: Record<string, unknown>): string | null {\n return normalizeString(metadata.agent_id)?.toLowerCase() ?? normalizeString(metadata.agentId)?.toLowerCase() ?? null;\n}\n\nfunction resolveCompactionProfile(params: {\n config: Config;\n requestMetadata: Record<string, unknown>;\n storedAgentId?: string;\n}): ResolvedCompactionProfile {\n const { config, requestMetadata, storedAgentId } = params;\n const { defaults } = config.agents;\n const defaultAgentId = resolveDefaultAgentProfileId(config);\n const agentId =\n normalizeString(storedAgentId)?.toLowerCase() ??\n readRequestedAgentId(requestMetadata) ??\n defaultAgentId;\n const profile =\n findEffectiveAgentProfile(config, agentId) ??\n findEffectiveAgentProfile(config, defaultAgentId);\n return {\n contextTokens: profile?.contextTokens ?? defaults.contextTokens,\n model: profile?.model ?? defaults.model,\n reservedContextTokens: ContextWindowBudgetService.resolveReservedContextTokens({\n contextTokens: profile?.contextTokens ?? defaults.contextTokens,\n configuredReservedContextTokens: profile?.reservedContextTokens ?? defaults.reservedContextTokens,\n }),\n };\n}\n\nfunction mergeInputMessages(params: {\n inputMessages: readonly NcpMessage[];\n sessionMessages: readonly NcpMessage[];\n}): NcpMessage[] {\n const messages = params.sessionMessages.map((message) => structuredClone(message));\n const seen = new Set(messages.map((message) => message.id));\n for (const message of params.inputMessages) {\n if (seen.has(message.id)) {\n continue;\n }\n messages.push(structuredClone(message));\n }\n return messages;\n}\n\nfunction stringifyCompactionSource(messages: readonly Record<string, unknown>[]): string {\n const json = JSON.stringify(messages, null, 2);\n if (json.length <= SUMMARY_SOURCE_MAX_CHARS) {\n return json;\n }\n return `${json.slice(0, SUMMARY_SOURCE_MAX_CHARS).trimEnd()}\\n[truncated_source]`;\n}\n\nfunction buildContextWindowSnapshotFromBudget(params: {\n budget: ContextWindowBudgetEvaluation;\n checkpoint: ContextCompactionCheckpoint | null;\n totalContextTokens: number;\n}): ContextWindowSnapshot {\n const { budget, checkpoint, totalContextTokens } = params;\n return buildContextWindowSnapshot({\n usedContextTokens: budget.estimatedTokens,\n totalContextTokens,\n prunedUsedContextTokens: budget.estimatedTokens,\n droppedHistoryCount: budget.droppedHistoryCount,\n truncatedToolResultCount: budget.truncatedToolResultCount,\n truncatedSystemPrompt: budget.truncatedSystemPrompt,\n truncatedUserMessage: budget.truncatedUserMessage,\n checkpoint,\n compactedUsedContextTokens: checkpoint ? budget.estimatedTokens : undefined,\n });\n}\n\nfunction buildContextWindowSnapshotForMessages(\n contextWindowBudgetService: ContextWindowBudgetService,\n params: {\n checkpoint: ReturnType<typeof readCompressedContextCompactionCheckpoint>;\n contextTokens: number;\n reservedContextTokens: number;\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n },\n): ContextWindowSnapshot {\n const { checkpoint, contextTokens, reservedContextTokens, sessionId, sessionMessages } = params;\n const modelCandidateMessages = sessionMessages.filter(\n (message) => !isContextCompactionTimelineMessage(message),\n );\n const projectedMessages = checkpoint\n ? projectNcpMessagesWithContextCompaction({\n sessionId,\n sessionMessages,\n })\n : modelCandidateMessages;\n const messages = toLegacyMessages(projectedMessages) as Record<string, unknown>[];\n const budget = contextWindowBudgetService.evaluate({\n messages,\n contextTokens,\n reservedContextTokens,\n });\n return buildContextWindowSnapshotFromBudget({\n budget,\n checkpoint,\n totalContextTokens: contextTokens,\n });\n}\n\nexport class ContextCompactionPreflightService {\n private readonly compactionService = new ContextCompactionService();\n private readonly contextWindowBudgetService = new ContextWindowBudgetService();\n\n constructor(\n private readonly options: {\n configManager: ConfigManager;\n providerManager?: LlmProviderRuntime;\n },\n ) {}\n\n preview = (params: {\n requestMetadata: Record<string, unknown>;\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n storedAgentId?: string;\n storedMetadata: Record<string, unknown>;\n }): ContextWindowSnapshot | null => {\n const {\n requestMetadata,\n sessionId,\n sessionMessages,\n storedAgentId,\n storedMetadata,\n } = params;\n const profile = resolveCompactionProfile({\n config: this.options.configManager.loadConfig(),\n requestMetadata,\n storedAgentId,\n });\n const existingCheckpoint = readCompressedContextCompactionCheckpoint(\n storedMetadata[CONTEXT_COMPACTION_METADATA_KEY],\n );\n return buildContextWindowSnapshotForMessages(this.contextWindowBudgetService, {\n checkpoint: existingCheckpoint,\n contextTokens: profile.contextTokens,\n reservedContextTokens: profile.reservedContextTokens,\n sessionId,\n sessionMessages,\n });\n };\n\n begin = (params: {\n inputMessages: readonly NcpMessage[];\n requestMetadata: Record<string, unknown>;\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n storedAgentId?: string;\n storedMetadata: Record<string, unknown>;\n }): ContextCompactionPreflightBeginResult => {\n const {\n inputMessages,\n requestMetadata,\n sessionId,\n sessionMessages,\n storedAgentId,\n storedMetadata,\n } = params;\n const profile = resolveCompactionProfile({\n config: this.options.configManager.loadConfig(),\n requestMetadata,\n storedAgentId,\n });\n const { contextTokens, reservedContextTokens } = profile;\n const ncpMessages = mergeInputMessages({\n inputMessages,\n sessionMessages,\n });\n const modelCandidateMessages = ncpMessages.filter(\n (message) => !isContextCompactionTimelineMessage(message),\n );\n const existingCheckpoint = readCompressedContextCompactionCheckpoint(\n storedMetadata[CONTEXT_COMPACTION_METADATA_KEY],\n );\n const projectedMessages = existingCheckpoint\n ? projectNcpMessagesWithContextCompaction({\n sessionId,\n sessionMessages: ncpMessages,\n })\n : modelCandidateMessages;\n const messages = toLegacyMessages(projectedMessages) as Record<string, unknown>[];\n const budget = this.contextWindowBudgetService.evaluate({\n messages,\n contextTokens,\n reservedContextTokens,\n });\n const plan = existingCheckpoint || !budget.shouldCompact\n ? null\n : this.compactionService.prepareForModelInput({\n messages: budget.messages,\n contextTokens,\n compactionThresholdTokens: budget.triggerTokens,\n });\n const checkpoint = plan\n ? {\n ...buildCompressingCompactionCheckpoint(\n storedMetadata[CONTEXT_COMPACTION_METADATA_KEY],\n ),\n coveredMessageCount: plan.coveredMessages.length,\n coveredSessionMessageCount: plan.coveredMessages.length,\n originalEstimatedTokens: plan.originalEstimatedTokens,\n projectedEstimatedTokens: budget.estimatedTokens,\n }\n : existingCheckpoint;\n\n const contextWindow = buildContextWindowSnapshotFromBudget({\n budget,\n checkpoint,\n totalContextTokens: contextTokens,\n });\n return {\n contextWindow,\n metadataPatch: plan && checkpoint\n ? { [CONTEXT_COMPACTION_METADATA_KEY]: checkpoint }\n : {},\n sessionMessages: ncpMessages,\n timelineMessage: plan && checkpoint\n ? buildContextCompactionTimelineNcpMessage({\n sessionId,\n checkpoint,\n })\n : null,\n pendingCompaction: plan && checkpoint\n ? {\n checkpoint,\n contextTokens,\n model: profile.model,\n plan,\n reservedContextTokens,\n sessionId,\n sessionMessages: ncpMessages,\n }\n : null,\n };\n };\n\n finish = async (\n pending: ContextCompactionPendingWork,\n ): Promise<ContextCompactionPreflightResult> => {\n const compacted = await this.compactionService.compactPreparedForModelInput({\n contextTokens: pending.contextTokens,\n plan: pending.plan,\n generateSummary: async ({ messages }) =>\n await this.generateSummary({\n messages,\n model: pending.model,\n }),\n });\n const generatedCheckpoint = compacted.checkpoint;\n if (!generatedCheckpoint) {\n throw new Error(\"context compaction pending work did not produce a checkpoint\");\n }\n const checkpoint = {\n ...generatedCheckpoint,\n id: pending.checkpoint.id,\n createdAt: pending.checkpoint.createdAt,\n status: \"compressed\" as const,\n };\n const budget = this.contextWindowBudgetService.evaluate({\n messages: compacted.messages,\n contextTokens: pending.contextTokens,\n reservedContextTokens: pending.reservedContextTokens,\n });\n const contextWindow = buildContextWindowSnapshotFromBudget({\n budget,\n checkpoint,\n totalContextTokens: pending.contextTokens,\n });\n return {\n contextWindow,\n metadataPatch: {\n [CONTEXT_COMPACTION_METADATA_KEY]: checkpoint,\n },\n sessionMessages: pending.sessionMessages,\n timelineMessage: buildContextCompactionTimelineNcpMessage({\n sessionId: pending.sessionId,\n checkpoint,\n }),\n };\n };\n\n private generateSummary = async (params: {\n messages: Record<string, unknown>[];\n model: string;\n }): Promise<string> => {\n if (!this.options.providerManager) {\n throw new Error(\"context compaction summary generation requires a provider manager\");\n }\n const { messages, model } = params;\n const response = await this.options.providerManager.chat({\n model,\n maxTokens: SUMMARY_MAX_TOKENS,\n messages: [\n {\n role: \"system\",\n content: [\n \"You are NextClaw's context compactor for a coding agent session.\",\n \"Create a dense, structured summary that will replace earlier conversation history in a future model request.\",\n \"Preserve user goals, explicit instructions, decisions, files touched or inspected, code changes, commands run, test results, failures, blockers, and exact next steps.\",\n \"Do not invent facts. If something is uncertain, mark it as uncertain.\",\n \"Return Markdown only. Start with '# Compressed Earlier Context'.\",\n ].join(\"\\n\"),\n },\n {\n role: \"user\",\n content: [\n \"Compress these earlier runtime messages into a reusable checkpoint summary.\",\n \"\",\n \"Messages JSON:\",\n stringifyCompactionSource(messages),\n ].join(\"\\n\"),\n },\n ],\n });\n const summary = response.content?.trim();\n if (!summary) {\n throw new Error(\"context compaction summary is empty\");\n }\n return summary;\n };\n}\n","import type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { ContextWindowSnapshot } from \"@nextclaw/core\";\nimport {\n type NcpAgentRunInput,\n type NcpEndpointEvent,\n type NcpMessage,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport type { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport type { LiveSession } from \"@kernel/utils/session-run.utils.js\";\nimport {\n ContextCompactionPreflightService,\n type ContextCompactionPreflightResult,\n} from \"@kernel/features/context-compaction/services/context-compaction-preflight.service.js\";\n\nexport class ContextWindowPreviewManager {\n private readonly preflightService: ContextCompactionPreflightService;\n\n constructor(\n private readonly options: {\n configManager: ConfigManager;\n },\n ) {\n this.preflightService = new ContextCompactionPreflightService({\n configManager: options.configManager,\n });\n }\n\n preview = (params: {\n requestMetadata: Record<string, unknown>;\n sessionId: string;\n sessionMessages: readonly NcpMessage[];\n storedAgentId?: string;\n storedMetadata: Record<string, unknown>;\n }): ContextWindowSnapshot | null => {\n const {\n requestMetadata,\n sessionId,\n sessionMessages,\n storedAgentId,\n storedMetadata,\n } = params;\n return this.preflightService.preview({\n requestMetadata,\n sessionId,\n sessionMessages,\n storedAgentId,\n storedMetadata,\n });\n };\n}\n\nexport class ContextCompactionManager {\n private readonly preflightService: ContextCompactionPreflightService;\n\n constructor(\n private readonly options: {\n configManager: ConfigManager;\n providerManager?: LlmProviderRuntime;\n sessionRunManager: SessionRunManager;\n },\n ) {\n this.preflightService = new ContextCompactionPreflightService({\n configManager: options.configManager,\n providerManager: options.providerManager,\n });\n }\n\n runLivePreflight = async function* (\n this: ContextCompactionManager,\n params: {\n input: NcpAgentRunInput;\n session: LiveSession;\n },\n ): AsyncIterable<NcpEndpointEvent> {\n const sessionRunManager = this.options.sessionRunManager;\n const { input, session } = params;\n const beginResult = this.preflightService.begin({\n inputMessages: input.messages,\n requestMetadata: input.metadata ?? {},\n sessionId: input.sessionId,\n sessionMessages: session.stateManager.getSnapshot().messages,\n ...(session.agentId ? { storedAgentId: session.agentId } : {}),\n storedMetadata: input.metadata ?? {},\n });\n yield* this.applyLivePreflightResult({ input, result: beginResult, session, sessionRunManager });\n if (!beginResult.pendingCompaction) {\n return;\n }\n const finishResult = await this.preflightService.finish(beginResult.pendingCompaction);\n yield* this.applyLivePreflightResult({ input, result: finishResult, session, sessionRunManager });\n };\n\n private applyLivePreflightResult = async function* (\n this: ContextCompactionManager,\n params: {\n input: NcpAgentRunInput;\n result: ContextCompactionPreflightResult;\n session: LiveSession;\n sessionRunManager: SessionRunManager;\n },\n ): AsyncIterable<NcpEndpointEvent> {\n const { input, result, session, sessionRunManager } = params;\n if (Object.keys(result.metadataPatch).length > 0) {\n await sessionRunManager.updateSessionMetadata(session.sessionId, result.metadataPatch);\n }\n const contextWindowEvent = {\n type: NcpEventType.ContextWindowUpdated,\n payload: {\n sessionId: input.sessionId,\n contextWindow: result.contextWindow,\n },\n } as const;\n await sessionRunManager.appendSessionEvent(session.sessionId, contextWindowEvent);\n yield contextWindowEvent;\n if (!result.timelineMessage) {\n return;\n }\n const activeRun = session.stateManager.getSnapshot().activeRun;\n session.stateManager.hydrate({\n sessionId: input.sessionId,\n messages: result.sessionMessages,\n activeRun,\n contextWindow: result.contextWindow,\n });\n const timelineEvent = {\n type: NcpEventType.MessageSent,\n payload: {\n sessionId: input.sessionId,\n message: result.timelineMessage,\n },\n } as const;\n await sessionRunManager.appendSessionEvent(session.sessionId, timelineEvent);\n yield timelineEvent;\n };\n}\n","import {\n type NcpEndpointEvent,\n NcpEventType,\n} from \"@nextclaw/ncp\";\n\nexport function readContextWindowEventSessionId(event: NcpEndpointEvent): string | null {\n const payload = \"payload\" in event ? event.payload : null;\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n return \"sessionId\" in payload && typeof payload.sessionId === \"string\"\n ? payload.sessionId.trim() || null\n : null;\n}\n\nexport function isContextWindowSnapshot(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function createContextWindowSignature(value: Record<string, unknown>): string {\n return JSON.stringify(value);\n}\n\nexport function shouldRefreshContextWindowDuringStream(event: NcpEndpointEvent): boolean {\n switch (event.type) {\n case NcpEventType.MessageTextStart:\n case NcpEventType.MessageTextDelta:\n case NcpEventType.MessageTextEnd:\n case NcpEventType.MessageReasoningStart:\n case NcpEventType.MessageReasoningDelta:\n case NcpEventType.MessageReasoningEnd:\n case NcpEventType.MessageToolCallStart:\n case NcpEventType.MessageToolCallArgs:\n case NcpEventType.MessageToolCallArgsDelta:\n case NcpEventType.MessageToolCallEnd:\n case NcpEventType.MessageToolCallResult:\n return true;\n default:\n return false;\n }\n}\n\nexport function shouldRefreshContextWindowImmediately(event: NcpEndpointEvent): boolean {\n switch (event.type) {\n case NcpEventType.MessageSent:\n case NcpEventType.MessageCompleted:\n case NcpEventType.MessageFailed:\n case NcpEventType.MessageAbort:\n case NcpEventType.RunFinished:\n case NcpEventType.RunError:\n return true;\n default:\n return false;\n }\n}\n","import {\n ToolRegistry,\n createToolExecutionContext,\n type Config,\n type ExtensionToolContext,\n type SearchConfig,\n type Tool,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpTool, NcpToolDefinition, NcpToolRegistry } from \"@nextclaw/ncp\";\nimport { isRecord } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nexport type UpdateToolCallResult = (params: {\n sessionId: string;\n toolCallId: string;\n result: unknown;\n}) => Promise<void>;\n\nexport type ToolRunContext = {\n agentId: string;\n channel: string;\n chatId: string;\n config: Config;\n execTimeoutSeconds: number;\n handoffDepth: number;\n metadata: Record<string, unknown>;\n restrictToWorkspace: boolean;\n searchConfig: SearchConfig;\n sessionId: string;\n workspace: string;\n};\n\nexport type ToolRegistrationContext = {\n registerTool: (tool: Tool) => void;\n registerNcpTool: (tool: NcpTool) => void;\n hasTool: (name: string) => boolean;\n getExtensionToolRunContext: () => ExtensionToolContext;\n};\n\nexport type ToolProvider = {\n id: string;\n registerTools: (context: ToolRunContext, registry: ToolRegistrationContext) => void;\n};\n\nexport type ToolRuntimeRegistryOptions = {\n updateToolCallResult: UpdateToolCallResult;\n};\n\nexport type ToolRuntimeRegistry = NcpToolRegistry & {\n prepareForRun: (context: ToolRunContext) => void;\n};\n\nfunction toToolParams(args: unknown): Record<string, unknown> {\n if (isRecord(args)) {\n return args;\n }\n if (typeof args === \"string\") {\n try {\n const parsed = JSON.parse(args) as unknown;\n return isRecord(parsed) ? parsed : {};\n } catch {\n return {};\n }\n }\n return {};\n}\n\nclass CoreToolNcpAdapter implements NcpTool {\n constructor(private readonly tool: Tool, private readonly executeTool: (toolName: string, args: unknown) => Promise<unknown>) {}\n\n get name(): string {\n return this.tool.name;\n }\n\n get description(): string {\n return this.tool.description;\n }\n\n get parameters(): Record<string, unknown> {\n return this.tool.parameters;\n }\n\n execute = async (args: unknown): Promise<unknown> => {\n return this.executeTool(this.tool.name, args);\n };\n}\n\nclass RuntimeToolRegistry implements ToolRuntimeRegistry {\n private registry = new ToolRegistry();\n private readonly tools = new Map<string, NcpTool>();\n private currentExtensionToolContext: ExtensionToolContext = {};\n\n constructor(\n private readonly getProviders: () => ToolProvider[],\n private readonly options: ToolRuntimeRegistryOptions,\n ) {}\n\n prepareForRun = (context: ToolRunContext): void => {\n const {\n channel,\n chatId,\n config,\n restrictToWorkspace,\n sessionId,\n workspace,\n } = context;\n this.currentExtensionToolContext = {\n config,\n workspaceDir: workspace,\n sessionKey: sessionId,\n channel,\n chatId,\n sandboxed: restrictToWorkspace,\n };\n\n this.registry = new ToolRegistry();\n this.tools.clear();\n\n const registrationContext = this.createRegistrationContext();\n for (const provider of this.getProviders()) {\n provider.registerTools(context, registrationContext);\n }\n };\n\n listTools = (): ReadonlyArray<NcpTool> => {\n return [...this.tools.values()].filter((tool) => this.isToolAvailable(tool.name));\n };\n\n getTool = (name: string): NcpTool | undefined => {\n if (!this.isToolAvailable(name)) {\n return undefined;\n }\n return this.tools.get(name);\n };\n\n getToolDefinitions = (): ReadonlyArray<NcpToolDefinition> => {\n return this.listTools().map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }));\n };\n\n execute = async (toolCallId: string, toolName: string, args: unknown): Promise<unknown> => {\n if (this.registry.has(toolName)) {\n return this.registry.executeRaw(\n toolName,\n toToolParams(args),\n this.buildToolExecutionContext(toolCallId),\n );\n }\n return this.tools.get(toolName)?.execute(args);\n };\n\n private buildToolExecutionContext = (toolCallId: string): ToolExecutionContext => {\n const sessionId = this.currentExtensionToolContext.sessionKey;\n return createToolExecutionContext({\n toolCallId,\n updateToolCallResult: async (result: unknown) => {\n if (!sessionId) {\n return;\n }\n await this.options.updateToolCallResult({\n sessionId,\n toolCallId,\n result,\n });\n },\n });\n };\n\n private createRegistrationContext = (): ToolRegistrationContext => ({\n registerTool: this.registerTool,\n registerNcpTool: this.registerNcpTool,\n hasTool: (name) => this.tools.has(name),\n getExtensionToolRunContext: () => this.currentExtensionToolContext,\n });\n\n private registerTool = (tool: Tool): void => {\n this.registry.register(tool);\n this.tools.set(\n tool.name,\n new CoreToolNcpAdapter(tool, async (toolName, args) =>\n this.registry.execute(toolName, toToolParams(args)),\n ),\n );\n };\n\n private registerNcpTool = (tool: NcpTool): void => {\n if (this.tools.has(tool.name)) {\n return;\n }\n this.tools.set(tool.name, tool);\n };\n\n private isToolAvailable = (name: string): boolean => {\n const coreTool = this.registry.get(name);\n return coreTool ? coreTool.isAvailable() : true;\n };\n}\n\nexport class ToolManager {\n private readonly providers = new Map<string, ToolProvider>();\n\n provideTools = (provider: ToolProvider): { dispose: () => void } => {\n if (this.providers.has(provider.id)) {\n throw new Error(`Tool provider is already registered: ${provider.id}`);\n }\n this.providers.set(provider.id, provider);\n return {\n dispose: () => {\n if (this.providers.get(provider.id) === provider) {\n this.providers.delete(provider.id);\n }\n },\n };\n };\n\n createRuntimeRegistry = (options: ToolRuntimeRegistryOptions): ToolRuntimeRegistry => {\n return new RuntimeToolRegistry(() => [...this.providers.values()], options);\n };\n\n}\n\nexport function resolveAgentHandoffDepth(metadata: Record<string, unknown>): number {\n const rawDepth = Number(metadata.agent_handoff_depth ?? 0);\n if (!Number.isFinite(rawDepth) || rawDepth < 0) {\n return 0;\n }\n return Math.trunc(rawDepth);\n}\n","import { parseThinkingLevel, type ThinkingLevel } from \"@nextclaw/core\";\n\nexport function normalizeOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport function readMetadataModel(metadata: Record<string, unknown>): string | null {\n const candidates = [metadata.model, metadata.llm_model, metadata.agent_model, metadata.session_model];\n for (const candidate of candidates) {\n const normalized = normalizeOptionalString(candidate);\n if (normalized) {\n return normalized;\n }\n }\n return null;\n}\n\nexport function readMetadataThinking(metadata: Record<string, unknown>): ThinkingLevel | \"__clear__\" | null {\n const candidates = [\n metadata.thinking,\n metadata.thinking_level,\n metadata.thinkingLevel,\n metadata.thinking_effort,\n metadata.thinkingEffort,\n ];\n for (const candidate of candidates) {\n if (typeof candidate !== \"string\") {\n continue;\n }\n const normalized = candidate.trim().toLowerCase();\n if (!normalized) {\n continue;\n }\n if (normalized === \"clear\" || normalized === \"reset\" || normalized === \"off!\") {\n return \"__clear__\";\n }\n const level = parseThinkingLevel(normalized);\n if (level) {\n return level;\n }\n }\n return null;\n}\n\nexport function resolveEffectiveModel(params: {\n sessionMetadata: Record<string, unknown>;\n requestMetadata: Record<string, unknown>;\n fallbackModel: string;\n}): { metadata: Record<string, unknown>; model: string } {\n const { fallbackModel, requestMetadata } = params;\n const metadata = structuredClone(params.sessionMetadata);\n const clearModel =\n requestMetadata.clear_model === true ||\n requestMetadata.reset_model === true;\n if (clearModel) {\n delete metadata.preferred_model;\n }\n\n const inboundModel = readMetadataModel(requestMetadata);\n if (inboundModel) {\n metadata.preferred_model = inboundModel;\n }\n\n return {\n metadata,\n model: normalizeOptionalString(metadata.preferred_model) ?? fallbackModel,\n };\n}\n\nexport function syncSessionThinkingPreference(params: {\n sessionMetadata: Record<string, unknown>;\n requestMetadata: Record<string, unknown>;\n}): Record<string, unknown> {\n const { requestMetadata } = params;\n const metadata = structuredClone(params.sessionMetadata);\n const clearThinking =\n requestMetadata.clear_thinking === true ||\n requestMetadata.reset_thinking === true;\n if (clearThinking) {\n delete metadata.preferred_thinking;\n }\n\n const inboundThinking = readMetadataThinking(requestMetadata);\n if (inboundThinking === \"__clear__\") {\n delete metadata.preferred_thinking;\n return metadata;\n }\n if (inboundThinking) {\n metadata.preferred_thinking = inboundThinking;\n }\n return metadata;\n}\n\nexport function resolveSessionChannelContext(params: {\n sessionMetadata: Record<string, unknown>;\n requestMetadata: Record<string, unknown>;\n}): { channel: string; chatId: string; metadata: Record<string, unknown> } {\n const { requestMetadata } = params;\n const metadata = structuredClone(params.sessionMetadata);\n const channel =\n normalizeOptionalString(requestMetadata.channel) ??\n normalizeOptionalString(metadata.last_channel) ??\n \"ui\";\n const chatId =\n normalizeOptionalString(requestMetadata.chatId) ??\n normalizeOptionalString(requestMetadata.chat_id) ??\n normalizeOptionalString(metadata.last_to) ??\n \"web-ui\";\n\n metadata.last_channel = channel;\n metadata.last_to = chatId;\n return { channel, chatId, metadata };\n}\n","import {\n ContextWindowBudgetService,\n findEffectiveAgentProfile,\n getWorkspacePath,\n parseThinkingLevel,\n RequestedSkillsMetadataReader,\n resolveDefaultAgentProfileId,\n resolveSessionWorkspacePath,\n resolveThinkingLevel,\n type Config,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport {\n resolveEffectiveModel,\n resolveSessionChannelContext,\n normalizeOptionalString,\n} from \"@kernel/features/native-runtime/utils/nextclaw-ncp-session-preferences.utils.js\";\nimport {\n resolveAgentHandoffDepth,\n type ToolRunContext,\n} from \"@kernel/managers/tool.manager.js\";\n\nexport type NextclawNcpResolvedAgentProfile = {\n agentId: string;\n contextTokens: number;\n execTimeoutSeconds: number;\n model: string;\n reservedContextTokens: number;\n restrictToWorkspace: boolean;\n searchConfig: Config[\"search\"];\n workspace: string;\n};\n\nexport type NextclawNcpRunContextParams = {\n configManager: ConfigManager;\n sessionId: string;\n requestMetadata?: Record<string, unknown>;\n sessionMetadata?: Record<string, unknown>;\n storedAgentId?: string;\n};\n\nexport type NextclawNcpResolvedRunContext = {\n channel: string;\n chatId: string;\n config: Config;\n effectiveModel: string;\n effectiveWorkspace: string;\n profile: NextclawNcpResolvedAgentProfile;\n requestMetadata: Record<string, unknown>;\n requestedSkills: ReturnType<RequestedSkillsMetadataReader[\"readSelection\"]>;\n requestedToolNames: string[];\n runtimeThinking: ReturnType<typeof resolveThinkingLevel>;\n sessionKey: string;\n sessionMetadata: Record<string, unknown>;\n toolRunContext: ToolRunContext;\n};\n\nconst REQUESTED_SKILLS_METADATA_READER = new RequestedSkillsMetadataReader();\n\nfunction readRequestedAgentId(metadata: Record<string, unknown>): string | null {\n return normalizeOptionalString(metadata.agent_id)?.toLowerCase() ??\n normalizeOptionalString(metadata.agentId)?.toLowerCase() ??\n null;\n}\n\nfunction resolveAgentProfile(params: {\n config: Config;\n requestMetadata: Record<string, unknown>;\n storedAgentId?: string;\n}): NextclawNcpResolvedAgentProfile {\n const { config, requestMetadata, storedAgentId } = params;\n const {\n agents: { defaults },\n search: searchConfig,\n tools: {\n restrictToWorkspace,\n exec: { timeout: execTimeoutSeconds },\n },\n } = config;\n const defaultAgentId = resolveDefaultAgentProfileId(config);\n const candidateAgentId =\n normalizeOptionalString(storedAgentId)?.toLowerCase() ??\n readRequestedAgentId(requestMetadata) ??\n defaultAgentId;\n const profile =\n findEffectiveAgentProfile(config, candidateAgentId) ??\n findEffectiveAgentProfile(config, defaultAgentId);\n if (!profile) {\n throw new Error(`default agent profile not found: ${defaultAgentId}`);\n }\n const contextTokens = profile.contextTokens ?? defaults.contextTokens;\n return {\n agentId: profile.id,\n workspace: getWorkspacePath(profile.workspace ?? defaults.workspace),\n model: profile.model ?? defaults.model,\n contextTokens,\n reservedContextTokens: ContextWindowBudgetService.resolveReservedContextTokens({\n contextTokens,\n configuredReservedContextTokens: profile.reservedContextTokens ?? defaults.reservedContextTokens,\n }),\n restrictToWorkspace,\n searchConfig,\n execTimeoutSeconds,\n };\n}\n\nfunction resolveRequestedToolNames(metadata: Record<string, unknown>): string[] {\n const rawValue = metadata.requested_tools ?? metadata.requestedTools;\n if (!Array.isArray(rawValue)) {\n return [];\n }\n return Array.from(\n new Set(\n rawValue\n .map((item) => normalizeOptionalString(item))\n .filter((item): item is string => Boolean(item)),\n ),\n );\n}\n\nfunction mergeRunMetadata(params: {\n requestMetadata?: Record<string, unknown>;\n sessionMetadata?: Record<string, unknown>;\n}): Record<string, unknown> {\n const { requestMetadata, sessionMetadata } = params;\n return {\n ...(sessionMetadata ? structuredClone(sessionMetadata) : {}),\n ...(requestMetadata ? structuredClone(requestMetadata) : {}),\n };\n}\n\nexport function buildSessionOrchestrationSection(): string {\n return [\n \"## Session Orchestration\",\n \"- Before passing a non-default `runtime` to `sessions_spawn` or agent creation/update flows, inspect the installed runtime kinds with `nextclaw agents runtimes --json`.\",\n \"- `sessions_spawn` is the unified session-creation tool. Omit `scope` or use `scope=\\\"standalone\\\"` for a regular session, and use `scope=\\\"child\\\"` when the new session should be a child session of the current flow.\",\n \"- `sessions_spawn` only creates the session by default. Add top-level `notify: \\\"none\\\" | \\\"final_reply\\\"` when the new session should start working immediately.\",\n \"- When `sessions_spawn.scope=\\\"child\\\"` and `sessions_spawn.notify=\\\"final_reply\\\"`, the new child session starts right away and this session automatically continues after that child reaches its final reply.\",\n \"- Use `sessions_spawn` without `notify` when the user wants a separate thread created now but does not need it to start working yet.\",\n \"- Use `sessions_request` to send one task to an existing session, including a session that was just created by `sessions_spawn` or a previously created child session.\",\n \"- `sessions_request.target` must be an object shaped like `{ \\\"session_id\\\": \\\"<target-session-id>\\\" }`. Do not pass a bare string.\",\n \"- Prefer `notify=\\\"final_reply\\\"` when the current session should continue after the target session produces its final reply. Use `notify=\\\"none\\\"` when you only want the target session to run independently.\",\n ].join(\"\\n\");\n}\n\nexport function resolveNextclawNcpRunContext(\n params: NextclawNcpRunContextParams,\n): NextclawNcpResolvedRunContext {\n const {\n configManager,\n requestMetadata: inputRequestMetadata,\n sessionId,\n sessionMetadata: inputSessionMetadata,\n storedAgentId,\n } = params;\n const config = configManager.loadConfig();\n const requestMetadata = mergeRunMetadata({\n sessionMetadata: inputSessionMetadata,\n requestMetadata: inputRequestMetadata,\n });\n const profile = resolveAgentProfile({\n config,\n storedAgentId,\n requestMetadata,\n });\n const { metadata: modelMetadata, model: effectiveModel } = resolveEffectiveModel({\n sessionMetadata: requestMetadata,\n requestMetadata,\n fallbackModel: profile.model,\n });\n const effectiveWorkspace = resolveSessionWorkspacePath({\n sessionMetadata: modelMetadata,\n workspace: profile.workspace,\n });\n const channelContext = resolveSessionChannelContext({\n sessionMetadata: modelMetadata,\n requestMetadata,\n });\n const sessionMetadata = channelContext.metadata;\n const requestedSkills = REQUESTED_SKILLS_METADATA_READER.readSelection(requestMetadata);\n const runtimeThinking = resolveThinkingLevel({\n config,\n agentId: profile.agentId,\n model: effectiveModel,\n sessionThinkingLevel: parseThinkingLevel(sessionMetadata.preferred_thinking) ?? null,\n });\n\n return {\n channel: channelContext.channel,\n chatId: channelContext.chatId,\n config,\n effectiveModel,\n effectiveWorkspace,\n profile,\n requestMetadata,\n requestedSkills,\n requestedToolNames: resolveRequestedToolNames(requestMetadata),\n runtimeThinking,\n sessionKey: sessionId,\n sessionMetadata,\n toolRunContext: {\n sessionId,\n channel: channelContext.channel,\n chatId: channelContext.chatId,\n agentId: profile.agentId,\n config,\n execTimeoutSeconds: profile.execTimeoutSeconds,\n handoffDepth: resolveAgentHandoffDepth(requestMetadata),\n metadata: requestMetadata,\n restrictToWorkspace: profile.restrictToWorkspace,\n searchConfig: profile.searchConfig,\n workspace: effectiveWorkspace,\n },\n };\n}\n","import {\n buildToolCatalogEntries,\n buildMinimalSystemExecutionPrompt,\n ContextBuilder,\n InputBudgetPruner,\n readSessionProjectRoot,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport {\n buildOpenAiFunctionTool,\n type LocalAssetStore,\n} from \"@nextclaw/ncp-agent-runtime\";\nimport type {\n NcpAgentRunInput,\n NcpContextBuilder,\n NcpContextPrepareOptions,\n NcpLLMApiInput,\n NcpToolDefinition,\n OpenAIChatMessage,\n OpenAITool,\n} from \"@nextclaw/ncp\";\nimport {\n toLegacyMessages,\n} from \"@kernel/utils/ncp-message-bridge.utils.js\";\nimport { buildCurrentTurnState } from \"@kernel/features/native-runtime/utils/nextclaw-ncp-current-turn.utils.js\";\nimport { projectNcpMessagesWithContextCompaction } from \"@kernel/features/context-compaction/index.js\";\nimport {\n type ToolRuntimeRegistry,\n} from \"@kernel/managers/tool.manager.js\";\nimport {\n buildSessionOrchestrationSection,\n resolveNextclawNcpRunContext,\n type NextclawNcpResolvedRunContext,\n} from \"@kernel/features/native-runtime/utils/nextclaw-ncp-run-context.utils.js\";\n\ntype NextclawNcpContextBuilderOptions = {\n agentId?: string;\n toolRegistry: ToolRuntimeRegistry;\n configManager: ConfigManager;\n assetStore?: LocalAssetStore | null;\n};\n\ntype PreparedRunContext = NextclawNcpResolvedRunContext & {\n currentTurn: ReturnType<typeof buildCurrentTurnState>;\n};\n\ntype BuiltNcpModelMessages = {\n messages: Record<string, unknown>[];\n toolDefinitions: readonly NcpToolDefinition[];\n};\n\nconst TIME_HINT_TRIGGER_PATTERNS = [\n /\\b(now|right now|current time|what time|today|tonight|tomorrow|yesterday|this morning|this afternoon|this evening|date)\\b/i,\n /(现在|此刻|当前时间|现在几点|几点了|今天|今晚|今早|今晨|明天|昨天|日期)/,\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction mergeInputMetadata(input: NcpAgentRunInput): Record<string, unknown> {\n const messageMetadata = input.messages\n .slice()\n .reverse()\n .find((message) => isRecord(message.metadata))?.metadata;\n return {\n ...(isRecord(messageMetadata) ? structuredClone(messageMetadata) : {}),\n ...(isRecord(input.metadata) ? structuredClone(input.metadata) : {}),\n };\n}\n\nfunction shouldAppendTimeHint(content: string): boolean {\n const normalized = content.trim();\n if (!normalized) {\n return false;\n }\n return TIME_HINT_TRIGGER_PATTERNS.some((pattern) => pattern.test(normalized));\n}\n\nfunction buildMinutePrecisionTimeHint(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n const hour = String(date.getHours()).padStart(2, \"0\");\n const minute = String(date.getMinutes()).padStart(2, \"0\");\n const offsetMinutes = -date.getTimezoneOffset();\n const sign = offsetMinutes >= 0 ? \"+\" : \"-\";\n const absMinutes = Math.abs(offsetMinutes);\n const offsetHour = String(Math.floor(absMinutes / 60)).padStart(2, \"0\");\n const offsetMinute = String(absMinutes % 60).padStart(2, \"0\");\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || \"local\";\n return `${year}-${month}-${day} ${hour}:${minute} ${sign}${offsetHour}:${offsetMinute} (${timezone})`;\n}\n\nfunction appendTimeHintForPrompt(content: string, timestamp: Date): string {\n if (!shouldAppendTimeHint(content)) {\n return content;\n }\n const date = Number.isNaN(timestamp.getTime()) ? new Date() : timestamp;\n return `${content}\\n\\n[time_hint_local_minute] ${buildMinutePrecisionTimeHint(date)}`;\n}\n\nfunction prependRequestedSkills(content: string, requestedSkillSelectors: string[]): string {\n if (requestedSkillSelectors.length === 0) {\n return content;\n }\n return `[Requested skills for this turn: ${requestedSkillSelectors.join(\", \")}]\\n\\n${content}`;\n}\n\nfunction buildRequestedOpenAiTools(\n toolDefinitions: ReadonlyArray<NcpToolDefinition>,\n requestedToolNames: string[],\n): OpenAITool[] | undefined {\n const tools = toolDefinitions.map(buildOpenAiFunctionTool);\n if (tools.length === 0) {\n return undefined;\n }\n if (requestedToolNames.length === 0) {\n return tools;\n }\n const requested = new Set(requestedToolNames);\n const filtered = tools.filter((tool) => requested.has(tool.function.name));\n return filtered.length > 0 ? filtered : undefined;\n}\n\nexport class NextclawNcpContextBuilder implements NcpContextBuilder {\n private readonly inputBudgetPruner = new InputBudgetPruner();\n\n constructor(\n private readonly options: NextclawNcpContextBuilderOptions,\n ) {}\n\n prepare = (input: NcpAgentRunInput, _options?: NcpContextPrepareOptions): NcpLLMApiInput => {\n const runContext = this.prepareRunContext(input);\n const modelMessages = this.buildModelMessages(input, _options, runContext);\n const pruned = this.pruneModelMessages(runContext, modelMessages);\n\n return {\n messages: pruned.messages as OpenAIChatMessage[],\n tools: buildRequestedOpenAiTools(modelMessages.toolDefinitions, runContext.requestedToolNames),\n model: runContext.effectiveModel,\n thinkingLevel: runContext.runtimeThinking,\n };\n };\n\n private prepareRunContext = (input: NcpAgentRunInput): PreparedRunContext => {\n const requestMetadata = mergeInputMetadata(input);\n const resolved = resolveNextclawNcpRunContext({\n configManager: this.options.configManager,\n sessionId: input.sessionId,\n requestMetadata,\n sessionMetadata: requestMetadata,\n storedAgentId: this.options.agentId,\n });\n const currentTurn = buildCurrentTurnState({\n input,\n currentModel: resolved.effectiveModel,\n formatPrompt: ({ text, timestamp }) =>\n appendTimeHintForPrompt(\n prependRequestedSkills(text, resolved.requestedSkills.selectors),\n timestamp,\n ),\n assetStore: this.options.assetStore,\n });\n\n this.options.toolRegistry.prepareForRun(resolved.toolRunContext);\n\n return {\n ...resolved,\n currentTurn,\n effectiveModel: currentTurn.effectiveModel,\n };\n };\n\n private buildModelMessages = (\n input: NcpAgentRunInput,\n _options: NcpContextPrepareOptions | undefined,\n runContext: PreparedRunContext,\n ): BuiltNcpModelMessages => {\n const {\n channel,\n chatId,\n config,\n currentTurn,\n effectiveModel,\n effectiveWorkspace,\n profile,\n requestedSkills,\n runtimeThinking,\n sessionMetadata,\n } = runContext;\n const toolDefinitions = this.options.toolRegistry.getToolDefinitions();\n const additionalSystemSections = [\n buildSessionOrchestrationSection(),\n buildMinimalSystemExecutionPrompt(effectiveModel),\n ].filter(Boolean);\n\n const contextBuilder = new ContextBuilder(\n effectiveWorkspace,\n config.agents.context,\n {\n hostWorkspace: profile.workspace,\n sessionProjectRoot: readSessionProjectRoot(sessionMetadata),\n },\n );\n const sessionMessages = projectNcpMessagesWithContextCompaction({\n sessionId: input.sessionId,\n sessionMessages: _options?.sessionMessages ?? [],\n });\n const messages = contextBuilder.buildMessages({\n history: toLegacyMessages([...sessionMessages], {\n assetStore: this.options.assetStore,\n serviceRole: \"system\",\n }),\n currentMessage: \"\",\n channel,\n chatId,\n sessionKey: input.sessionId,\n thinkingLevel: runtimeThinking,\n skillNames: requestedSkills.selectors,\n availableTools: buildToolCatalogEntries(toolDefinitions),\n additionalSystemSections,\n });\n messages[messages.length - 1] = {\n role: currentTurn.currentRole,\n content: currentTurn.currentUserContent,\n };\n return {\n messages,\n toolDefinitions,\n };\n };\n\n private pruneModelMessages = (\n runContext: PreparedRunContext,\n modelMessages: BuiltNcpModelMessages,\n ) => {\n return this.inputBudgetPruner.prune({\n messages: modelMessages.messages,\n contextTokens: runContext.profile.contextTokens,\n reserveTokensFloor: runContext.profile.reservedContextTokens,\n softThresholdTokens: 0,\n });\n };\n}\n","import type {\n OpenAIChatChunk,\n OpenAIToolCallDelta,\n NcpLLMApi,\n NcpLLMApiInput,\n NcpLLMApiOptions,\n} from \"@nextclaw/ncp\";\nimport { parseThinkingLevel, type LLMResponse, type ThinkingLevel, type ToolCallRequest } from \"@nextclaw/core\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\n\nfunction normalizeModel(value: string | undefined): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizeThinkingLevel(value: string | null | undefined): ThinkingLevel | null {\n return parseThinkingLevel(value);\n}\n\nfunction normalizeFinishReason(value: string | undefined): string {\n if (typeof value !== \"string\") {\n return \"stop\";\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : \"stop\";\n}\n\nfunction toToolCallDelta(toolCall: ToolCallRequest, index: number) {\n return {\n index,\n id: toolCall.id,\n type: \"function\" as const,\n function: {\n name: toolCall.name,\n arguments: JSON.stringify(toolCall.arguments ?? {})\n }\n };\n}\n\nfunction toFinalChunk(\n response: LLMResponse,\n options: {\n includeText: boolean;\n includeReasoning: boolean;\n includeToolCalls: boolean;\n },\n): OpenAIChatChunk {\n const delta: NonNullable<OpenAIChatChunk[\"choices\"]>[number][\"delta\"] = {};\n if (options.includeText && typeof response.content === \"string\" && response.content.length > 0) {\n delta.content = response.content;\n }\n if (\n options.includeReasoning &&\n typeof response.reasoningContent === \"string\" &&\n response.reasoningContent.length > 0\n ) {\n delta.reasoning_content = response.reasoningContent;\n }\n if (options.includeToolCalls && response.toolCalls.length > 0) {\n delta.tool_calls = response.toolCalls.map((toolCall, index) => toToolCallDelta(toolCall, index));\n }\n\n return {\n choices: [\n {\n delta,\n finish_reason: normalizeFinishReason(response.finishReason)\n }\n ],\n usage: response.usage\n };\n}\n\nexport class ProviderManagerNcpLLMApi implements NcpLLMApi {\n constructor(private readonly providerManager: LlmProviderRuntime) {}\n\n readonly generate = async function* (\n this: ProviderManagerNcpLLMApi,\n input: NcpLLMApiInput,\n options?: NcpLLMApiOptions\n ): AsyncGenerator<OpenAIChatChunk> {\n const model = normalizeModel(input.model) ?? this.providerManager.get(null).getDefaultModel();\n const thinkingLevel = normalizeThinkingLevel(input.thinkingLevel);\n let sawTextDelta = false;\n let sawReasoningDelta = false;\n let sawToolCallDelta = false;\n\n for await (const event of this.providerManager.chatStream({\n messages: input.messages as Array<Record<string, unknown>>,\n tools: input.tools as Array<Record<string, unknown>> | undefined,\n model,\n ...(thinkingLevel ? { thinkingLevel } : {}),\n maxTokens: input.max_tokens,\n signal: options?.signal\n })) {\n if (event.type === \"delta\") {\n sawTextDelta = true;\n yield {\n choices: [\n {\n delta: {\n content: event.delta\n }\n }\n ]\n };\n continue;\n }\n\n if (event.type === \"reasoning_delta\") {\n sawReasoningDelta = true;\n yield {\n choices: [\n {\n delta: {\n reasoning_content: event.delta,\n },\n },\n ],\n };\n continue;\n }\n\n if (event.type === \"tool_call_delta\") {\n sawToolCallDelta = true;\n yield {\n choices: [\n {\n delta: {\n tool_calls: event.toolCalls as OpenAIToolCallDelta[],\n },\n },\n ],\n };\n continue;\n }\n\n yield toFinalChunk(event.response, {\n includeText: !sawTextDelta,\n includeReasoning: !sawReasoningDelta,\n includeToolCalls: !sawToolCallDelta,\n });\n }\n };\n}\n","import type { Config } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport { DefaultNcpAgentRuntime, type LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n type NcpAgentRuntime,\n readAssistantReasoningNormalizationMode,\n readAssistantReasoningNormalizationModeFromMetadata,\n type NcpAssistantReasoningNormalizationMode,\n} from \"@nextclaw/ncp\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\nimport { type LlmUsageManager } from \"@kernel/managers/llm-usage.manager.js\";\nimport type {\n ToolManager,\n UpdateToolCallResult,\n} from \"@kernel/managers/tool.manager.js\";\nimport { NextclawNcpContextBuilder } from \"./nextclaw-ncp-context-builder.service.js\";\nimport { ProviderManagerNcpLLMApi } from \"./provider-manager-ncp-llm-api.service.js\";\n\nexport type NativeRuntimeFactory = (runtimeParams: RuntimeFactoryParams) => NcpAgentRuntime;\n\nexport type NativeAgentRuntimeFactoryOptions = {\n providerManager: LlmProviderRuntime;\n configManager: ConfigManager;\n llmUsage: LlmUsageManager;\n assetStore: LocalAssetStore;\n updateToolCallResult: UpdateToolCallResult;\n toolManager: ToolManager;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction resolveNativeReasoningNormalizationMode(params: {\n config: Config;\n sessionMetadata: Record<string, unknown>;\n}): NcpAssistantReasoningNormalizationMode {\n const runtimeEntry =\n params.config.agents.runtimes.entries.native?.config ??\n params.config.ui.ncp.runtimes.native;\n const runtimeMetadata = isRecord(runtimeEntry) ? runtimeEntry : {};\n\n return (\n readAssistantReasoningNormalizationModeFromMetadata(params.sessionMetadata) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoningNormalization) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoning_normalization) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoningNormalizationMode) ??\n readAssistantReasoningNormalizationMode(runtimeMetadata.reasoning_normalization_mode) ??\n \"think-tags\"\n );\n}\n\nexport class NativeAgentRuntimeFactory {\n private readonly observedProviderManager: LlmProviderRuntime;\n\n constructor(private readonly options: NativeAgentRuntimeFactoryOptions) {\n this.observedProviderManager = options.llmUsage.observeProviderManager(\n options.providerManager,\n \"ui-ncp\",\n );\n }\n\n create: NativeRuntimeFactory = ({\n agentId,\n stateManager,\n sessionMetadata,\n }: RuntimeFactoryParams): NcpAgentRuntime => {\n const reasoningNormalizationMode = resolveNativeReasoningNormalizationMode({\n config: this.options.configManager.loadConfig(),\n sessionMetadata,\n });\n\n const toolRegistry = this.createToolRegistry();\n const runtime = new DefaultNcpAgentRuntime({\n contextBuilder: new NextclawNcpContextBuilder({\n agentId,\n toolRegistry,\n configManager: this.options.configManager,\n assetStore: this.options.assetStore,\n }),\n llmApi: new ProviderManagerNcpLLMApi(this.observedProviderManager),\n toolRegistry,\n stateManager,\n reasoningNormalizationMode,\n });\n return {\n run: async function* (input, options) {\n yield* runtime.run(input, options);\n },\n };\n };\n\n private createToolRegistry = () => {\n return this.options.toolManager.createRuntimeRegistry({\n updateToolCallResult: this.options.updateToolCallResult,\n });\n };\n}\n","import { resolve } from \"node:path\";\nimport {\n buildAssetContentPath,\n type LocalAssetStore,\n type StoredAssetRecord,\n} from \"@nextclaw/ncp-agent-runtime\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nfunction readOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction readOptionalBase64Bytes(value: unknown): Uint8Array | null {\n const base64 = readOptionalString(value);\n if (!base64) {\n return null;\n }\n try {\n return Buffer.from(base64, \"base64\");\n } catch {\n return null;\n }\n}\n\nfunction toAssetPayload(record: StoredAssetRecord, contentBasePath: string) {\n return {\n uri: record.uri,\n name: record.fileName,\n mimeType: record.mimeType,\n sizeBytes: record.sizeBytes,\n createdAt: record.createdAt,\n url: buildAssetContentPath({\n basePath: contentBasePath,\n assetUri: record.uri,\n }),\n };\n}\n\nclass AssetPutTool implements NcpTool {\n readonly name = \"asset_put\";\n readonly description =\n \"Publish a file to the user as a chat/channel attachment with preview and download support.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Existing local file path to publish to the user as an attachment.\",\n },\n bytesBase64: {\n type: \"string\",\n description: \"Base64 file bytes to publish when no source path exists. Use with fileName.\",\n },\n fileName: {\n type: \"string\",\n description: \"Optional display/download file name. Required when using bytesBase64.\",\n },\n mimeType: {\n type: \"string\",\n description: \"Optional MIME type override for preview and download rendering.\",\n },\n },\n additionalProperties: false,\n };\n\n constructor(\n private readonly assetStore: LocalAssetStore,\n private readonly contentBasePath: string,\n ) {}\n\n validateArgs = (args: Record<string, unknown>): string[] => {\n const path = readOptionalString(args.path);\n const bytesBase64 = readOptionalString(args.bytesBase64);\n const fileName = readOptionalString(args.fileName);\n\n if (path && bytesBase64) {\n return [\"Provide either path, or bytesBase64 + fileName, not both.\"];\n }\n if (path) {\n return [];\n }\n if (bytesBase64) {\n return fileName ? [] : [\"fileName is required when using bytesBase64.\"];\n }\n return [\"Provide either path, or bytesBase64 + fileName.\"];\n };\n\n execute = async (args: unknown): Promise<unknown> => {\n const path = readOptionalString((args as { path?: unknown } | null)?.path);\n const fileName = readOptionalString((args as { fileName?: unknown } | null)?.fileName);\n const mimeType = readOptionalString((args as { mimeType?: unknown } | null)?.mimeType);\n const bytes = readOptionalBase64Bytes((args as { bytesBase64?: unknown } | null)?.bytesBase64);\n\n if (path) {\n const record = await this.assetStore.putPath({\n path,\n fileName: fileName ?? undefined,\n mimeType,\n });\n return {\n ok: true,\n asset: toAssetPayload(record, this.contentBasePath),\n };\n }\n\n if (bytes && fileName) {\n const record = await this.assetStore.putBytes({\n fileName,\n mimeType,\n bytes,\n });\n return {\n ok: true,\n asset: toAssetPayload(record, this.contentBasePath),\n };\n }\n\n throw new Error(\"asset_put received invalid arguments after validation.\");\n };\n}\n\nclass AssetExportTool implements NcpTool {\n readonly name = \"asset_export\";\n readonly description =\n \"Export a managed asset to a normal file path so it can be processed like any ordinary file.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n assetUri: {\n type: \"string\",\n description: \"Managed asset URI to export.\",\n },\n targetPath: {\n type: \"string\",\n description: \"Destination file path.\",\n },\n },\n required: [\"assetUri\", \"targetPath\"],\n additionalProperties: false,\n };\n\n constructor(private readonly assetStore: LocalAssetStore) {}\n\n execute = async (args: unknown): Promise<unknown> => {\n const assetUri = readOptionalString((args as { assetUri?: unknown } | null)?.assetUri);\n const targetPath = readOptionalString((args as { targetPath?: unknown } | null)?.targetPath);\n if (!assetUri || !targetPath) {\n throw new Error(\"asset_export requires assetUri and targetPath.\");\n }\n const exportedPath = await this.assetStore.export({ uri: assetUri }, resolve(targetPath));\n return {\n ok: true,\n assetUri,\n exportedPath,\n };\n };\n}\n\nclass AssetStatTool implements NcpTool {\n readonly name = \"asset_stat\";\n readonly description = \"Read managed asset metadata.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n assetUri: {\n type: \"string\",\n description: \"Managed asset URI to inspect.\",\n },\n },\n required: [\"assetUri\"],\n additionalProperties: false,\n };\n\n constructor(\n private readonly assetStore: LocalAssetStore,\n private readonly contentBasePath: string,\n ) {}\n\n execute = async (args: unknown): Promise<unknown> => {\n const assetUri = readOptionalString((args as { assetUri?: unknown } | null)?.assetUri);\n if (!assetUri) {\n throw new Error(\"asset_stat requires assetUri.\");\n }\n const record = await this.assetStore.statRecord(assetUri);\n if (!record) {\n return {\n ok: false,\n error: {\n code: \"not_found\",\n message: `Asset not found: ${assetUri}`,\n },\n };\n }\n return {\n ok: true,\n asset: toAssetPayload(record, this.contentBasePath),\n };\n };\n}\n\nexport function createAssetTools(params: {\n assetStore: LocalAssetStore;\n contentBasePath?: string;\n}): NcpTool[] {\n const { assetStore } = params;\n const contentBasePath = params.contentBasePath ?? \"/api/ncp/assets/content\";\n return [\n new AssetPutTool(assetStore, contentBasePath),\n new AssetExportTool(assetStore),\n new AssetStatTool(assetStore, contentBasePath),\n ];\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n ingressKeys,\n type AgentRunSendIngressPayload,\n type AgentRunSessionMessageRequestPayload,\n type Ingress,\n type IngressEnvelope,\n} from \"@nextclaw/shared\";\nimport {\n isHiddenNcpMessage,\n NcpEventType,\n type NcpAgentRunSendOptions,\n type NcpAgentSendEnvelope,\n type NcpEndpointEvent,\n type NcpMessageAbortPayload,\n type NcpRequestEnvelope,\n type NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport {\n consumeRunHandle,\n isTerminalRunEvent,\n type LiveSessionExecution,\n type MaterializedAgentRunRequest,\n normalizeRunEvent,\n normalizeSendRunEvent,\n readMessageTask,\n readMetadataString,\n readString,\n withSession,\n} from \"@kernel/utils/session-run.utils.js\";\nimport type { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport {\n resolveEffectiveModel,\n resolveSessionChannelContext,\n syncSessionThinkingPreference,\n} from \"@kernel/features/native-runtime/index.js\";\nimport type { ContextCompactionManager } from \"@kernel/features/context-compaction/index.js\";\n\nexport class AgentRunRequestManager {\n private readonly contextCompactionManager: ContextCompactionManager;\n private readonly cleanups: Array<() => Promise<void> | void> = [];\n private readonly ingress: Ingress;\n private readonly ncpSessionManager: NcpSessionManager;\n private readonly sessionRunManager: SessionRunManager;\n private disposed = false;\n private started = false;\n\n constructor(options: {\n contextCompactionManager: ContextCompactionManager;\n ingress: Ingress;\n ncpSessionManager: NcpSessionManager;\n sessionRunManager: SessionRunManager;\n }) {\n const {\n contextCompactionManager,\n ingress,\n ncpSessionManager,\n sessionRunManager,\n } = options;\n this.contextCompactionManager = contextCompactionManager;\n this.ingress = ingress;\n this.ncpSessionManager = ncpSessionManager;\n this.sessionRunManager = sessionRunManager;\n }\n\n start = (): void => {\n this.assertNotDisposed();\n if (this.started) {\n return;\n }\n this.started = true;\n this.cleanups.push(\n this.ingress.addHandler(ingressKeys.agentRun.send, this.handleSendRequest),\n this.ingress.addHandler(ingressKeys.agentRun.abort, this.handleAbortRequest),\n this.ingress.addHandler(ingressKeys.agentRun.sessionMessageRequest, this.handleSessionMessageRequest),\n );\n };\n\n dispose = async (): Promise<void> => {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n while (this.cleanups.length > 0) {\n await this.cleanups.pop()?.();\n }\n this.started = false;\n };\n\n run = (\n envelope: NcpRequestEnvelope,\n options?: NcpAgentRunSendOptions,\n ): AsyncIterable<NcpEndpointEvent> => this.iterateRun(this.materializeRunEnvelope(envelope), options);\n\n private readonly handleSendRequest = async (\n envelope: IngressEnvelope<AgentRunSendIngressPayload>,\n ): Promise<NcpRunHandle> => {\n if (!envelope.payload) {\n throw new Error(\"Invalid agent run send request.\");\n }\n const requestEnvelope = await this.materializeSendEnvelope(envelope.payload);\n return await consumeRunHandle(\n this.iterateRun(requestEnvelope),\n {\n sessionId: requestEnvelope.sessionId,\n userMessageId: requestEnvelope.message.id,\n assistantMessageId: null,\n runId: requestEnvelope.runId,\n ...(requestEnvelope.correlationId ? { correlationId: requestEnvelope.correlationId } : {}),\n },\n );\n };\n\n private readonly handleAbortRequest = async (\n envelope: IngressEnvelope<NcpMessageAbortPayload>,\n ): Promise<void> => {\n const payload = envelope.payload;\n if (!payload?.sessionId) {\n throw new Error(\"Invalid agent run abort request.\");\n }\n const activeRun = this.sessionRunManager.getActiveSessionRun(payload.sessionId);\n if (!activeRun || activeRun.closed) {\n return;\n }\n activeRun.abortHandled = true;\n activeRun.controller.abort();\n this.sessionRunManager.setActiveSessionRun(payload.sessionId, activeRun);\n await this.sessionRunManager.appendSessionEvent(payload.sessionId, {\n type: NcpEventType.MessageAbort,\n payload: {\n sessionId: payload.sessionId,\n ...(payload.messageId ? { messageId: payload.messageId } : {}),\n },\n });\n this.sessionRunManager.deleteActiveSessionRun(payload.sessionId, activeRun.runId);\n };\n\n private readonly iterateRun = async function* (\n this: AgentRunRequestManager,\n envelope: MaterializedAgentRunRequest,\n options?: NcpAgentRunSendOptions,\n ): AsyncIterable<NcpEndpointEvent> {\n const metadata = await this.prepareRunSessionMetadata(envelope.sessionId, envelope.metadata);\n const session = await this.sessionRunManager.getOrCreateLiveSession(envelope.sessionId, metadata);\n const controller = new AbortController();\n options?.signal?.addEventListener(\"abort\", () => controller.abort(), { once: true });\n const activeRun: LiveSessionExecution = {\n runId: envelope.runId,\n controller,\n requestEnvelope: structuredClone(envelope),\n abortHandled: false,\n closed: false,\n };\n this.sessionRunManager.setActiveSessionRun(session.sessionId, activeRun);\n let completedMessageSeen = false;\n\n try {\n if (!isHiddenNcpMessage(envelope.message)) {\n const messageSentEvent: NcpEndpointEvent = {\n type: NcpEventType.MessageSent,\n payload: {\n sessionId: envelope.sessionId,\n message: structuredClone(envelope.message),\n ...(envelope.correlationId ? { correlationId: envelope.correlationId } : {}),\n metadata,\n },\n };\n await this.sessionRunManager.appendSessionEvent(session.sessionId, messageSentEvent, {\n dispatchToStateManager: false,\n });\n yield messageSentEvent;\n }\n\n const runtimeInput = {\n sessionId: envelope.sessionId,\n runId: envelope.runId,\n messages: [envelope.message],\n correlationId: envelope.correlationId,\n metadata,\n };\n yield* this.contextCompactionManager.runLivePreflight({\n input: runtimeInput,\n session,\n });\n for await (const event of session.runtime.run(runtimeInput, {\n signal: activeRun.controller.signal,\n })) {\n const normalizedEvent = normalizeSendRunEvent({\n session,\n event: normalizeRunEvent(event, envelope),\n completedMessageSeen,\n });\n completedMessageSeen = normalizedEvent.completedMessageSeen;\n for (const eventToPublish of normalizedEvent.eventsToPublish) {\n await this.sessionRunManager.appendSessionEvent(session.sessionId, eventToPublish, {\n dispatchToStateManager: false,\n });\n yield eventToPublish;\n }\n }\n\n if (activeRun.controller.signal.aborted && !activeRun.abortHandled) {\n const abortEvent: NcpEndpointEvent = {\n type: NcpEventType.MessageAbort,\n payload: { sessionId: session.sessionId },\n };\n await this.sessionRunManager.appendSessionEvent(session.sessionId, abortEvent);\n yield abortEvent;\n }\n } catch (error) {\n if (!activeRun.controller.signal.aborted) {\n const runErrorEvent: NcpEndpointEvent = {\n type: NcpEventType.RunError,\n payload: {\n sessionId: envelope.sessionId,\n runId: envelope.runId,\n ...(envelope.correlationId ? { correlationId: envelope.correlationId } : {}),\n error: error instanceof Error ? error.message : String(error),\n },\n };\n await this.sessionRunManager.appendSessionEvent(session.sessionId, runErrorEvent);\n yield runErrorEvent;\n }\n } finally {\n this.sessionRunManager.deleteActiveSessionRun(session.sessionId, activeRun.runId);\n }\n };\n\n private readonly materializeSendEnvelope = async (\n envelope: AgentRunSendIngressPayload,\n ): Promise<MaterializedAgentRunRequest> => {\n const sendEnvelope = this.toNcpSendEnvelope(envelope);\n const existingSessionId = readString(sendEnvelope.sessionId) ?? readString(sendEnvelope.message.sessionId);\n if (existingSessionId) {\n return this.materializeRunEnvelope(withSession(sendEnvelope, existingSessionId));\n }\n\n const metadata = sendEnvelope.metadata ?? {};\n const createdSession = await this.ncpSessionManager.createSession({\n task: readMessageTask(sendEnvelope.message),\n title: readMetadataString(metadata, \"label\", \"title\"),\n sourceSessionMetadata: {},\n metadataOverrides: metadata,\n agentId: readMetadataString(metadata, \"agent_id\", \"agentId\"),\n model: readMetadataString(metadata, \"preferred_model\", \"model\"),\n runtime: readMetadataString(metadata, \"runtime\", \"session_type\"),\n sessionType: readMetadataString(metadata, \"session_type\", \"runtime\"),\n thinkingLevel: readMetadataString(metadata, \"preferred_thinking\", \"thinking\"),\n projectRoot: readMetadataString(metadata, \"project_root\"),\n });\n return this.materializeRunEnvelope(withSession(sendEnvelope, createdSession.sessionId));\n };\n\n private readonly toNcpSendEnvelope = (\n envelope: AgentRunSendIngressPayload,\n ): NcpAgentSendEnvelope => {\n if (Array.isArray(envelope.content)) {\n const { content, ...request } = envelope;\n return {\n ...request,\n message: {\n id: `user-message-${randomUUID()}`,\n role: \"user\",\n status: \"final\",\n timestamp: new Date().toISOString(),\n parts: structuredClone(content),\n },\n };\n }\n if (\"message\" in envelope && envelope.message) {\n return envelope;\n }\n throw new Error(\"Invalid agent run send request.\");\n };\n\n private readonly materializeRunEnvelope = (envelope: NcpRequestEnvelope): MaterializedAgentRunRequest => ({\n ...envelope,\n runId: `ncp-run-${randomUUID()}`,\n });\n\n private readonly prepareRunSessionMetadata = async (\n sessionId: string,\n requestMetadata: Record<string, unknown> = {},\n ): Promise<Record<string, unknown>> => {\n const storedSession = await this.ncpSessionManager.getSessionRecord(sessionId);\n const currentMetadata = {\n ...(storedSession?.metadata ?? {}),\n ...structuredClone(requestMetadata),\n };\n let nextMetadata = resolveEffectiveModel({\n sessionMetadata: currentMetadata,\n requestMetadata,\n fallbackModel: \"\",\n }).metadata;\n nextMetadata = syncSessionThinkingPreference({\n sessionMetadata: nextMetadata,\n requestMetadata,\n });\n nextMetadata = resolveSessionChannelContext({\n sessionMetadata: nextMetadata,\n requestMetadata,\n }).metadata;\n await this.sessionRunManager.updateSessionMetadata(sessionId, nextMetadata);\n return nextMetadata;\n };\n\n private readonly handleSessionMessageRequest = async (\n envelope: IngressEnvelope<AgentRunSessionMessageRequestPayload>,\n ): Promise<void> => {\n const request = envelope.payload;\n if (!request?.requestId || !request.sessionId || !request.message) {\n throw new Error(\"Invalid agent run session message request.\");\n }\n let terminalEventSeen = false;\n for await (const event of this.run({\n sessionId: request.sessionId,\n message: request.message,\n correlationId: request.requestId,\n })) {\n terminalEventSeen ||= isTerminalRunEvent(event);\n }\n if (!terminalEventSeen) {\n throw new Error(\"Session request completed without a final reply.\");\n }\n };\n\n private readonly assertNotDisposed = (): void => {\n if (this.disposed) {\n throw new Error(\"Agent run request manager has already been disposed.\");\n }\n };\n}\n","export const DEFAULT_AGENT_RUNTIME_ENTRY_ID = \"native\";\n","import { toDisposable, type Disposable } from \"@nextclaw/core\";\nimport type { NcpAgentRuntime } from \"@nextclaw/ncp\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\n\nexport type AgentRuntimeSessionTypeIcon = {\n kind: \"image\";\n src: string;\n alt?: string | null;\n};\n\nexport type AgentRuntimeSessionTypeOption = {\n value: string;\n label: string;\n icon?: AgentRuntimeSessionTypeIcon | null;\n ready?: boolean;\n reason?: string | null;\n reasonMessage?: string | null;\n supportedModels?: string[];\n recommendedModel?: string | null;\n cta?: {\n kind: string;\n label?: string;\n href?: string;\n } | null;\n};\n\nexport type AgentRuntimeSessionTypeDescribeParams = {\n describeMode?: \"observation\" | \"probe\";\n};\n\nexport type AgentRuntimeEntry = {\n id: string;\n label: string;\n icon?: AgentRuntimeSessionTypeIcon | null;\n type: string;\n enabled?: boolean;\n config?: Record<string, unknown>;\n};\n\nexport type AgentRuntimeProviderRegistration = {\n kind: string;\n label: string;\n createRuntime: (params: RuntimeFactoryParams) => NcpAgentRuntime;\n createRuntimeForEntry?: (params: {\n entry: AgentRuntimeEntry;\n runtimeParams: RuntimeFactoryParams;\n }) => NcpAgentRuntime;\n describeSessionType?: (params?: AgentRuntimeSessionTypeDescribeParams) => Promise<Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\"> | null | undefined>\n | Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\">\n | null\n | undefined;\n describeSessionTypeForEntry?: (params: {\n entry: AgentRuntimeEntry;\n describeParams?: AgentRuntimeSessionTypeDescribeParams;\n }) => Promise<Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\"> | null | undefined>\n | Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\">\n | null\n | undefined;\n};\n\ntype RuntimeProviderRegistrationEntry = AgentRuntimeProviderRegistration & { token: symbol };\n\nfunction normalizeIdentifier(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const normalized = value.trim().toLowerCase();\n return normalized.length > 0 ? normalized : null;\n}\n\nfunction cloneRuntimeEntry(entry: AgentRuntimeEntry): AgentRuntimeEntry {\n return {\n id: entry.id,\n label: entry.label,\n ...(entry.icon ? { icon: { ...entry.icon } } : {}),\n type: entry.type,\n enabled: entry.enabled !== false,\n config: entry.config ? { ...entry.config } : {},\n };\n}\n\nexport function normalizeAgentRuntimeSessionTypeIcon(\n value: unknown,\n): AgentRuntimeSessionTypeIcon | null {\n if (typeof value === \"string\") {\n const src = value.trim();\n return src ? { kind: \"image\", src } : null;\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n const iconRecord = value as Record<string, unknown>;\n const src = typeof iconRecord.src === \"string\" ? iconRecord.src.trim() : \"\";\n if (!src) {\n return null;\n }\n const alt =\n typeof iconRecord.alt === \"string\" && iconRecord.alt.trim().length > 0\n ? iconRecord.alt.trim()\n : null;\n return {\n kind: \"image\",\n src,\n ...(alt ? { alt } : {}),\n };\n}\n\ntype ConfigRuntimeEntry = {\n enabled?: boolean;\n label?: string;\n icon?: unknown;\n type?: string;\n config?: Record<string, unknown>;\n};\n\ntype AgentRuntimeResolverConfig = {\n ui?: {\n ncp?: {\n runtimes?: {\n native?: unknown;\n };\n };\n };\n agents: {\n runtimes: {\n entries?: Record<string, ConfigRuntimeEntry>;\n };\n };\n};\n\nconst BUILTIN_RUNTIME_PRESENTATION = {\n hermes: {\n label: \"Hermes\",\n icon: {\n kind: \"image\",\n src: \"app://runtime-icons/hermes-agent.png\",\n alt: \"Hermes\",\n },\n },\n} satisfies Record<string, { label: string; icon?: AgentRuntimeSessionTypeIcon }>;\n\ntype BuiltinRuntimePresentationKey = keyof typeof BUILTIN_RUNTIME_PRESENTATION;\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction readRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction resolveBuiltinRuntimePresentation(\n value: string | undefined,\n): { label: string; icon?: AgentRuntimeSessionTypeIcon } | null {\n const normalized = readString(value)?.toLowerCase();\n if (!normalized) {\n return null;\n }\n if (!(normalized in BUILTIN_RUNTIME_PRESENTATION)) {\n return null;\n }\n return BUILTIN_RUNTIME_PRESENTATION[normalized as BuiltinRuntimePresentationKey] ?? null;\n}\n\nfunction buildNativeRuntimeEntry(config: AgentRuntimeResolverConfig): AgentRuntimeEntry {\n const nativeRuntimeConfig = readRecord(config.ui?.ncp?.runtimes?.native) ?? {};\n return {\n id: DEFAULT_AGENT_RUNTIME_ENTRY_ID,\n label: \"Native\",\n type: DEFAULT_AGENT_RUNTIME_ENTRY_ID,\n enabled: nativeRuntimeConfig.enabled !== false,\n config: nativeRuntimeConfig,\n };\n}\n\nexport function resolveAgentRuntimeEntries(params: {\n config: AgentRuntimeResolverConfig;\n}): {\n defaultEntryId: string;\n entries: AgentRuntimeEntry[];\n} {\n const entries = new Map<string, AgentRuntimeEntry>();\n\n entries.set(DEFAULT_AGENT_RUNTIME_ENTRY_ID, buildNativeRuntimeEntry(params.config));\n\n for (const [rawId, rawEntry] of Object.entries(params.config.agents.runtimes.entries ?? {})) {\n const id = rawId.trim().toLowerCase();\n const type = readString(rawEntry.type)?.toLowerCase();\n if (!id || !type) {\n continue;\n }\n const explicitIcon = normalizeAgentRuntimeSessionTypeIcon(rawEntry.icon);\n const builtinPresentation =\n resolveBuiltinRuntimePresentation(id) ??\n resolveBuiltinRuntimePresentation(type);\n entries.set(id, {\n id,\n label: readString(rawEntry.label) ?? builtinPresentation?.label ?? id,\n ...(explicitIcon ?? builtinPresentation?.icon\n ? { icon: explicitIcon ?? builtinPresentation?.icon }\n : {}),\n type,\n enabled: rawEntry.enabled !== false,\n config: rawEntry.config ? { ...rawEntry.config } : {},\n });\n }\n\n const defaultEntryId = entries.has(DEFAULT_AGENT_RUNTIME_ENTRY_ID)\n ? DEFAULT_AGENT_RUNTIME_ENTRY_ID\n : [...entries.keys()][0] ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n return {\n defaultEntryId,\n entries: [...entries.values()],\n };\n}\n\nfunction readRequestedRuntimeEntryId(sessionMetadata: Record<string, unknown>): string | null {\n return (\n normalizeIdentifier(sessionMetadata.runtime) ??\n normalizeIdentifier(sessionMetadata.session_type) ??\n normalizeIdentifier(sessionMetadata.sessionType) ??\n null\n );\n}\n\nexport class AgentRuntimeRegistry {\n private readonly providers = new Map<string, RuntimeProviderRegistrationEntry>();\n private entries = new Map<string, AgentRuntimeEntry>();\n private defaultEntryId = DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n\n register = (registration: AgentRuntimeProviderRegistration): Disposable => {\n const normalizedKind = normalizeIdentifier(registration.kind);\n if (!normalizedKind) {\n throw new Error(\"agent runtime kind must be a non-empty string\");\n }\n\n const token = Symbol(normalizedKind);\n this.providers.set(normalizedKind, {\n ...registration,\n kind: normalizedKind,\n token,\n });\n\n return toDisposable(() => {\n const current = this.providers.get(normalizedKind);\n if (!current || current.token !== token) {\n return;\n }\n this.providers.delete(normalizedKind);\n });\n };\n\n applyEntries = (params: {\n entries: AgentRuntimeEntry[];\n defaultEntryId?: string;\n }): void => {\n const nextEntries = new Map<string, AgentRuntimeEntry>();\n for (const rawEntry of params.entries) {\n const id = normalizeIdentifier(rawEntry.id);\n const type = normalizeIdentifier(rawEntry.type);\n const label = rawEntry.label?.trim() ?? \"\";\n if (!id || !type || !label) {\n continue;\n }\n nextEntries.set(id, cloneRuntimeEntry({\n ...rawEntry,\n id,\n type,\n label,\n }));\n }\n this.entries = nextEntries;\n this.defaultEntryId =\n normalizeIdentifier(params.defaultEntryId) ??\n (nextEntries.has(DEFAULT_AGENT_RUNTIME_ENTRY_ID)\n ? DEFAULT_AGENT_RUNTIME_ENTRY_ID\n : [...nextEntries.keys()][0] ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID);\n };\n\n resolveSessionMetadata = (sessionMetadata: Record<string, unknown>): Record<string, unknown> => {\n const { entry } = this.resolveRuntimeEntry(sessionMetadata);\n return {\n ...sessionMetadata,\n runtime: entry.id,\n session_type: entry.id,\n runtime_type: entry.type,\n };\n };\n\n createRuntime = (params: RuntimeFactoryParams): NcpAgentRuntime => {\n const nextSessionMetadata = this.resolveSessionMetadata(params.sessionMetadata);\n const { entry, provider } = this.resolveRuntimeEntry(nextSessionMetadata);\n if (provider.createRuntimeForEntry) {\n return provider.createRuntimeForEntry({\n entry: cloneRuntimeEntry(entry),\n runtimeParams: {\n ...params,\n sessionMetadata: nextSessionMetadata,\n },\n });\n }\n return provider.createRuntime({\n ...params,\n sessionMetadata: nextSessionMetadata,\n });\n };\n\n private resolveRuntimeEntry = (sessionMetadata: Record<string, unknown>) => {\n const requestedEntryId =\n readRequestedRuntimeEntryId(sessionMetadata) ?? this.defaultEntryId;\n const entry = this.entries.get(requestedEntryId);\n if (!entry || entry.enabled === false) {\n throw new Error(`ncp runtime unavailable: ${requestedEntryId}`);\n }\n\n const provider = this.providers.get(entry.type);\n if (!provider) {\n throw new Error(`ncp runtime provider unavailable: ${entry.type}`);\n }\n return { entry, provider };\n };\n\n listSessionTypes = async (params?: AgentRuntimeSessionTypeDescribeParams): Promise<{\n defaultType: string;\n options: AgentRuntimeSessionTypeOption[];\n }> => {\n const options = await Promise.all(\n [...this.entries.values()]\n .filter((entry) => entry.enabled !== false)\n .map(async (entry) => {\n const provider = this.providers.get(entry.type);\n if (!provider) {\n return {\n value: entry.id,\n label: entry.label,\n icon: entry.icon ?? null,\n ready: false,\n reason: \"runtime_provider_unavailable\",\n reasonMessage: `Runtime provider unavailable for type \"${entry.type}\".`,\n recommendedModel: null,\n cta: {\n kind: \"settings\",\n label: \"Configure Runtime\",\n },\n } satisfies AgentRuntimeSessionTypeOption;\n }\n\n const descriptor = provider.describeSessionTypeForEntry\n ? await provider.describeSessionTypeForEntry({\n entry: cloneRuntimeEntry(entry),\n describeParams: params,\n })\n : await provider.describeSessionType?.(params);\n return {\n value: entry.id,\n label: entry.label,\n icon: descriptor?.icon ?? entry.icon ?? null,\n ready: descriptor?.ready ?? true,\n reason: descriptor?.reason ?? null,\n reasonMessage: descriptor?.reasonMessage ?? null,\n recommendedModel: descriptor?.recommendedModel ?? null,\n cta: descriptor?.cta ?? null,\n ...(descriptor?.supportedModels ? { supportedModels: descriptor.supportedModels } : {}),\n } satisfies AgentRuntimeSessionTypeOption;\n }),\n );\n\n return {\n defaultType: this.defaultEntryId,\n options: options.sort((left, right) => {\n if (left.value === this.defaultEntryId) {\n return -1;\n }\n if (right.value === this.defaultEntryId) {\n return 1;\n }\n return left.value.localeCompare(right.value);\n }),\n };\n };\n}\n","import {\n type Disposable,\n type Config,\n} from \"@nextclaw/core\";\nimport type { LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\nimport {\n AgentRuntimeRegistry,\n type AgentRuntimeSessionTypeDescribeParams,\n type AgentRuntimeProviderRegistration,\n resolveAgentRuntimeEntries,\n} from \"@kernel/features/runtime-registry/index.js\";\n\n\nexport type AgentRuntimeManagerOptions = {\n configManager: { loadConfig: () => Config };\n assetStore: LocalAssetStore;\n};\n\nexport class AgentRuntimeManager {\n private readonly runtimeRegistry = new AgentRuntimeRegistry();\n private readonly refreshConfiguredRuntimeEntries = () => {\n this.runtimeRegistry.applyEntries(\n resolveAgentRuntimeEntries({\n config: this.params.configManager.loadConfig(),\n }),\n );\n };\n\n private disposed = false;\n\n constructor(private readonly params: AgentRuntimeManagerOptions) {}\n\n registerRuntimeProvider = (registration: AgentRuntimeProviderRegistration): Disposable => {\n this.assertNotDisposed();\n const disposable = this.runtimeRegistry.register(registration);\n this.refreshConfiguredRuntimeEntries();\n return disposable;\n };\n\n createRuntime = (runtimeParams: RuntimeFactoryParams) => {\n this.assertNotDisposed();\n this.refreshConfiguredRuntimeEntries();\n return this.runtimeRegistry.createRuntime({\n ...runtimeParams,\n resolveAssetContentPath: (assetUri) => this.params.assetStore.resolveContentPath(assetUri),\n });\n };\n\n resolveSessionMetadata = (sessionMetadata: Record<string, unknown>): Record<string, unknown> => {\n this.assertNotDisposed();\n this.refreshConfiguredRuntimeEntries();\n return this.runtimeRegistry.resolveSessionMetadata(sessionMetadata);\n };\n\n listSessionTypes = (describeParams?: AgentRuntimeSessionTypeDescribeParams) => {\n this.refreshConfiguredRuntimeEntries();\n return this.runtimeRegistry.listSessionTypes(describeParams);\n };\n\n dispose = async (): Promise<void> => {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n };\n\n private readonly assertNotDisposed = (): void => {\n if (this.disposed) {\n throw new Error(\"Agent runtime has already been disposed.\");\n }\n };\n}\n","import { CronService } from \"@nextclaw/core\";\n\nexport type AutomationManagerOptions = {\n storePath: string;\n};\n\nexport class AutomationManager extends CronService {\n constructor(options: AutomationManagerOptions) {\n super(options.storePath);\n }\n}\n","import {\n buildConfigSchema,\n buildReloadPlan,\n ConfigSchema,\n diffConfigPaths,\n getConfigPath,\n loadConfig,\n normalizeInlineSecretRefs,\n redactConfigObject,\n resolveConfigSecrets,\n saveConfig,\n type ChannelManager,\n type Config,\n type ExtensionRegistry,\n} from \"@nextclaw/core\";\nimport { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type { LlmProviderManager } from \"./llm-provider.manager.js\";\n\nexport type ConfigManagerRuntimeHooks = {\n resolveChannelConfig?: (config: Config) => Config;\n getExtensionChannels?: () => ExtensionRegistry[\"channels\"];\n applyAgentRuntimeConfig?: (config: Config) => void;\n reloadCompanion?: (params: { config: Config; changedPaths: string[] }) => Promise<void> | void;\n reloadMcp?: (params: { config: Config; changedPaths: string[] }) => Promise<void> | void;\n onRestartRequired?: (paths: string[]) => void;\n};\n\nexport type ConfigManagerOptions = {\n configPath?: string;\n channels: ChannelManager;\n providerManager: LlmProviderManager;\n};\n\nexport type ConfigMutationResult = Record<string, unknown> & { ok: boolean; error?: string };\n\ntype ConfigSnapshot = { raw: string | null; hash: string | null; config: Config; redacted: Record<string, unknown>; valid: boolean };\ntype RawConfigMutationParams = { raw: string; baseHash?: string; note?: string; version?: string };\n\nconst hashRaw = (raw: string): string => createHash(\"sha256\").update(raw).digest(\"hex\");\n\nconst mergeDeep = (base: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown> => {\n const next: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(patch)) {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const baseVal = base[key];\n next[key] = baseVal && typeof baseVal === \"object\" && !Array.isArray(baseVal)\n ? mergeDeep(baseVal as Record<string, unknown>, value as Record<string, unknown>)\n : mergeDeep({}, value as Record<string, unknown>);\n continue;\n }\n next[key] = value;\n }\n return next;\n};\n\nexport class ConfigManager {\n readonly configPath: string;\n private currentConfig: Config;\n private hooks: ConfigManagerRuntimeHooks = {};\n private reloadTask: Promise<void> | null = null;\n private providerReloadTask: Promise<void> | null = null;\n private reloadTimer: ReturnType<typeof setTimeout> | null = null;\n private reloadRunning = false;\n private reloadPending = false;\n\n constructor(private readonly options: ConfigManagerOptions) {\n this.configPath = options.configPath ?? getConfigPath();\n this.currentConfig = this.loadConfig();\n this.options.providerManager.load(this.currentConfig);\n this.options.channels.load({\n channelConfig: this.resolveChannelConfig(this.currentConfig),\n extensionChannels: this.resolveExtensionChannels(),\n });\n }\n\n get config(): Config {\n return this.currentConfig;\n }\n\n loadConfig = (): Config =>\n resolveConfigSecrets(loadConfig(this.configPath), { configPath: this.configPath });\n\n getDefaultModel = (): string =>\n this.loadConfig().agents.defaults.model;\n\n getModelMaxTokens = (model: string): number | undefined => {\n const value = this.loadConfig().agents.defaults.models[model]?.params?.max_tokens;\n return typeof value === \"number\" ? Math.trunc(value) : undefined;\n };\n\n installRuntimeHooks = (hooks: ConfigManagerRuntimeHooks): void => {\n this.hooks = { ...this.hooks, ...hooks };\n };\n\n applyLiveConfigReload = async (): Promise<void> => {\n await this.applyReloadPlan(this.loadConfig());\n };\n\n applyReloadPlan = async (nextConfig: Config): Promise<void> => {\n const changedPaths = diffConfigPaths(this.currentConfig, nextConfig);\n if (!changedPaths.length) {\n return;\n }\n this.currentConfig = nextConfig;\n const plan = buildReloadPlan(changedPaths);\n\n if (plan.reloadMcp) {\n await this.reloadMcp({\n config: nextConfig,\n changedPaths,\n });\n console.log(\"Config reload: MCP servers reloaded.\");\n }\n if (plan.reloadCompanion) {\n await this.reloadCompanion({\n config: nextConfig,\n changedPaths,\n });\n console.log(\"Config reload: companion setting applied.\");\n }\n if (plan.restartChannels) {\n await this.rebuildChannels(nextConfig, { start: true });\n console.log(\"Config reload: channels restarted.\");\n }\n if (plan.reloadProviders) {\n await this.reloadProvider(nextConfig);\n console.log(\"Config reload: provider settings applied.\");\n }\n if (plan.reloadAgent) {\n this.hooks.applyAgentRuntimeConfig?.(nextConfig);\n console.log(\"Config reload: agent defaults applied.\");\n }\n if (plan.restartRequired.length > 0) {\n this.hooks.onRestartRequired?.(plan.restartRequired);\n }\n };\n\n getConfigSnapshot = (params: { version?: string } = {}): Record<string, unknown> => {\n const { hash, raw, redacted, valid } = this.readConfigSnapshot(params);\n return {\n raw,\n hash,\n path: this.configPath,\n config: redacted,\n parsed: redacted,\n resolved: redacted,\n valid,\n };\n };\n\n getConfigSchema = (params: { version?: string } = {}): Record<string, unknown> => buildConfigSchema({ version: params.version });\n\n applyRawConfig = async (params: RawConfigMutationParams): Promise<ConfigMutationResult> =>\n this.mutateRawConfig(params, (_snapshot, parsed) => parsed);\n\n patchRawConfig = async (params: RawConfigMutationParams): Promise<ConfigMutationResult> =>\n this.mutateRawConfig(params, (snapshot, patch) => mergeDeep(snapshot.config as Record<string, unknown>, patch));\n\n scheduleReload = (reason: string): void => {\n if (this.reloadTimer) {\n clearTimeout(this.reloadTimer);\n }\n this.reloadTimer = setTimeout(() => {\n void this.runReload(reason);\n }, 300);\n };\n\n runReload = async (reason: string): Promise<void> => {\n if (this.reloadRunning) {\n this.reloadPending = true;\n return;\n }\n this.reloadRunning = true;\n if (this.reloadTimer) {\n clearTimeout(this.reloadTimer);\n this.reloadTimer = null;\n }\n try {\n await this.applyLiveConfigReload();\n } catch (error) {\n console.error(`Config reload failed (${reason}): ${String(error)}`);\n } finally {\n this.reloadRunning = false;\n if (this.reloadPending) {\n this.reloadPending = false;\n this.scheduleReload(\"pending\");\n }\n }\n };\n\n reloadConfig = async (reason?: string): Promise<string> => {\n await this.runReload(reason ?? \"gateway tool\");\n return \"Config reload triggered\";\n };\n\n rebuildChannels = async (nextConfig: Config, options: { start?: boolean } = {}): Promise<void> => {\n if (this.reloadTask) {\n await this.reloadTask;\n return;\n }\n this.reloadTask = (async () => {\n await this.options.channels.reload({\n channelConfig: this.resolveChannelConfig(nextConfig),\n extensionChannels: this.resolveExtensionChannels(),\n start: options.start ?? true,\n });\n })();\n try {\n await this.reloadTask;\n } finally {\n this.reloadTask = null;\n }\n };\n\n private resolveChannelConfig = (config: Config): Config =>\n this.hooks.resolveChannelConfig?.(config) ?? config;\n\n private resolveExtensionChannels = (): ExtensionRegistry[\"channels\"] =>\n this.hooks.getExtensionChannels?.() ?? [];\n\n private reloadProvider = async (nextConfig: Config): Promise<void> => {\n if (this.providerReloadTask) {\n await this.providerReloadTask;\n return;\n }\n this.providerReloadTask = (async () => {\n this.options.providerManager.load(nextConfig);\n })();\n try {\n await this.providerReloadTask;\n } finally {\n this.providerReloadTask = null;\n }\n };\n\n private reloadMcp = async (params: {\n config: Config;\n changedPaths: string[];\n }): Promise<void> => {\n await this.hooks.reloadMcp?.(params);\n };\n\n private reloadCompanion = async (params: {\n config: Config;\n changedPaths: string[];\n }): Promise<void> => {\n await this.hooks.reloadCompanion?.(params);\n };\n\n private readConfigSnapshot = (params: { version?: string } = {}): ConfigSnapshot => {\n let raw = \"\";\n let parsed: Record<string, unknown> = {};\n if (existsSync(this.configPath)) {\n raw = readFileSync(this.configPath, \"utf-8\");\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n parsed = {};\n }\n }\n\n let config: Config;\n let valid = true;\n try {\n config = ConfigSchema.parse(normalizeInlineSecretRefs(parsed));\n } catch {\n config = ConfigSchema.parse({});\n valid = false;\n }\n if (!raw) {\n raw = JSON.stringify(config, null, 2);\n }\n const hash = hashRaw(raw);\n return {\n raw: valid ? JSON.stringify(this.redactConfig(config, params), null, 2) : null,\n hash: valid ? hash : null,\n config,\n redacted: this.redactConfig(config, params),\n valid,\n };\n };\n\n private redactConfig = (config: Config, params: { version?: string } = {}): Record<string, unknown> => {\n const schema = buildConfigSchema({ version: params.version });\n return redactConfigObject(config, schema.uiHints) as Record<string, unknown>;\n };\n\n private validateBaseHash = (baseHash: string | undefined, snapshot: ConfigSnapshot): ConfigMutationResult | null => {\n if (!baseHash) {\n return { ok: false, error: \"config base hash required; re-run config.get and retry\" };\n }\n if (!snapshot.valid || !snapshot.hash) {\n return { ok: false, error: \"config base hash unavailable; re-run config.get and retry\" };\n }\n if (baseHash !== snapshot.hash) {\n return { ok: false, error: \"config changed since last load; re-run config.get and retry\" };\n }\n return null;\n };\n\n private validateConfigInput = (input: Record<string, unknown>): { ok: true; config: Config } | { ok: false; error: string } => {\n try {\n return { ok: true, config: ConfigSchema.parse(normalizeInlineSecretRefs(input)) };\n } catch (error) {\n return { ok: false, error: `invalid config: ${String(error)}` };\n }\n };\n\n private mutateRawConfig = async (\n params: RawConfigMutationParams,\n resolveInput: (snapshot: ConfigSnapshot, parsed: Record<string, unknown>) => Record<string, unknown>,\n ): Promise<ConfigMutationResult> => {\n const { baseHash, note, raw, version } = params;\n const snapshot = this.readConfigSnapshot({ version });\n const baseHashValidation = this.validateBaseHash(baseHash, snapshot);\n if (baseHashValidation) {\n return baseHashValidation;\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return { ok: false, error: \"invalid JSON in raw config\" };\n }\n\n const validated = this.validateConfigInput(resolveInput(snapshot, parsed));\n return validated.ok\n ? this.applyConfigChange({ nextConfig: validated.config, note, version })\n : validated;\n };\n\n private applyConfigChange = async (params: {\n nextConfig: Config;\n note?: string;\n version?: string;\n }): Promise<ConfigMutationResult> => {\n const { nextConfig, note, version } = params;\n const changedPaths = diffConfigPaths(this.readConfigSnapshot({ version }).config, nextConfig);\n\n if (changedPaths.length === 0) {\n return this.createConfigMutationResult({\n changedPaths,\n config: nextConfig,\n note,\n version,\n });\n }\n\n saveConfig(nextConfig, this.configPath);\n await this.applyReloadPlan(nextConfig);\n return this.createConfigMutationResult({\n changedPaths,\n config: nextConfig,\n note,\n version,\n });\n };\n\n private createConfigMutationResult = (params: {\n changedPaths: string[];\n config: Config;\n note?: string;\n version?: string;\n }): ConfigMutationResult => {\n const { changedPaths, config, note, version } = params;\n const plan = buildReloadPlan(changedPaths);\n const pendingRestart =\n plan.restartRequired.length > 0\n ? {\n required: true as const,\n automatic: false as const,\n changedPaths: [...plan.restartRequired],\n message: `Config saved. Restart manually to apply: ${plan.restartRequired.join(\", \")}.`,\n }\n : null;\n const message =\n changedPaths.length === 0\n ? \"Config already matched the requested state.\"\n : pendingRestart\n ? changedPaths.length > plan.restartRequired.length\n ? \"Config saved. Supported changes were applied immediately; restart manually to apply the rest.\"\n : \"Config saved. Restart manually to apply changes.\"\n : \"Config saved and applied.\";\n\n return {\n ok: true,\n note: note ?? null,\n path: this.configPath,\n config: this.redactConfig(config, { version }),\n changedPaths: [...changedPaths],\n message,\n pendingRestart,\n };\n };\n}\n","import { spawn } from \"node:child_process\";\nimport type {\n ExtensionManifest,\n RunningExtensionProcess,\n} from \"@kernel/features/extension-runtime/index.js\";\n\nfunction sanitizeExtensionNodeOptions(value: string | undefined): string | undefined {\n if (!value?.trim()) {\n return undefined;\n }\n const tokens = value.split(/\\s+/).filter(Boolean);\n const sanitized: string[] = [];\n for (let index = 0; index < tokens.length; index += 1) {\n const token = tokens[index];\n if (token === \"--conditions=development\" || token === \"-C=development\") {\n continue;\n }\n if ((token === \"--conditions\" || token === \"-C\") && tokens[index + 1] === \"development\") {\n index += 1;\n continue;\n }\n sanitized.push(token);\n }\n return sanitized.length > 0 ? sanitized.join(\" \") : undefined;\n}\n\nexport class ExtensionLifecycleService {\n private readonly processes = new Map<string, RunningExtensionProcess>();\n\n startAll = (manifests: ExtensionManifest[], params: {\n endpoint: string;\n token: string;\n }): RunningExtensionProcess[] => {\n const started: RunningExtensionProcess[] = [];\n for (const manifest of manifests) {\n try {\n started.push(this.start(manifest, params));\n } catch (error) {\n console.warn(`Extension ${manifest.id} failed to start: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n return started;\n };\n\n stopAll = async (): Promise<void> => {\n const processes = [...this.processes.values()];\n this.processes.clear();\n await Promise.all(processes.map(async ({ process }) => {\n if (process.exitCode !== null || process.signalCode !== null) {\n return;\n }\n process.kill();\n await new Promise<void>((resolvePromise) => {\n process.once(\"exit\", () => resolvePromise());\n process.once(\"error\", () => resolvePromise());\n setTimeout(resolvePromise, 1000).unref();\n });\n }));\n };\n\n private start = (\n manifest: ExtensionManifest,\n params: {\n endpoint: string;\n token: string;\n },\n ): RunningExtensionProcess => {\n const existing = this.processes.get(manifest.id);\n if (existing) {\n return existing;\n }\n const command = manifest.server.command === \"node\" || manifest.server.command === \"node.exe\"\n ? process.execPath\n : manifest.server.command;\n const child = spawn(command, manifest.server.args ?? [], {\n cwd: manifest.rootDir,\n env: {\n ...process.env,\n NODE_OPTIONS: sanitizeExtensionNodeOptions(process.env.NODE_OPTIONS),\n ...manifest.server.env,\n NEXTCLAW_EXTENSION_ID: manifest.id,\n NEXTCLAW_EXTENSION_ENDPOINT: params.endpoint,\n NEXTCLAW_EXTENSION_TOKEN: params.token,\n },\n stdio: [\"ignore\", \"ignore\", \"inherit\"],\n windowsHide: true,\n });\n const running = { manifest, process: child };\n this.processes.set(manifest.id, running);\n child.once(\"exit\", () => {\n if (this.processes.get(manifest.id)?.process === child) {\n this.processes.delete(manifest.id);\n }\n console.warn(`Extension ${manifest.id} exited.`);\n });\n child.once(\"error\", (error) => {\n console.warn(`Extension ${manifest.id} failed: ${error.message}`);\n });\n return running;\n };\n}\n","import { getDataPath } from \"@nextclaw/core\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { Config, ExtensionManifest } from \"@kernel/features/extension-runtime/index.js\";\n\nconst EXTENSION_MANIFEST_FILE = \"nextclaw.extension.json\";\nconst BUILTIN_EXTENSION_PACKAGES = [\n \"@nextclaw/channel-extension-dingtalk\",\n \"@nextclaw/channel-extension-discord\",\n \"@nextclaw/channel-extension-email\",\n \"@nextclaw/channel-extension-feishu\",\n \"@nextclaw/channel-extension-qq\",\n \"@nextclaw/channel-extension-slack\",\n \"@nextclaw/channel-extension-telegram\",\n \"@nextclaw/channel-extension-wecom\",\n \"@nextclaw/channel-extension-whatsapp\",\n \"@nextclaw/channel-extension-weixin\",\n] as const;\nconst runtimeRequire = createRequire(import.meta.url);\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readStringArray(value: unknown): string[] | undefined {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\") ? value : undefined;\n}\n\nfunction readStringRecord(value: unknown): Record<string, string> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n const entries = Object.entries(value);\n return entries.every(([, item]) => typeof item === \"string\")\n ? Object.fromEntries(entries) as Record<string, string>\n : undefined;\n}\n\nfunction readRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {};\n}\n\nfunction uniquePaths(paths: string[]): string[] {\n const seen = new Set<string>();\n const unique: string[] = [];\n for (const path of paths) {\n const normalized = resolve(path);\n if (!seen.has(normalized)) {\n seen.add(normalized);\n unique.push(normalized);\n }\n }\n return unique;\n}\n\nfunction findExtensionManifestRoot(startPath: string): string | undefined {\n let current = resolve(startPath);\n while (true) {\n if (existsSync(join(current, EXTENSION_MANIFEST_FILE))) {\n return current;\n }\n const parent = dirname(current);\n if (parent === current) {\n return undefined;\n }\n current = parent;\n }\n}\n\nfunction resolveDevFirstPartyExtensionDir(\n explicitDir = process.env.NEXTCLAW_DEV_FIRST_PARTY_EXTENSION_DIR,\n moduleDir = dirname(fileURLToPath(import.meta.url)),\n): string | undefined {\n const configured = explicitDir?.trim();\n if (configured) {\n return configured;\n }\n const candidates = [\n resolve(moduleDir, \"../../extensions\"),\n resolve(moduleDir, \"../../../extensions\"),\n resolve(moduleDir, \"../../../../extensions\"),\n resolve(moduleDir, \"../../../../../extensions\"),\n ];\n return candidates.find((candidate) => existsSync(candidate));\n}\n\nfunction toManifest(value: unknown, rootDir: string): ExtensionManifest {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(\"extension manifest must be an object\");\n }\n const record = value as Record<string, unknown>;\n const server = readRecord(record.server);\n const id = readString(record.id);\n const command = readString(server.command);\n if (!id) {\n throw new Error(\"extension manifest id is required\");\n }\n if (server.type !== \"stdio\") {\n throw new Error(\"extension server.type must be stdio\");\n }\n if (!command) {\n throw new Error(\"extension server.command is required\");\n }\n return {\n id,\n rootDir,\n ...(readString(record.name) ? { name: readString(record.name) } : {}),\n ...(readString(record.version) ? { version: readString(record.version) } : {}),\n server: {\n type: \"stdio\",\n command,\n ...(readStringArray(server.args) ? { args: readStringArray(server.args) } : {}),\n ...(readStringRecord(server.env) ? { env: readStringRecord(server.env) } : {}),\n },\n ...(record.contributes && typeof record.contributes === \"object\" && !Array.isArray(record.contributes)\n ? { contributes: record.contributes as ExtensionManifest[\"contributes\"] }\n : {}),\n };\n}\n\nexport function resolveBuiltinExtensionManifestRoots(): string[] {\n if (process.env.NEXTCLAW_DISABLE_BUILTIN_EXTENSIONS === \"1\") {\n return [];\n }\n const roots: string[] = [];\n for (const packageName of BUILTIN_EXTENSION_PACKAGES) {\n try {\n const entryPath = runtimeRequire.resolve(packageName);\n const root = findExtensionManifestRoot(dirname(entryPath));\n if (root) {\n roots.push(root);\n }\n } catch {\n // Built-in packages can be omitted by some development package manager installs.\n }\n }\n return uniquePaths(roots);\n}\n\nexport function resolveExtensionManifestRoots(params: {\n config: Config;\n workspace: string;\n}): string[] {\n const devExtensionsDir = resolveDevFirstPartyExtensionDir();\n return uniquePaths([\n join(getDataPath(), \"extensions\"),\n join(params.workspace, \".nextclaw\", \"extensions\"),\n ...(devExtensionsDir ? [devExtensionsDir] : []),\n ...resolveBuiltinExtensionManifestRoots(),\n ]);\n}\n\nexport class ExtensionManifestDiscoveryService {\n discover = async (roots: string[]): Promise<ExtensionManifest[]> => {\n const manifests: ExtensionManifest[] = [];\n for (const root of roots) {\n manifests.push(...(await this.discoverRoot(root)));\n }\n return this.uniqueById(manifests);\n };\n\n discoverSync = (roots: string[]): ExtensionManifest[] => {\n const manifests: ExtensionManifest[] = [];\n for (const root of roots) {\n manifests.push(...this.discoverRootSync(root));\n }\n return this.uniqueById(manifests);\n };\n\n private uniqueById = (manifests: ExtensionManifest[]): ExtensionManifest[] => {\n const seen = new Set<string>();\n const unique: ExtensionManifest[] = [];\n for (const manifest of manifests) {\n if (seen.has(manifest.id)) {\n continue;\n }\n seen.add(manifest.id);\n unique.push(manifest);\n }\n return unique;\n };\n\n private discoverRoot = async (root: string): Promise<ExtensionManifest[]> => {\n const directManifest = await this.readManifestIfExists(join(root, EXTENSION_MANIFEST_FILE));\n if (directManifest) {\n return [directManifest];\n }\n const entries = await readdir(root, { withFileTypes: true }).catch(() => []);\n const manifests = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => this.readManifestIfExists(join(root, entry.name, EXTENSION_MANIFEST_FILE))),\n );\n return manifests.filter((manifest): manifest is ExtensionManifest => Boolean(manifest));\n };\n\n private discoverRootSync = (root: string): ExtensionManifest[] => {\n const directManifest = this.readManifestIfExistsSync(join(root, EXTENSION_MANIFEST_FILE));\n if (directManifest) {\n return [directManifest];\n }\n return this.readDirectoriesSync(root)\n .map((entry) => this.readManifestIfExistsSync(join(root, entry, EXTENSION_MANIFEST_FILE)))\n .filter((manifest): manifest is ExtensionManifest => Boolean(manifest));\n };\n\n private readManifestIfExists = async (path: string): Promise<ExtensionManifest | null> => {\n try {\n return toManifest(JSON.parse(await readFile(path, \"utf-8\")), dirname(path));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n };\n\n private readManifestIfExistsSync = (path: string): ExtensionManifest | null => {\n try {\n return toManifest(JSON.parse(readFileSync(path, \"utf-8\")), dirname(path));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n };\n\n private readDirectoriesSync = (root: string): string[] => {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n } catch {\n return [];\n }\n };\n}\n","import type { Config } from \"@nextclaw/core\";\nimport {\n ExtensionManifestDiscoveryService,\n resolveExtensionManifestRoots,\n} from \"@kernel/features/extension-runtime/index.js\";\n\nexport function listExtensionChannelIds(params: {\n config: Config;\n workspace: string;\n}): string[] {\n const discovery = new ExtensionManifestDiscoveryService();\n const manifests = discovery.discoverSync(resolveExtensionManifestRoots(params));\n const channelIds: string[] = [];\n for (const manifest of manifests) {\n for (const channel of manifest.contributes?.channels ?? []) {\n const channelId = typeof channel.id === \"string\" ? channel.id.trim() : \"\";\n if (channelId && !channelIds.includes(channelId)) {\n channelIds.push(channelId);\n }\n }\n }\n return channelIds;\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n ingressKeys,\n type ExtensionChannelCommandExecuteIngressPayload,\n type ExtensionChannelCommandListIngressPayload,\n type ExtensionChannelConfigGetIngressPayload,\n type ExtensionChannelMessageSubmitIngressPayload,\n type ExtensionResponseIngressPayload,\n type IngressContext,\n type IngressEnvelope,\n} from \"@nextclaw/shared\";\nimport { AgentRouteResolver, CommandRegistry } from \"@nextclaw/core\";\nimport type {\n ExtensionChannelAuthConnectResult,\n ExtensionChannelAuthLoginResult,\n ExtensionChannelAuthPollResult,\n ExtensionChannelAuthStartResult,\n ExtensionChannelBinding,\n ExtensionUiMetadata,\n} from \"@nextclaw/core\";\nimport {\n ExtensionLifecycleService,\n ExtensionManifestDiscoveryService,\n resolveExtensionManifestRoots,\n type Config,\n type ExtensionChannelRequestKind,\n type ExtensionManifest,\n type ExtensionRequestSender,\n type ExtensionRuntimeContributions,\n type ExtensionRuntimeServiceOptions,\n type InboundAttachment,\n type InboundMessage,\n type PendingExtensionRequest,\n} from \"@kernel/features/extension-runtime/index.js\";\n\nconst EXTENSION_REQUEST_EVENT_TYPE = \"extension.request\";\nconst EXTENSION_REQUEST_TIMEOUT_MS = 60_000;\n\ntype ExtensionChannelAuthClient = NonNullable<ExtensionChannelBinding[\"channel\"][\"auth\"]>;\ntype ExtensionChannelOutbound = NonNullable<ExtensionChannelBinding[\"channel\"][\"outbound\"]>;\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readRecord(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {};\n}\n\nfunction readRequiredString(value: unknown, name: string): string {\n const trimmed = readString(value);\n if (!trimmed) {\n throw new Error(`${name} is required`);\n }\n return trimmed;\n}\n\nfunction readTextContent(value: unknown): string {\n const content = readRecord(value);\n if (content.type !== \"text\" || typeof content.text !== \"string\") {\n throw new Error(\"only text channel messages are supported by the first ingress bridge\");\n }\n return content.text;\n}\n\nfunction readOptionalNumber(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction readInboundAttachments(value: unknown): InboundAttachment[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .filter((entry): entry is Record<string, unknown> =>\n Boolean(entry && typeof entry === \"object\" && !Array.isArray(entry))\n )\n .map((entry) => ({\n ...(readString(entry.id) ? { id: readString(entry.id) } : {}),\n ...(readString(entry.name) ? { name: readString(entry.name) } : {}),\n ...(readString(entry.path) ? { path: readString(entry.path) } : {}),\n ...(readString(entry.url) ? { url: readString(entry.url) } : {}),\n ...(readString(entry.assetUri) ? { assetUri: readString(entry.assetUri) } : {}),\n ...(readString(entry.mimeType) ? { mimeType: readString(entry.mimeType) } : {}),\n ...(readOptionalNumber(entry.size) !== undefined ? { size: readOptionalNumber(entry.size) } : {}),\n ...(readString(entry.source) ? { source: readString(entry.source) } : {}),\n ...(entry.status === \"ready\" || entry.status === \"remote-only\" ? { status: entry.status } : {}),\n ...(readString(entry.errorCode) ? { errorCode: readString(entry.errorCode) as InboundAttachment[\"errorCode\"] } : {}),\n }));\n}\n\nfunction toInboundMessage(value: unknown): InboundMessage {\n const payload = readRecord(value);\n return {\n channel: readRequiredString(payload.channelId, \"channelId\"),\n chatId: readRequiredString(payload.conversationId, \"conversationId\"),\n senderId: readRequiredString(payload.senderId, \"senderId\"),\n content: readTextContent(payload.content),\n timestamp: new Date(),\n attachments: readInboundAttachments(payload.attachments),\n metadata: readRecord(payload.metadata),\n };\n}\n\nfunction normalizeChannelConfigResult(value: unknown): Record<string, unknown> {\n const record = readRecord(value);\n return readRecord(record.channelConfig);\n}\n\nfunction normalizeAuthLoginResult(value: unknown): ExtensionChannelAuthLoginResult {\n const record = readRecord(value);\n return {\n channelConfig: normalizeChannelConfigResult(record),\n accountId: typeof record.accountId === \"string\" ? record.accountId : null,\n notes: Array.isArray(record.notes) ? record.notes.filter((note): note is string => typeof note === \"string\") : [],\n };\n}\n\nfunction normalizeAuthPollResult(value: unknown): ExtensionChannelAuthPollResult | null {\n if (!value) {\n return null;\n }\n const record = readRecord(value);\n return {\n channel: readRequiredString(record.channel, \"channel\"),\n status: record.status as ExtensionChannelAuthPollResult[\"status\"],\n message: readString(record.message),\n nextPollMs: readOptionalNumber(record.nextPollMs),\n accountId: typeof record.accountId === \"string\" ? record.accountId : null,\n notes: Array.isArray(record.notes) ? record.notes.filter((note): note is string => typeof note === \"string\") : [],\n channelConfig: normalizeChannelConfigResult(record),\n };\n}\n\nclass ExtensionChannelClient implements ExtensionChannelAuthClient, ExtensionChannelOutbound {\n constructor(\n private readonly params: {\n extensionId: string;\n channelId: string;\n request: ExtensionRequestSender;\n },\n ) {}\n\n readonly login: ExtensionChannelAuthClient[\"login\"] = async ({ accountId, baseUrl, verbose }) =>\n normalizeAuthLoginResult(await this.params.request({\n extensionId: this.params.extensionId,\n kind: \"channel.auth.login\",\n payload: {\n channelId: this.params.channelId,\n accountId,\n baseUrl,\n verbose,\n },\n }));\n\n readonly start: ExtensionChannelAuthClient[\"start\"] = async (params) =>\n await this.params.request<ExtensionChannelAuthStartResult>({\n extensionId: this.params.extensionId,\n kind: \"channel.auth.start\",\n payload: {\n channelId: this.params.channelId,\n accountId: params.accountId,\n baseUrl: params.baseUrl,\n domain: (params as { domain?: string | null }).domain,\n },\n });\n\n readonly connect: ExtensionChannelAuthClient[\"connect\"] = async (params) =>\n normalizeAuthPollResult(await this.params.request<ExtensionChannelAuthConnectResult>({\n extensionId: this.params.extensionId,\n kind: \"channel.auth.connect\",\n payload: {\n channelId: this.params.channelId,\n accountId: params.accountId,\n domain: params.domain,\n fields: params.fields,\n },\n })) as ExtensionChannelAuthConnectResult;\n\n readonly poll: ExtensionChannelAuthClient[\"poll\"] = async ({ sessionId }) =>\n normalizeAuthPollResult(await this.params.request({\n extensionId: this.params.extensionId,\n kind: \"channel.auth.poll\",\n payload: {\n channelId: this.params.channelId,\n sessionId,\n },\n }));\n\n readonly sendText: ExtensionChannelOutbound[\"sendText\"] = async ({ to, text, accountId, replyTo, media, metadata }) =>\n await this.params.request({\n extensionId: this.params.extensionId,\n kind: \"channel.outbound.sendText\",\n payload: {\n channelId: this.params.channelId,\n to,\n text,\n accountId,\n replyTo,\n media,\n metadata,\n },\n });\n}\n\nexport class ExtensionRuntimeService {\n readonly token = randomUUID();\n private readonly lifecycle = new ExtensionLifecycleService();\n private readonly pendingRequests = new Map<string, PendingExtensionRequest>();\n private manifests: ExtensionManifest[] = [];\n\n constructor(private readonly options: ExtensionRuntimeServiceOptions) {}\n\n readonly registerIngressHandlers = (): void => {\n this.options.ingress.addHandler(\n ingressKeys.extension.channelConfigGet,\n this.handleChannelConfigGet,\n );\n this.options.ingress.addHandler(\n ingressKeys.extension.channelMessageSubmit,\n this.handleChannelMessageSubmit,\n );\n this.options.ingress.addHandler(\n ingressKeys.extension.channelCommandList,\n this.handleChannelCommandList,\n );\n this.options.ingress.addHandler(\n ingressKeys.extension.channelCommandExecute,\n this.handleChannelCommandExecute,\n );\n this.options.ingress.addHandler(\n ingressKeys.extension.response,\n this.handleExtensionResponse,\n );\n };\n\n readonly loadChannelContributions = async (params: {\n config: Config;\n workspace: string;\n }): Promise<ExtensionRuntimeContributions> => {\n this.manifests = await this.discoverManifests(params);\n return this.toContributions(this.manifests);\n };\n\n readonly start = async (params: { endpoint: string | null }): Promise<void> => {\n const endpoint = params.endpoint?.trim();\n if (!endpoint) {\n return;\n }\n const manifests = this.manifests.length > 0\n ? this.manifests\n : await this.discoverManifests({\n config: this.options.getConfig(),\n workspace: this.options.getWorkspace(),\n });\n const running = this.lifecycle.startAll(manifests, {\n endpoint,\n token: this.token,\n });\n if (running.length > 0) {\n console.log(`✓ Extensions started: ${running.map((entry) => entry.manifest.id).join(\", \")}`);\n }\n };\n\n readonly stop = async (): Promise<void> => {\n await this.lifecycle.stopAll();\n for (const [requestId, request] of this.pendingRequests) {\n clearTimeout(request.timeout);\n request.reject(new Error(`Extension request cancelled: ${requestId}`));\n }\n this.pendingRequests.clear();\n };\n\n private readonly discoverManifests = async (params: {\n config: Config;\n workspace: string;\n }): Promise<ExtensionManifest[]> => {\n const discovery = new ExtensionManifestDiscoveryService();\n return await discovery.discover(resolveExtensionManifestRoots(params));\n };\n\n private readonly toContributions = (manifests: ExtensionManifest[]): ExtensionRuntimeContributions => {\n const channelBindings: ExtensionChannelBinding[] = [];\n const uiMetadata: ExtensionUiMetadata[] = [];\n for (const manifest of manifests) {\n for (const channel of manifest.contributes?.channels ?? []) {\n const channelId = readString(channel.id);\n if (!channelId) {\n continue;\n }\n const configUiHints = this.readConfigUiHints(channel.configUiHints);\n channelBindings.push({\n extensionId: manifest.id,\n channelId,\n channel: {\n id: channelId,\n meta: {\n label: channel.name ?? channelId,\n selectionLabel: channel.name ?? channelId,\n ...(channel.description ? { blurb: channel.description } : {}),\n ...(channel.meta ?? {}),\n },\n ...(channel.configSchema ? {\n configSchema: {\n schema: channel.configSchema,\n ...(configUiHints ? { uiHints: configUiHints } : {}),\n },\n } : {}),\n ...(channel.auth ? { auth: this.createChannelAuth(manifest.id, channelId) } : {}),\n outbound: this.createChannelOutbound(manifest.id, channelId),\n },\n });\n uiMetadata.push({\n id: manifest.id,\n configSchema: channel.configSchema,\n ...(configUiHints ? { configUiHints } : {}),\n });\n }\n }\n return { channelBindings, uiMetadata };\n };\n\n private readonly handleChannelConfigGet = (\n envelope: IngressEnvelope<ExtensionChannelConfigGetIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n const payload = readRecord(envelope.payload);\n const channelId = readRequiredString(payload.channelId, \"channelId\");\n return {\n config: (this.options.getConfig().channels as Record<string, unknown>)[channelId] ?? {},\n };\n };\n\n private readonly handleChannelMessageSubmit = async (\n envelope: IngressEnvelope<ExtensionChannelMessageSubmitIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n await this.options.messageBus.publishInbound(toInboundMessage(envelope.payload));\n return { accepted: true };\n };\n\n private readonly handleChannelCommandList = (\n _envelope: IngressEnvelope<ExtensionChannelCommandListIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n const registry = new CommandRegistry(this.options.getConfig(), this.options.sessionManager);\n return {\n commands: registry.listSlashCommands(),\n };\n };\n\n private readonly handleChannelCommandExecute = async (\n envelope: IngressEnvelope<ExtensionChannelCommandExecuteIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n const payload = readRecord(envelope.payload);\n const channel = readRequiredString(payload.channelId, \"channelId\");\n const chatId = readRequiredString(payload.conversationId, \"conversationId\");\n const senderId = readRequiredString(payload.senderId, \"senderId\");\n const metadata = readRecord(payload.metadata);\n const config = this.options.getConfig();\n const registry = new CommandRegistry(config, this.options.sessionManager);\n const route = new AgentRouteResolver(config).resolveInbound({\n message: {\n channel,\n chatId,\n senderId,\n content: readString(payload.rawText) ?? readString(payload.commandName) ?? \"\",\n timestamp: new Date(),\n attachments: [],\n metadata,\n },\n forcedAgentId: readString(metadata.target_agent_id),\n sessionKeyOverride: readString(metadata.session_key_override),\n });\n const rawText = readString(payload.rawText);\n if (rawText) {\n const result = await registry.executeText(rawText, {\n channel,\n chatId,\n senderId,\n sessionKey: route.sessionKey,\n });\n return result ?? {\n content: \"\",\n ephemeral: true,\n };\n }\n return await registry.execute(\n readRequiredString(payload.commandName, \"commandName\"),\n readRecord(payload.args),\n {\n channel,\n chatId,\n senderId,\n sessionKey: route.sessionKey,\n },\n );\n };\n\n private readonly handleExtensionResponse = (\n envelope: IngressEnvelope<ExtensionResponseIngressPayload>,\n context: IngressContext,\n ) => {\n this.assertAuthorized(context);\n const payload = readRecord(envelope.payload);\n const requestId = readRequiredString(payload.requestId, \"requestId\");\n const pending = this.pendingRequests.get(requestId);\n if (!pending) {\n return { accepted: false };\n }\n this.pendingRequests.delete(requestId);\n clearTimeout(pending.timeout);\n if (payload.ok === false) {\n const error = readRecord(payload.error);\n const message = readString(error.message) ?? \"Extension request failed\";\n pending.reject(new Error(message));\n return { accepted: true };\n }\n pending.resolve(payload.data);\n return { accepted: true };\n };\n\n private readonly readConfigUiHints = (\n value: unknown,\n ): ExtensionUiMetadata[\"configUiHints\"] | undefined => {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as ExtensionUiMetadata[\"configUiHints\"]\n : undefined;\n };\n\n private readonly createChannelAuth = (\n extensionId: string,\n channelId: string,\n ): ExtensionChannelAuthClient =>\n new ExtensionChannelClient({\n extensionId,\n channelId,\n request: this.requestExtension,\n });\n\n private readonly createChannelOutbound = (\n extensionId: string,\n channelId: string,\n ): ExtensionChannelOutbound =>\n new ExtensionChannelClient({\n extensionId,\n channelId,\n request: this.requestExtension,\n });\n\n private readonly requestExtension = async <T>(params: {\n extensionId: string;\n kind: ExtensionChannelRequestKind;\n payload: Record<string, unknown>;\n }): Promise<T> => {\n const requestId = randomUUID();\n const result = new Promise<T>((resolvePromise, rejectPromise) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n rejectPromise(new Error(`Extension request timed out: ${params.kind}`));\n }, EXTENSION_REQUEST_TIMEOUT_MS);\n this.pendingRequests.set(requestId, {\n resolve: (value) => resolvePromise(value as T),\n reject: rejectPromise,\n timeout,\n });\n });\n this.options.eventBus.emitEnvelope({\n type: EXTENSION_REQUEST_EVENT_TYPE,\n payload: {\n requestId,\n extensionId: params.extensionId,\n kind: params.kind,\n payload: params.payload,\n },\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n });\n return await result;\n };\n\n private readonly assertAuthorized = (context: IngressContext): void => {\n if (context.token !== this.token) {\n throw new Error(\"Unauthorized ingress token\");\n }\n };\n}\n","import {\n getWorkspacePath,\n mergeExtensionConfigView,\n toExtensionConfigView,\n type Config,\n type ExtensionChannelBinding,\n type ExtensionDiagnostic,\n type ExtensionRegistry,\n type ExtensionUiMetadata,\n type MessageBus,\n type SessionManager,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { ExtensionRuntimeService } from \"@kernel/services/extension-runtime.service.js\";\nimport type { EventBus, Ingress } from \"@nextclaw/shared\";\n\ntype ExtensionSnapshot = {\n extensionRegistry: ExtensionRegistry;\n channelBindings: ExtensionChannelBinding[];\n uiMetadata: ExtensionUiMetadata[];\n};\n\nexport type ExtensionLoadProgress = {\n extensionId: string;\n loadedExtensionCount: number;\n totalExtensionCount: number;\n};\n\nexport type ExtensionLoadResult = {\n diagnostics: ExtensionDiagnostic[];\n totalExtensionCount: number;\n loadedExtensionCount: number;\n shouldRestartChannels: boolean;\n};\n\ntype ExtensionManagerOptions = {\n configManager: Pick<ConfigManager, \"loadConfig\">;\n eventBus: Pick<EventBus, \"emitEnvelope\">;\n ingress: Pick<Ingress, \"addHandler\">;\n messageBus: Pick<MessageBus, \"publishInbound\">;\n sessionManager: SessionManager;\n};\n\ntype ExtensionLoadParams = {\n config?: Config;\n changedPaths?: readonly string[];\n onLoadStart?: (params: { totalExtensionCount: number }) => void;\n onExtensionProcessed?: (params: ExtensionLoadProgress) => void;\n};\n\nfunction createEmptyExtensionRegistry(): ExtensionRegistry {\n return {\n tools: [],\n channels: [],\n diagnostics: [],\n };\n}\n\nfunction buildSortedBindingSignatures(bindings: readonly ExtensionChannelBinding[]): `${string}:${string}`[] {\n return bindings.map((binding) => `${binding.extensionId}:${binding.channelId}` as const).sort();\n}\n\nfunction buildSortedExtensionChannelIds(channels: readonly ExtensionRegistry[\"channels\"][number][]): string[] {\n return channels\n .map((registration) => registration.channel.id)\n .filter((id): id is string => typeof id === \"string\" && id.trim().length > 0)\n .sort();\n}\n\nfunction areSortedStringListsEqual(left: readonly string[], right: readonly string[]): boolean {\n return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction readConfigPathSegment(path: string, prefix: string): string | null {\n if (!path.startsWith(prefix)) {\n return null;\n }\n const [segment] = path.slice(prefix.length).split(\".\");\n return segment?.trim() ? segment.trim() : null;\n}\n\nfunction buildSnapshot(params: {\n channelBindings: ExtensionChannelBinding[];\n uiMetadata: ExtensionUiMetadata[];\n}): ExtensionSnapshot {\n return {\n extensionRegistry: {\n ...createEmptyExtensionRegistry(),\n channels: params.channelBindings.map((binding) => ({\n extensionId: binding.extensionId,\n channel: binding.channel,\n source: \"extension-manifest\",\n })),\n },\n channelBindings: params.channelBindings,\n uiMetadata: params.uiMetadata,\n };\n}\n\nfunction shouldRestartChannelsForExtensionReload(params: {\n changedPaths: readonly string[];\n currentSnapshot: ExtensionSnapshot;\n nextSnapshot: ExtensionSnapshot;\n}): boolean {\n const { changedPaths, currentSnapshot, nextSnapshot } = params;\n const currentBindingSignatures = buildSortedBindingSignatures(currentSnapshot.channelBindings);\n const nextBindingSignatures = buildSortedBindingSignatures(nextSnapshot.channelBindings);\n if (!areSortedStringListsEqual(currentBindingSignatures, nextBindingSignatures)) {\n return true;\n }\n\n const currentExtensionChannelIds = buildSortedExtensionChannelIds(currentSnapshot.extensionRegistry.channels);\n const nextExtensionChannelIds = buildSortedExtensionChannelIds(nextSnapshot.extensionRegistry.channels);\n if (!areSortedStringListsEqual(currentExtensionChannelIds, nextExtensionChannelIds)) {\n return true;\n }\n\n const channelIds = new Set<string>();\n for (const binding of [...currentSnapshot.channelBindings, ...nextSnapshot.channelBindings]) {\n channelIds.add(binding.channelId);\n }\n\n for (const path of changedPaths) {\n const channelId = readConfigPathSegment(path, \"channels.\");\n if (channelId && channelIds.has(channelId)) {\n return true;\n }\n if (path.startsWith(\"extensions.\")) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction countExtensionIds(bindings: readonly ExtensionChannelBinding[], metadata: readonly ExtensionUiMetadata[]): number {\n return new Set([\n ...bindings.map((binding) => binding.extensionId),\n ...metadata.map((item) => item.id),\n ]).size;\n}\n\nexport class ExtensionManager {\n private snapshot: ExtensionSnapshot = buildSnapshot({\n channelBindings: [],\n uiMetadata: [],\n });\n private readonly runtime: ExtensionRuntimeService;\n\n constructor(private readonly options: ExtensionManagerOptions) {\n this.runtime = new ExtensionRuntimeService({\n eventBus: options.eventBus,\n getConfig: options.configManager.loadConfig,\n getWorkspace: this.getWorkspace,\n ingress: options.ingress,\n messageBus: options.messageBus,\n sessionManager: options.sessionManager,\n });\n }\n\n load = async (params: ExtensionLoadParams = {}): Promise<ExtensionLoadResult> => {\n const { changedPaths = [], onLoadStart, onExtensionProcessed } = params;\n const config = params.config ?? this.options.configManager.loadConfig();\n const workspace = getWorkspacePath(config.agents.defaults.workspace);\n const contributions = await this.runtime.loadChannelContributions({\n config,\n workspace,\n });\n const totalExtensionCount = countExtensionIds(contributions.channelBindings, contributions.uiMetadata);\n onLoadStart?.({ totalExtensionCount });\n for (const [index, binding] of contributions.channelBindings.entries()) {\n onExtensionProcessed?.({\n extensionId: binding.extensionId,\n loadedExtensionCount: index + 1,\n totalExtensionCount,\n });\n }\n const currentSnapshot = this.snapshot;\n const nextSnapshot = buildSnapshot(contributions);\n this.snapshot = nextSnapshot;\n return {\n diagnostics: [],\n totalExtensionCount,\n loadedExtensionCount: totalExtensionCount,\n shouldRestartChannels: shouldRestartChannelsForExtensionReload({\n changedPaths,\n currentSnapshot,\n nextSnapshot,\n }),\n };\n };\n\n reloadForConfigChange = async (params: ExtensionLoadParams & {\n changedPaths: readonly string[];\n }): Promise<ExtensionLoadResult> => await this.load(params);\n\n registerIngressHandlers = (): void => {\n this.runtime.registerIngressHandlers();\n };\n\n start = async (params: { endpoint: string | null }): Promise<void> => {\n await this.runtime.start(params);\n };\n\n stop = async (): Promise<void> => {\n await this.runtime.stop();\n };\n\n getExtensionRegistry = (): ExtensionRegistry => this.snapshot.extensionRegistry;\n\n getChannelBindings = (): ExtensionChannelBinding[] => this.snapshot.channelBindings;\n\n getUiMetadata = (): ExtensionUiMetadata[] => this.snapshot.uiMetadata;\n\n toConfigView = (config: Config): Config =>\n toExtensionConfigView(config) as Config;\n\n mergeConfigView = (current: Config, nextConfigView: Record<string, unknown>): Config =>\n mergeExtensionConfigView(current, nextConfigView);\n\n private readonly getWorkspace = (): string =>\n getWorkspacePath(this.options.configManager.loadConfig().agents.defaults.workspace);\n}\n","const IMAGE_OMITTED_TEXT = \"[Image omitted: the selected model is not configured for vision input.]\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isImageContentPart(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n const type = value.type;\n return type === \"image_url\" || type === \"input_image\";\n}\n\nfunction normalizeContentWithoutVision(content: unknown): unknown {\n if (!Array.isArray(content)) {\n return content;\n }\n\n let sawImage = false;\n const parts = content.map((part) => {\n if (!isImageContentPart(part)) {\n return part;\n }\n sawImage = true;\n return { type: \"text\", text: IMAGE_OMITTED_TEXT };\n });\n\n if (!sawImage) {\n return content;\n }\n\n const textParts = parts\n .filter((part): part is { type: \"text\"; text: string } => (\n isRecord(part) && part.type === \"text\" && typeof part.text === \"string\"\n ))\n .map((part) => part.text.trim())\n .filter(Boolean);\n if (textParts.length === parts.length) {\n return textParts.join(\"\\n\\n\");\n }\n return parts;\n}\n\nexport function normalizeModelMessagesForVisionSupport(params: {\n messages: Array<Record<string, unknown>>;\n supportsVision: boolean;\n}): Array<Record<string, unknown>> {\n if (params.supportsVision) {\n return params.messages;\n }\n return params.messages.map((message) => {\n if (!Object.prototype.hasOwnProperty.call(message, \"content\")) {\n return message;\n }\n const content = normalizeContentWithoutVision(message.content);\n return content === message.content ? message : { ...message, content };\n });\n}\n","import {\n LLMProvider,\n LiteLLMProvider,\n ProviderRegistry,\n modelSupportsVision,\n type Config,\n type LLMResponse,\n type LLMStreamEvent,\n type ProviderConfig,\n type ThinkingLevel,\n} from \"@nextclaw/core\";\nimport { BUILTIN_PROVIDER_PLUGINS } from \"@nextclaw/runtime\";\nimport { normalizeModelMessagesForVisionSupport } from \"@kernel/utils/model-message-vision.utils.js\";\n\ntype ProviderChatParams = {\n messages: Array<Record<string, unknown>>;\n tools?: Array<Record<string, unknown>>;\n model?: string | null;\n maxTokens?: number;\n thinkingLevel?: ThinkingLevel | null;\n signal?: AbortSignal;\n};\n\nexport type LlmProviderRuntime = {\n get: (model?: string | null) => LLMProvider;\n chat: (params: ProviderChatParams) => Promise<LLMResponse>;\n chatStream: (params: ProviderChatParams) => AsyncGenerator<LLMStreamEvent>;\n};\n\ntype ProviderRoute = {\n model: string;\n providerName: string | null;\n provider: ProviderConfig | null;\n apiBase: string | null;\n};\n\ntype ProviderConnectionTestInput = {\n providerName: string | null;\n apiKey?: string | null;\n apiBase?: string | null;\n defaultModel: string;\n extraHeaders?: Record<string, string> | null;\n wireApi?: \"auto\" | \"chat\" | \"responses\" | null;\n messages: Array<Record<string, unknown>>;\n maxTokens?: number;\n signal?: AbortSignal;\n};\n\nconst normalizedModel = (value: string | null | undefined): string | null => {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n};\n\nconst headersFingerprint = (headers: Record<string, string> | null | undefined): string => {\n if (!headers) {\n return \"\";\n }\n const sortedEntries = Object.entries(headers).sort(([left], [right]) => left.localeCompare(right));\n return JSON.stringify(sortedEntries);\n};\n\nclass MissingKernelProvider extends LLMProvider {\n constructor(private defaultModel: string) {\n super(null, null);\n }\n\n setDefaultModel = (model: string): void => {\n this.defaultModel = model;\n };\n\n getDefaultModel = (): string => {\n return this.defaultModel;\n };\n\n readonly chat = async (_params: ProviderChatParams): Promise<never> => {\n throw new Error(\"No API key configured yet. Configure provider credentials in UI and retry.\");\n };\n}\n\nexport class LlmProviderManager {\n private readonly providerRegistry: ProviderRegistry;\n private readonly providerPool = new Map<string, LLMProvider>();\n private readonly missingProvider = new MissingKernelProvider(\"gpt-4o\");\n private config: Config | null = null;\n\n constructor() {\n this.providerRegistry = new ProviderRegistry(BUILTIN_PROVIDER_PLUGINS);\n }\n\n load = (config: Config): void => {\n this.config = config;\n this.providerPool.clear();\n this.missingProvider.setDefaultModel(config.agents.defaults.model);\n };\n\n get = (model?: string | null): LLMProvider => {\n const route = this.resolveRoute(model);\n if (!route) {\n return this.missingProvider;\n }\n return this.getOrCreateProvider(route);\n };\n\n readonly chat = async (params: ProviderChatParams): Promise<LLMResponse> => {\n const route = this.resolveRoute(params.model ?? null);\n const provider = route ? this.getOrCreateProvider(route) : this.missingProvider;\n return provider.chat({\n ...params,\n messages: this.prepareMessagesForProvider(route, params.messages),\n });\n };\n\n readonly chatStream = async function* (\n this: LlmProviderManager,\n params: ProviderChatParams\n ): AsyncGenerator<LLMStreamEvent> {\n const route = this.resolveRoute(params.model ?? null);\n const provider = route ? this.getOrCreateProvider(route) : this.missingProvider;\n for await (const event of provider.chatStream({\n ...params,\n messages: this.prepareMessagesForProvider(route, params.messages),\n })) {\n yield event;\n }\n };\n\n readonly testConnection = async (input: ProviderConnectionTestInput): Promise<void> => {\n const provider = this.createProvider({\n providerName: input.providerName,\n provider: {\n enabled: true,\n displayName: \"\",\n apiKey: input.apiKey ?? \"\",\n apiBase: input.apiBase ?? null,\n extraHeaders: input.extraHeaders ?? null,\n wireApi: input.wireApi ?? \"auto\",\n models: [],\n modelConfig: {},\n },\n apiBase: input.apiBase ?? null,\n model: input.defaultModel,\n });\n await provider.chat({\n messages: input.messages,\n model: input.defaultModel,\n maxTokens: input.maxTokens,\n signal: input.signal,\n });\n };\n\n private resolveRoute = (model?: string | null): ProviderRoute | null => {\n if (!this.config) {\n return null;\n }\n\n const effectiveModel = normalizedModel(model) ?? this.config.agents.defaults.model;\n const { provider, name } = this.resolveProvider(effectiveModel);\n const providerSpec = name ? this.providerRegistry.findProviderByName(name) : undefined;\n return {\n model: effectiveModel,\n providerName: name,\n provider,\n apiBase: provider?.apiBase ?? providerSpec?.defaultApiBase ?? null,\n };\n };\n\n private resolveProvider = (model: string): {\n provider: ProviderConfig | null;\n name: string | null;\n } => {\n const providers = this.config?.providers as Record<string, ProviderConfig> | undefined;\n if (!providers) {\n return { provider: null, name: null };\n }\n\n const specs = this.providerRegistry.listProviderSpecs();\n const modelLower = model.toLowerCase();\n const modelPrefix = modelLower.includes(\"/\")\n ? modelLower.slice(0, modelLower.indexOf(\"/\"))\n : \"\";\n\n if (modelPrefix) {\n const prefixed = this.matchPrefixedProvider(providers, modelPrefix);\n if (prefixed) {\n return prefixed;\n }\n }\n\n const keywordMatches = specs\n .map((spec) => ({ name: spec.name, provider: providers[spec.name], spec }))\n .filter((entry) => entry.provider?.enabled !== false && Boolean(entry.provider?.apiKey))\n .filter((entry) => entry.spec.keywords.some((keyword) => modelLower.includes(keyword)));\n if (keywordMatches.length === 1) {\n const match = keywordMatches[0];\n return { provider: match.provider ?? null, name: match.name };\n }\n if (keywordMatches.length > 1) {\n return { provider: null, name: null };\n }\n\n const builtinNames = new Set(specs.map((spec) => spec.name));\n const enabledProviders = Object.entries(providers)\n .filter(([, provider]) => provider.enabled !== false && Boolean(provider.apiKey));\n const enabledBuiltin = enabledProviders.filter(([name]) => builtinNames.has(name));\n if (enabledBuiltin.length === 1) {\n const [name, provider] = enabledBuiltin[0];\n return { provider, name };\n }\n const enabledCustom = enabledProviders.filter(([name]) => !builtinNames.has(name));\n if (enabledCustom.length === 1) {\n const [name, provider] = enabledCustom[0];\n return { provider, name };\n }\n return { provider: null, name: null };\n };\n\n private matchPrefixedProvider = (\n providers: Record<string, ProviderConfig>,\n modelPrefix: string\n ): { provider: ProviderConfig | null; name: string | null } | null => {\n for (const spec of this.providerRegistry.listProviderSpecs()) {\n const provider = providers[spec.name];\n const aliases = [spec.name, spec.modelPrefix ?? \"\"]\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean);\n if (provider && aliases.includes(modelPrefix)) {\n return provider.enabled !== false\n ? { provider, name: spec.name }\n : { provider: null, name: null };\n }\n }\n const customProvider = Object.entries(providers)\n .find(([name]) => name.toLowerCase() === modelPrefix);\n if (!customProvider) {\n return null;\n }\n const [name, provider] = customProvider;\n return provider.enabled !== false ? { provider, name } : { provider: null, name: null };\n };\n\n private getOrCreateProvider = (route: ProviderRoute): LLMProvider => {\n if (!route.provider?.apiKey && !route.model.startsWith(\"bedrock/\")) {\n return this.missingProvider;\n }\n\n const cacheKey = this.buildCacheKey(route);\n const cached = this.providerPool.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const created = this.createProvider(route);\n this.providerPool.set(cacheKey, created);\n return created;\n };\n\n private createProvider = (route: ProviderRoute): LLMProvider => {\n return new LiteLLMProvider({\n apiKey: route.provider?.apiKey ?? null,\n apiBase: route.apiBase,\n defaultModel: route.model,\n extraHeaders: route.provider?.extraHeaders ?? null,\n providerName: route.providerName,\n providerRegistry: this.providerRegistry,\n wireApi: route.provider?.wireApi ?? null,\n });\n };\n\n private prepareMessagesForProvider = (\n route: ProviderRoute | null,\n messages: Array<Record<string, unknown>>,\n ): Array<Record<string, unknown>> => {\n return normalizeModelMessagesForVisionSupport({\n messages,\n supportsVision: modelSupportsVision({\n model: route?.model,\n providerName: route?.providerName,\n modelConfig: route?.provider?.modelConfig,\n }),\n });\n };\n\n private buildCacheKey = (route: ProviderRoute): string => {\n const routeProvider = route.provider;\n return [\n route.providerName ?? \"\",\n routeProvider?.apiKey ?? \"\",\n route.apiBase ?? \"\",\n routeProvider?.wireApi ?? \"\",\n headersFingerprint(routeProvider?.extraHeaders ?? null),\n ].join(\"||\");\n };\n}\n","import type { Config } from \"@nextclaw/core\";\nimport { McpRegistryService, McpServerLifecycleManager } from \"@nextclaw/mcp\";\nimport { McpNcpToolRegistryAdapter } from \"@nextclaw/ncp-mcp\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class McpManager {\n private currentMcpConfig: Config;\n private readonly mcpLifecycleManager: McpServerLifecycleManager;\n private readonly mcpRegistryService: McpRegistryService;\n private readonly toolRegistryAdapter: McpNcpToolRegistryAdapter;\n private warmupPromise: Promise<void> | null = null;\n\n constructor(getConfig: () => Config) {\n this.currentMcpConfig = getConfig();\n this.mcpLifecycleManager = new McpServerLifecycleManager({\n getConfig: () => this.currentMcpConfig,\n });\n this.mcpRegistryService = new McpRegistryService({\n getConfig: () => this.currentMcpConfig,\n lifecycleManager: this.mcpLifecycleManager,\n });\n this.toolRegistryAdapter = new McpNcpToolRegistryAdapter(this.mcpRegistryService);\n }\n\n listToolsForRun = (params: { agentId: string }): ReadonlyArray<NcpTool> =>\n this.toolRegistryAdapter.listToolsForRun(params);\n\n start = (): void => {\n this.warmupPromise ??= this.prewarmEnabledServersSafely();\n };\n\n applyConfig = async (config: Config): Promise<void> => {\n const previousConfig = this.currentMcpConfig;\n this.currentMcpConfig = config;\n const reconcileResult = await this.mcpRegistryService.reconcileConfig({\n prevConfig: previousConfig,\n nextConfig: config,\n });\n\n for (const warmResult of reconcileResult.warmed) {\n if (!warmResult.ok) {\n console.warn(`[mcp] Failed to warm ${warmResult.name}: ${warmResult.error}`);\n }\n }\n };\n\n dispose = async (): Promise<void> => {\n await this.warmupPromise?.catch(() => undefined);\n await this.mcpRegistryService.close();\n };\n\n private prewarmEnabledServersSafely = async (): Promise<void> => {\n const results = await this.mcpRegistryService.prewarmEnabledServers();\n for (const result of results) {\n if (!result.ok) {\n console.warn(`[mcp] Failed to warm ${result.name}: ${result.error}`);\n }\n }\n };\n}\n","import {\n type AgentSessionEventRecord,\n type AgentSessionRecord,\n DefaultNcpAgentConversationStateManager,\n} from \"@nextclaw/ncp-toolkit\";\nimport {\n type NcpEndpointEvent,\n NcpEventType,\n type NcpMessage,\n type NcpSessionSummary,\n} from \"@nextclaw/ncp\";\n\nexport const NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION = 1;\nexport const NCP_AGENT_SESSION_JOURNAL_INDEX_FILE = \".ncp-agent-session-index.json\";\n\nconst AUTO_SESSION_LABEL_MAX_LENGTH = 64;\n\nexport type NcpAgentSessionJournalMetadataEntry = {\n _type: \"metadata\";\n version: typeof NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION;\n created_at: string;\n agent_id?: string;\n metadata: Record<string, unknown>;\n};\n\nexport const NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE = \"session.snapshot.message\";\nexport const NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE = \"session.request.accepted\";\nexport const NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE = \"session.request.completed\";\nexport const NCP_SESSION_REQUEST_FAILED_EVENT_TYPE = \"session.request.failed\";\n\ntype NcpAgentSessionSnapshotMessageEvent = {\n type: typeof NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE;\n payload: Extract<NcpEndpointEvent, { type: NcpEventType.MessageSent }>[\"payload\"];\n};\n\nexport type NcpSessionRequestJournalEventType =\n | typeof NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE\n | typeof NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE\n | typeof NCP_SESSION_REQUEST_FAILED_EVENT_TYPE;\n\nexport type NcpSessionRequestJournalEvent = {\n type: NcpSessionRequestJournalEventType;\n payload: {\n sessionId: string;\n request: unknown;\n };\n};\n\nexport type NcpAgentSessionJournalReplayEvent =\n | NcpEndpointEvent\n | NcpAgentSessionSnapshotMessageEvent\n | NcpSessionRequestJournalEvent;\n\ntype NcpAgentSessionReplayableEvent = NcpEndpointEvent | NcpAgentSessionSnapshotMessageEvent;\n\nexport type NcpAgentSessionJournalEventEntry = {\n _type: \"event\";\n version: typeof NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION;\n seq: number;\n timestamp: string;\n event: NcpAgentSessionJournalReplayEvent;\n};\n\nexport type NcpAgentSessionJournalIndex = {\n version: typeof NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION;\n records: NcpSessionSummary[];\n};\n\nexport type LoadedNcpAgentJournalSession = {\n record: AgentSessionRecord;\n nextSeq: number;\n};\n\nexport function normalizeNcpSessionId(sessionId: string): string {\n return sessionId.trim();\n}\n\nexport function safeNcpSessionFilename(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n}\n\nexport function normalizeNcpAgentId(agentId: string | undefined): string | undefined {\n return agentId?.trim().toLowerCase() || undefined;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function toIsoString(value: unknown, fallback: string): string {\n const parsed = typeof value === \"string\" ? Date.parse(value) : NaN;\n return Number.isFinite(parsed) ? new Date(parsed).toISOString() : fallback;\n}\n\nexport function createNcpAgentSessionSummary(record: AgentSessionRecord): NcpSessionSummary {\n const metadata = structuredClone(record.metadata ?? {});\n const label = readOptionalText(metadata.label) ?? resolveAutoSessionLabel(record.messages);\n if (label) {\n metadata.label = label;\n }\n const lastMessageAt = readMessageTimestamp(record.messages.at(-1));\n return {\n sessionId: record.sessionId,\n ...(normalizeNcpAgentId(record.agentId) ? { agentId: normalizeNcpAgentId(record.agentId) } : {}),\n messageCount: record.messages.length,\n ...(record.createdAt ? { createdAt: record.createdAt } : {}),\n updatedAt: record.updatedAt,\n ...(lastMessageAt ? { lastMessageAt } : {}),\n status: \"idle\",\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n };\n}\n\nexport function createNcpAgentSessionJournalMetadataEntry(\n record: AgentSessionEventRecord,\n): NcpAgentSessionJournalMetadataEntry {\n return {\n _type: \"metadata\",\n version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n created_at: record.createdAt ?? record.updatedAt,\n ...(normalizeNcpAgentId(record.agentId) ? { agent_id: normalizeNcpAgentId(record.agentId) } : {}),\n metadata: structuredClone(record.metadata ?? {}),\n };\n}\n\nexport function upsertNcpAgentSessionSummaryEvent(params: {\n current: NcpSessionSummary | undefined;\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n updatedAt: string;\n}): NcpSessionSummary {\n const { current, event, sessionId, updatedAt } = params;\n const eventMessage = readMessageFromSummaryEvent(event);\n const messageCount = current\n ? current.messageCount + (eventMessage ? 1 : 0)\n : eventMessage\n ? 1\n : 0;\n const lastMessageAt = readMessageTimestamp(eventMessage) ?? current?.lastMessageAt;\n return {\n sessionId,\n ...(normalizeNcpAgentId(current?.agentId) ? { agentId: normalizeNcpAgentId(current?.agentId) } : {}),\n messageCount,\n createdAt: current?.createdAt ?? updatedAt,\n updatedAt,\n ...(lastMessageAt ? { lastMessageAt } : {}),\n status: \"idle\",\n };\n}\n\nexport async function replayNcpAgentSessionEvents(\n events: readonly NcpAgentSessionJournalReplayEvent[],\n): Promise<NcpMessage[]> {\n const stateManager = new DefaultNcpAgentConversationStateManager();\n for (const event of events) {\n if (isJournalOnlyEvent(event)) {\n continue;\n }\n await stateManager.dispatch(createReplayEvent(event));\n }\n const snapshot = stateManager.getSnapshot();\n return [\n ...snapshot.messages.map((message) => structuredClone(message)),\n ...(snapshot.streamingMessage ? [structuredClone(snapshot.streamingMessage)] : []),\n ];\n}\n\nfunction createReplayEvent(event: NcpAgentSessionReplayableEvent): NcpEndpointEvent {\n const replayEvent = structuredClone(event);\n const replayMessage = readMessageFromSummaryEvent(replayEvent);\n if (\n replayMessage?.role === \"assistant\" &&\n (replayMessage.status === \"pending\" || replayMessage.status === \"streaming\")\n ) {\n replayMessage.status = \"final\";\n }\n if (\n replayEvent.type === NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE ||\n replayEvent.type === NcpEventType.MessageCompleted\n ) {\n return { type: NcpEventType.MessageSent, payload: replayEvent.payload };\n }\n return replayEvent;\n}\n\nfunction isJournalOnlyEvent(event: NcpAgentSessionJournalReplayEvent): event is NcpSessionRequestJournalEvent {\n return (\n event.type === NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE ||\n event.type === NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE ||\n event.type === NCP_SESSION_REQUEST_FAILED_EVENT_TYPE\n );\n}\n\nexport function readNcpSessionSummaryActivityAt(summary: NcpSessionSummary): string {\n return summary.lastMessageAt ?? summary.createdAt ?? summary.updatedAt;\n}\n\nfunction readMessageTimestamp(message: NcpMessage | undefined): string | undefined {\n return toIsoString(message?.timestamp, \"\") || undefined;\n}\n\nfunction truncateLabel(value: string): string {\n const chars = Array.from(value);\n return chars.length <= AUTO_SESSION_LABEL_MAX_LENGTH\n ? value\n : `${chars.slice(0, AUTO_SESSION_LABEL_MAX_LENGTH).join(\"\")}...`;\n}\n\nfunction readOptionalText(value: unknown): string | null {\n const trimmed = typeof value === \"string\" ? value.trim() : \"\";\n return trimmed || null;\n}\n\nfunction resolveAutoSessionLabel(messages: readonly NcpMessage[]): string | null {\n for (const message of messages) {\n if (message.role !== \"user\") {\n continue;\n }\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"rich-text\") {\n const text = readOptionalText(part.text);\n if (text) {\n return truncateLabel(text);\n }\n }\n }\n }\n return null;\n}\n\nfunction readMessageFromSummaryEvent(event: NcpAgentSessionJournalReplayEvent): NcpMessage | undefined {\n switch (event.type) {\n case NcpEventType.MessageSent:\n return event.payload.message;\n case NcpEventType.MessageCompleted:\n return event.payload.message;\n case NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE:\n return event.payload.message;\n default:\n return undefined;\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport type {\n CreatedSession,\n CreateSessionInput,\n SessionSearchManager,\n} from \"@nextclaw/core\";\nimport { BUILTIN_MAIN_AGENT_ID } from \"@nextclaw/core\";\nimport type {\n ListMessagesOptions,\n ListSessionsOptions,\n NcpMessage,\n NcpSessionApi,\n NcpSessionPatch,\n NcpSessionSummary,\n} from \"@nextclaw/ncp\";\nimport { NcpEventType } from \"@nextclaw/ncp\";\nimport type { AgentSessionRecord } from \"@nextclaw/ncp-toolkit\";\nimport { ContextWindowPreviewManager } from \"@kernel/features/context-compaction/index.js\";\nimport type { NcpAgentSessionJournalStore } from \"@kernel/stores/ncp-agent-session-journal.store.js\";\nimport {\n createNcpAgentSessionSummary,\n type NcpAgentSessionJournalReplayEvent,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\nimport { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\n\ntype CreateNcpSessionInput = CreateSessionInput & {\n sessionId?: string;\n};\n\nconst DEFAULT_SESSION_TYPE = \"native\";\nconst DEFAULT_LIFECYCLE = \"persistent\";\nconst SESSION_METADATA_LABEL_KEY = \"label\";\nconst CHILD_SESSION_PARENT_METADATA_KEY = \"parent_session_id\";\nconst CHILD_SESSION_REQUEST_METADATA_KEY = \"spawned_by_request_id\";\nconst CHILD_SESSION_LIFECYCLE_METADATA_KEY = \"session_lifecycle\";\n\nexport type NcpSessionManagerOptions = {\n configManager: ConfigManager;\n eventBus: EventBus;\n journalStore: NcpAgentSessionJournalStore;\n sessionSearch: SessionSearchManager;\n};\n\nfunction normalizeSessionId(sessionId: string): string {\n return sessionId.trim();\n}\n\nfunction applyLimit<T>(items: T[], limit?: number): T[] {\n if (!Number.isFinite(limit) || typeof limit !== \"number\" || limit <= 0) {\n return items;\n }\n return items.slice(0, Math.trunc(limit));\n}\n\nfunction readOptionalString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction summarizeTask(task: string): string {\n const normalized = task.trim().replace(/\\s+/g, \" \");\n if (!normalized) {\n return \"Session\";\n }\n return normalized.length <= 72 ? normalized : `${normalized.slice(0, 69)}...`;\n}\n\nfunction buildSessionId(): string {\n return `ncp-${Date.now().toString(36)}-${randomUUID().replace(/-/g, \"\").slice(0, 8)}`;\n}\n\nfunction cloneInheritedMetadata(sourceMetadata: Record<string, unknown>): Record<string, unknown> {\n const nextMetadata: Record<string, unknown> = {};\n const inheritedKeys = [\n \"runtime\",\n \"session_type\",\n \"preferred_model\",\n \"preferred_thinking\",\n \"project_root\",\n \"requested_skill_refs\",\n \"codex_runtime_backend\",\n \"reasoningNormalizationMode\",\n \"reasoning_normalization_mode\",\n ];\n for (const key of inheritedKeys) {\n if (Object.prototype.hasOwnProperty.call(sourceMetadata, key)) {\n nextMetadata[key] = structuredClone(sourceMetadata[key]);\n }\n }\n return nextMetadata;\n}\n\nfunction mergeMetadataOverrides(\n metadata: Record<string, unknown>,\n overrides?: Record<string, unknown>,\n): Record<string, unknown> {\n return overrides && Object.keys(overrides).length > 0\n ? { ...metadata, ...structuredClone(overrides) }\n : metadata;\n}\n\nfunction resolveSessionType(params: {\n runtime?: string;\n sessionType?: string;\n metadata: Record<string, unknown>;\n}): string {\n const { metadata, runtime, sessionType } = params;\n return (\n readOptionalString(runtime) ??\n readOptionalString(metadata.runtime) ??\n readOptionalString(sessionType) ??\n readOptionalString(metadata.session_type) ??\n DEFAULT_SESSION_TYPE\n );\n}\n\nfunction applySessionOverrides(params: {\n lifecycle: string;\n metadata: Record<string, unknown>;\n model?: string;\n parentSessionId?: string;\n projectRoot?: string | null;\n requestId?: string;\n sessionType: string;\n thinkingLevel?: string;\n title?: string;\n}): void {\n const {\n lifecycle,\n metadata,\n model,\n parentSessionId,\n projectRoot,\n requestId,\n sessionType,\n thinkingLevel,\n title,\n } = params;\n metadata.session_type = sessionType;\n metadata.runtime = sessionType;\n metadata[SESSION_METADATA_LABEL_KEY] = title;\n metadata[CHILD_SESSION_LIFECYCLE_METADATA_KEY] = lifecycle;\n if (parentSessionId) {\n metadata[CHILD_SESSION_PARENT_METADATA_KEY] = parentSessionId;\n }\n if (requestId) {\n metadata[CHILD_SESSION_REQUEST_METADATA_KEY] = requestId;\n }\n if (readOptionalString(model)) {\n metadata.model = model?.trim();\n metadata.preferred_model = model?.trim();\n }\n if (readOptionalString(thinkingLevel)) {\n metadata.thinking = thinkingLevel?.trim();\n metadata.preferred_thinking = thinkingLevel?.trim();\n }\n if (readOptionalString(projectRoot)) {\n metadata.project_root = projectRoot?.trim();\n }\n}\n\nfunction isSessionSummaryRefreshEvent(event: NcpAgentSessionJournalReplayEvent): boolean {\n switch (event.type) {\n case NcpEventType.MessageSent:\n case NcpEventType.MessageCompleted:\n case NcpEventType.MessageAbort:\n case NcpEventType.RunFinished:\n case NcpEventType.RunError:\n return true;\n default:\n return false;\n }\n}\n\nexport class NcpSessionManager implements NcpSessionApi {\n private readonly contextWindowPreview: ContextWindowPreviewManager;\n private readonly runningSessionIds = new Set<string>();\n private readonly unsubscribeSessionRunStatus: () => void;\n\n constructor(private readonly options: NcpSessionManagerOptions) {\n this.contextWindowPreview = new ContextWindowPreviewManager({\n configManager: options.configManager,\n });\n this.unsubscribeSessionRunStatus = options.eventBus.on(\n eventKeys.sessionRunStatus,\n this.handleSessionRunStatus,\n );\n }\n\n dispose = (): void => {\n this.unsubscribeSessionRunStatus();\n this.runningSessionIds.clear();\n };\n\n createSession = async (params: CreateNcpSessionInput): Promise<CreatedSession> => {\n const {\n agentId: requestedAgentId,\n metadataOverrides,\n model,\n parentSessionId: rawParentSessionId,\n projectRoot,\n requestId: rawRequestId,\n runtime,\n sessionId: requestedSessionId,\n sessionType: requestedSessionType,\n sourceSessionId,\n sourceSessionMetadata,\n task,\n thinkingLevel,\n title: requestedTitle,\n } = params;\n const sourceRecord = sourceSessionId\n ? await this.getSessionRecord(sourceSessionId)\n : null;\n const metadata = cloneInheritedMetadata(sourceSessionMetadata);\n const title = readOptionalString(requestedTitle) ?? summarizeTask(task);\n const parentSessionId = readOptionalString(rawParentSessionId);\n const requestId = readOptionalString(rawRequestId);\n const sessionType = resolveSessionType({\n runtime,\n sessionType: requestedSessionType,\n metadata,\n });\n applySessionOverrides({\n lifecycle: DEFAULT_LIFECYCLE,\n metadata,\n model,\n parentSessionId: parentSessionId ?? undefined,\n projectRoot,\n requestId: requestId ?? undefined,\n sessionType,\n thinkingLevel,\n title,\n });\n const now = new Date().toISOString();\n const nextMetadata = mergeMetadataOverrides(metadata, metadataOverrides);\n const agentId =\n readOptionalString(requestedAgentId) ??\n readOptionalString(sourceRecord?.agentId) ??\n BUILTIN_MAIN_AGENT_ID;\n const sessionId = readOptionalString(requestedSessionId) ?? buildSessionId();\n const record: AgentSessionRecord = {\n sessionId,\n ...(agentId ? { agentId } : {}),\n messages: [],\n createdAt: now,\n updatedAt: now,\n metadata: nextMetadata,\n };\n await this.options.journalStore.importSessionSnapshot(record);\n await this.publishSessionChange(sessionId);\n return {\n sessionId,\n agentId,\n sessionType,\n runtimeFamily: sessionType === DEFAULT_SESSION_TYPE ? \"native\" : \"external\",\n ...(parentSessionId ? { parentSessionId } : {}),\n ...(requestId ? { spawnedByRequestId: requestId } : {}),\n lifecycle: DEFAULT_LIFECYCLE,\n title,\n metadata: nextMetadata,\n createdAt: now,\n updatedAt: now,\n };\n };\n\n appendSessionEvent = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n }): Promise<void> => {\n const { event } = params;\n const sessionId = normalizeSessionId(params.sessionId);\n if (!sessionId) {\n return;\n }\n await this.options.journalStore.appendSessionEvent({\n event,\n sessionId,\n });\n if (isSessionSummaryRefreshEvent(event)) {\n await this.publishSessionChange(sessionId);\n }\n };\n\n setSessionMetadata = async (\n sessionId: string,\n metadata: Record<string, unknown>,\n ): Promise<boolean> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return false;\n }\n const updated = await this.options.journalStore.setSessionMetadata({\n sessionId: normalizedSessionId,\n metadata: structuredClone(metadata),\n });\n if (!updated) {\n return false;\n }\n this.publishSessionMetadataChanged(normalizedSessionId, metadata, \"set\");\n await this.publishSessionChange(normalizedSessionId);\n return true;\n };\n\n updateSessionMetadata = async (\n sessionId: string,\n metadata: Record<string, unknown>,\n ): Promise<boolean> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return false;\n }\n const updated = await this.options.journalStore.updateSessionMetadata({\n sessionId: normalizedSessionId,\n metadata: structuredClone(metadata),\n });\n if (!updated) {\n return false;\n }\n this.publishSessionMetadataChanged(normalizedSessionId, metadata, \"update\");\n await this.publishSessionChange(normalizedSessionId);\n return true;\n };\n\n updateSession = async (\n sessionId: string,\n patch: NcpSessionPatch,\n ): Promise<NcpSessionSummary | null> => {\n if (!Object.prototype.hasOwnProperty.call(patch, \"metadata\")) {\n return await this.getSession(sessionId);\n }\n const updated = patch.metadata === null\n ? await this.setSessionMetadata(sessionId, {})\n : await this.updateSessionMetadata(sessionId, patch.metadata ?? {});\n return updated ? await this.getSession(sessionId) : null;\n };\n\n deleteSession = async (sessionId: string): Promise<void> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return;\n }\n await this.options.journalStore.deleteSession(normalizedSessionId);\n await this.publishSessionChange(normalizedSessionId);\n };\n\n getSessionRecord = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return null;\n }\n return await this.options.journalStore.getSession(normalizedSessionId);\n };\n\n listSessions = async (options?: ListSessionsOptions): Promise<NcpSessionSummary[]> => {\n const summaries = await this.options.journalStore.listSessionSummaries();\n return applyLimit(summaries, options?.limit).map(this.withLiveSessionStatus);\n };\n\n listSessionMessages = async (\n sessionId: string,\n options?: ListMessagesOptions,\n ): Promise<NcpMessage[]> => {\n const normalizedSessionId = normalizeSessionId(sessionId);\n if (!normalizedSessionId) {\n return [];\n }\n const messages = await this.options.journalStore.listSessionMessages(normalizedSessionId);\n return applyLimit(messages, options?.limit);\n };\n\n getSession = async (sessionId: string): Promise<NcpSessionSummary | null> => {\n const record = await this.getSessionRecord(sessionId);\n return record ? this.withLiveSessionStatus(this.createSummaryFromRecord(record, true)) : null;\n };\n\n getContextWindow = async (\n sessionId: string,\n liveRecord?: AgentSessionRecord | null,\n ): Promise<Record<string, unknown> | null> => {\n const summary = liveRecord\n ? this.withLiveSessionStatus(this.createSummaryFromRecord(liveRecord, true))\n : await this.getSession(sessionId);\n return summary?.contextWindow ?? null;\n };\n\n publishSessionChange = async (sessionKey: string): Promise<void> => {\n const normalizedSessionKey = normalizeSessionId(sessionKey);\n if (!normalizedSessionKey) {\n return;\n }\n this.options.eventBus.emit(eventKeys.sessionUpdated, { sessionKey: normalizedSessionKey }, {\n emittedAt: new Date().toISOString(),\n source: \"ncp-session\",\n });\n await this.options.sessionSearch.handleSessionUpdated(normalizedSessionKey);\n const summary = await this.getSession(normalizedSessionKey);\n if (summary) {\n this.options.eventBus.emit(eventKeys.sessionSummaryUpsert, { summary });\n return;\n }\n this.options.eventBus.emit(eventKeys.sessionSummaryDelete, {\n sessionKey: normalizedSessionKey,\n });\n };\n\n private createSummaryFromRecord = (\n record: AgentSessionRecord,\n includeContextWindow = false,\n ): NcpSessionSummary => {\n const summary = createNcpAgentSessionSummary(record);\n const contextWindow = includeContextWindow\n ? this.contextWindowPreview.preview({\n requestMetadata: record.metadata ?? {},\n sessionId: record.sessionId,\n sessionMessages: record.messages,\n storedAgentId: record.agentId,\n storedMetadata: record.metadata ?? {},\n })\n : undefined;\n return contextWindow ? { ...summary, contextWindow } : summary;\n };\n\n private withLiveSessionStatus = (summary: NcpSessionSummary): NcpSessionSummary =>\n this.runningSessionIds.has(summary.sessionId)\n ? { ...summary, status: \"running\" }\n : summary;\n\n private handleSessionRunStatus = (payload: {\n sessionKey: string;\n status: \"running\" | \"idle\";\n }): void => {\n const sessionId = normalizeSessionId(payload.sessionKey);\n if (!sessionId) {\n return;\n }\n if (payload.status === \"running\") this.runningSessionIds.add(sessionId);\n else this.runningSessionIds.delete(sessionId);\n };\n\n private publishSessionMetadataChanged = (\n sessionKey: string,\n metadata: Record<string, unknown>,\n mode: \"set\" | \"update\",\n ): void => {\n this.options.eventBus.emit(\n eventKeys.sessionMetadataChanged,\n { sessionKey, mode, metadata: structuredClone(metadata) },\n { emittedAt: new Date().toISOString(), source: \"ncp-session\" },\n );\n };\n}\n","import { parse as parseYaml } from \"yaml\";\n\nexport type LocalizedTextMap = Record<string, string>;\n\nexport type SkillFrontmatter = {\n name?: string;\n summary?: string;\n summaryI18n?: LocalizedTextMap;\n description?: string;\n descriptionI18n?: LocalizedTextMap;\n author?: string;\n tags?: string[];\n};\n\nexport function parseSkillFrontmatter(raw: string): SkillFrontmatter {\n const frontmatter = parseFrontmatterBlock(raw);\n if (!frontmatter) {\n return {};\n }\n\n const parsed = parseYamlFrontmatter(frontmatter);\n const summaryI18n = readLocalizedTextMap(parsed, \"summaryi18n\", \"summary_i18n\");\n const descriptionI18n = readLocalizedTextMap(parsed, \"descriptioni18n\", \"description_i18n\");\n\n return {\n name: readString(parsed, \"name\"),\n summary: readString(parsed, \"summary\"),\n summaryI18n: mergeLocalizedTextMap(summaryI18n, { zh: readString(parsed, \"summaryzh\", \"summary_zh\") }),\n description: readString(parsed, \"description\"),\n descriptionI18n: mergeLocalizedTextMap(descriptionI18n, {\n zh: readString(parsed, \"descriptionzh\", \"description_zh\"),\n }),\n author: readString(parsed, \"author\"),\n tags: readTags(parsed),\n };\n}\n\nexport function stripSkillFrontmatter(raw: string): string {\n const normalized = raw.replace(/\\r\\n/g, \"\\n\");\n const match = normalized.match(/^---\\n[\\s\\S]*?\\n---\\n?/);\n return match ? normalized.slice(match[0].length).trim() : normalized.trim();\n}\n\nexport function buildLocalizedTextMap(\n englishText: string,\n ...maps: Array<LocalizedTextMap | Partial<LocalizedTextMap> | undefined>\n): LocalizedTextMap {\n return {\n ...(mergeLocalizedTextMap(...maps) ?? {}),\n en: englishText,\n };\n}\n\nfunction parseFrontmatterBlock(raw: string): string | null {\n const match = raw.replace(/\\r\\n/g, \"\\n\").match(/^---\\n([\\s\\S]*?)\\n---/);\n return match?.[1] ?? null;\n}\n\nfunction parseYamlFrontmatter(raw: string): Record<string, unknown> {\n try {\n const parsed = parseYaml(raw);\n return isRecord(parsed) ? parsed : {};\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Invalid SKILL.md frontmatter: ${message}`);\n }\n}\n\nfunction readString(record: Record<string, unknown>, ...names: string[]): string | undefined {\n const value = readValue(record, names);\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readLocalizedTextMap(record: Record<string, unknown>, ...names: string[]): LocalizedTextMap | undefined {\n const value = readValue(record, names);\n if (!isRecord(value)) {\n return undefined;\n }\n\n const localized = Object.fromEntries(\n Object.entries(value)\n .filter((entry): entry is [string, string] => typeof entry[1] === \"string\" && entry[1].trim().length > 0)\n .map(([locale, text]) => [normalizeLocaleTag(locale), text.trim()]),\n );\n return Object.keys(localized).length > 0 ? localized : undefined;\n}\n\nfunction readTags(record: Record<string, unknown>): string[] | undefined {\n const value = readValue(record, [\"tags\"]);\n const tags = Array.isArray(value) ? value : typeof value === \"string\" ? value.split(\",\") : [];\n const normalized = tags\n .filter((entry): entry is string => typeof entry === \"string\")\n .map((entry) => entry.trim())\n .filter(Boolean);\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction mergeLocalizedTextMap(\n ...maps: Array<LocalizedTextMap | Partial<LocalizedTextMap> | undefined>\n): LocalizedTextMap | undefined {\n const localized = Object.fromEntries(\n maps.flatMap((map) =>\n Object.entries(map ?? {})\n .filter((entry): entry is [string, string] => typeof entry[1] === \"string\" && entry[1].trim().length > 0)\n .map(([locale, text]) => [normalizeLocaleTag(locale), text.trim()]),\n ),\n );\n return Object.keys(localized).length > 0 ? localized : undefined;\n}\n\nfunction readValue(record: Record<string, unknown>, names: string[]): unknown {\n const normalizedNames = names.map(normalizeFrontmatterKey);\n const matchingKey = Object.keys(record).find((candidate) =>\n normalizedNames.includes(normalizeFrontmatterKey(candidate)),\n );\n return matchingKey ? record[matchingKey] : undefined;\n}\n\nfunction normalizeFrontmatterKey(raw: string): string {\n return raw.replace(/[-_]/g, \"\").toLowerCase();\n}\n\nfunction normalizeLocaleTag(raw: string): string {\n return raw.trim().toLowerCase();\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, relative, resolve } from \"node:path\";\nimport {\n SkillsLoader,\n type SkillInfo as CoreSkillInfo,\n} from \"@nextclaw/core\";\nimport {\n parseSkillFrontmatter,\n stripSkillFrontmatter,\n type LocalizedTextMap,\n} from \"@kernel/utils/skill-frontmatter.utils.js\";\n\nexport type { SkillInfo, SkillScope } from \"@nextclaw/core\";\n\ntype WorkspaceParams = { workspace: string };\ntype InstalledSkillScopeFilter = CoreSkillInfo[\"scope\"] | \"all\";\n\nexport type InstalledSkillSummary = {\n ref: string;\n name: string;\n path: string;\n relativePath: string | null;\n scope: CoreSkillInfo[\"scope\"];\n source: CoreSkillInfo[\"source\"];\n summary: string | null;\n summaryI18n: LocalizedTextMap | null;\n description: string | null;\n descriptionI18n: LocalizedTextMap | null;\n author: string | null;\n tags: string[];\n always: boolean;\n};\n\nexport type InstalledSkillDetail = InstalledSkillSummary & {\n metadata: Record<string, string> | null;\n raw: string;\n bodyRaw: string;\n};\n\nexport type InstalledSkillsList = {\n workspace: string;\n total: number;\n skills: InstalledSkillSummary[];\n};\n\nexport class SkillManager {\n private readonly loader: SkillsLoader;\n private readonly workspace: string;\n\n constructor(params: WorkspaceParams) {\n this.workspace = resolve(params.workspace);\n this.loader = new SkillsLoader(this.workspace);\n }\n\n listSkills = (params: { filterUnavailable?: boolean } = {}): CoreSkillInfo[] => {\n return this.loader.listSkills(params.filterUnavailable);\n };\n\n getSkillInfo = (selector: string): CoreSkillInfo | null => {\n return this.loader.getSkillInfo(selector);\n };\n\n getSkillMetadata = (selector: string | CoreSkillInfo): Record<string, string> | null => {\n return this.loader.getSkillMetadata(selector);\n };\n\n loadSkillContent = (selector: string): string | null => {\n return this.loader.loadSkill(selector);\n };\n\n listInstalledSkills = (params: {\n query?: string;\n scope?: string;\n } = {}): InstalledSkillsList => {\n const scope = this.normalizeInstalledScope(params.scope);\n const normalizedQuery = this.normalizeOptionalString(params.query)?.toLowerCase() ?? null;\n\n const skills = this\n .listSkills({ filterUnavailable: false })\n .map((skill) => this.buildInstalledSkillSummary(skill))\n .filter((skill) => scope === \"all\" || skill.scope === scope)\n .filter((skill) => this.matchesInstalledSkillQuery(skill, normalizedQuery));\n\n return {\n workspace: this.workspace,\n total: skills.length,\n skills,\n };\n };\n\n getInstalledSkillDetail = (selector: string): InstalledSkillDetail | null => {\n const skill = this.getSkillInfo(selector);\n if (!skill) {\n return null;\n }\n\n const summary = this.buildInstalledSkillSummary(skill);\n const raw = readFileSync(skill.path, \"utf8\");\n return {\n ...summary,\n metadata: this.getSkillMetadata(skill),\n raw,\n bodyRaw: stripSkillFrontmatter(raw),\n };\n };\n\n findBuiltinSkill = (name: string): CoreSkillInfo | null => {\n return this\n .listSkills({ filterUnavailable: false })\n .find((skill) => skill.name === name && skill.source === \"builtin\") ?? null;\n };\n\n resolveBuiltinSkillDir = (name: string): string | null => {\n const skill = this.findBuiltinSkill(name);\n return skill ? dirname(skill.path) : null;\n };\n\n private buildInstalledSkillSummary = (skill: CoreSkillInfo): InstalledSkillSummary => {\n const raw = readFileSync(skill.path, \"utf8\");\n const metadata = this.getSkillMetadata(skill);\n const frontmatter = parseSkillFrontmatter(raw);\n\n return {\n ref: skill.ref,\n name: skill.name,\n path: skill.path,\n relativePath: this.buildRelativePath(skill.path),\n scope: skill.scope,\n source: skill.source,\n summary: frontmatter.summary ?? null,\n summaryI18n: frontmatter.summaryI18n ?? null,\n description: frontmatter.description ?? metadata?.description ?? null,\n descriptionI18n: frontmatter.descriptionI18n ?? null,\n author: frontmatter.author ?? null,\n tags: frontmatter.tags ?? [],\n always: this.readAlwaysFlag(metadata),\n };\n };\n\n private matchesInstalledSkillQuery = (\n skill: InstalledSkillSummary,\n query: string | null,\n ): boolean => {\n if (!query) {\n return true;\n }\n\n const haystacks = [\n skill.ref,\n skill.name,\n skill.path,\n skill.relativePath ?? \"\",\n skill.scope,\n skill.source,\n skill.summary ?? \"\",\n skill.description ?? \"\",\n skill.author ?? \"\",\n ...skill.tags,\n ...Object.values(skill.summaryI18n ?? {}),\n ...Object.values(skill.descriptionI18n ?? {}),\n ];\n\n return haystacks.some((value) => value.toLowerCase().includes(query));\n };\n\n private readAlwaysFlag = (metadata: Record<string, string> | null): boolean => {\n if (metadata?.always === \"true\") {\n return true;\n }\n\n const raw = metadata?.metadata;\n if (!raw) {\n return false;\n }\n\n try {\n const parsed = JSON.parse(raw) as {\n nextclaw?: {\n always?: unknown;\n };\n };\n return parsed.nextclaw?.always === true;\n } catch {\n return false;\n }\n };\n\n private buildRelativePath = (absolutePath: string): string | null => {\n const relativePath = relative(this.workspace, absolutePath).replace(/\\\\/g, \"/\");\n return relativePath.startsWith(\"..\") ? null : relativePath;\n };\n\n private normalizeInstalledScope = (value: string | undefined): InstalledSkillScopeFilter => {\n const normalized = this.normalizeOptionalString(value);\n if (!normalized || normalized === \"all\") {\n return \"all\";\n }\n if (normalized === \"builtin\" || normalized === \"project\" || normalized === \"workspace\") {\n return normalized;\n }\n throw new Error(`Invalid skill scope: ${value}. Expected all, builtin, project, or workspace.`);\n };\n\n private normalizeOptionalString = (value: string | undefined): string | null => {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n };\n}\n","import { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport type { UpdateToolCallResult } from \"@kernel/managers/tool.manager.js\";\nimport {\n NcpEventType,\n type NcpAgentRuntime,\n type NcpEndpointEvent,\n} from \"@nextclaw/ncp\";\nimport {\n DefaultNcpAgentConversationStateManager,\n} from \"@nextclaw/ncp-toolkit\";\nimport {\n buildSessionRecord,\n disposeRuntime,\n type LiveSession,\n type LiveSessionExecution,\n type PublishSessionEventOptions,\n readAgentId,\n readString,\n} from \"@kernel/utils/session-run.utils.js\";\nimport type { AgentRuntimeManager } from \"@kernel/managers/agent-runtime.manager.js\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\n\ntype Cleanup = () => Promise<void> | void;\nconst RUNTIME_METADATA_KEYS = [\"runtime\", \"session_type\", \"runtime_type\"] as const;\n\nfunction isDurableSessionEvent(event: NcpEndpointEvent): boolean {\n return event.type !== NcpEventType.ContextWindowUpdated;\n}\n\nfunction pickRuntimeMetadataPatch(\n current: Record<string, unknown>,\n next: Record<string, unknown>,\n): Record<string, unknown> {\n const patch: Record<string, unknown> = {};\n for (const key of RUNTIME_METADATA_KEYS) {\n const value = next[key];\n if (!Object.is(current[key], value)) {\n patch[key] = structuredClone(value);\n }\n }\n return patch;\n}\n\nexport class SessionRunManager {\n private readonly agentRuntimeManager: AgentRuntimeManager;\n private readonly ncpSessionManager: NcpSessionManager;\n private readonly eventBus: EventBus;\n private readonly liveSessions = new Map<string, LiveSession>();\n private readonly cleanups: Cleanup[] = [];\n private disposed = false;\n\n constructor(options: {\n agentRuntimeManager: AgentRuntimeManager;\n eventBus: EventBus;\n ncpSessionManager: NcpSessionManager;\n }) {\n const {\n agentRuntimeManager,\n eventBus,\n ncpSessionManager,\n } = options;\n this.agentRuntimeManager = agentRuntimeManager;\n this.ncpSessionManager = ncpSessionManager;\n this.eventBus = eventBus;\n }\n\n dispose = async (): Promise<void> => {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n while (this.cleanups.length > 0) {\n await this.cleanups.pop()?.();\n }\n };\n\n isRunning = (sessionId: string): boolean => Boolean(this.liveSessions.get(sessionId)?.activeExecution);\n\n getOrCreateLiveSession = async (\n sessionId: string,\n initialMetadata: Record<string, unknown> = {},\n ): Promise<LiveSession> => this.ensureLiveSession(sessionId, initialMetadata);\n\n getActiveSessionRun = (sessionId: string): LiveSessionExecution | null =>\n this.liveSessions.get(sessionId)?.activeExecution ?? null;\n\n getLiveSessionRecord = (sessionId: string) => {\n const session = this.liveSessions.get(sessionId.trim());\n return session ? buildSessionRecord(session, new Date().toISOString()) : null;\n };\n\n setActiveSessionRun = (\n sessionId: string,\n activeRun: LiveSessionExecution,\n ): void => {\n const session = this.requireLiveSession(sessionId);\n const current = session.activeExecution;\n if (current && current !== activeRun && !current.closed) {\n throw new Error(`Session ${session.sessionId} already has an active execution.`);\n }\n session.activeExecution = activeRun;\n if (current !== activeRun) {\n this.publishSessionRunStatus({ sessionKey: session.sessionId, status: \"running\" });\n }\n };\n\n deleteActiveSessionRun = (\n sessionId: string,\n runId: string,\n ): void => {\n const session = this.requireLiveSession(sessionId);\n const current = session.activeExecution;\n if (!current || current.runId !== runId) {\n return;\n }\n current.closed = true;\n session.activeExecution = null;\n this.publishSessionRunStatus({ sessionKey: session.sessionId, status: \"idle\" });\n };\n\n updateToolCallResult: UpdateToolCallResult = async ({\n result,\n sessionId,\n toolCallId,\n }): Promise<void> => {\n this.assertNotDisposed();\n const normalizedSessionId = sessionId.trim();\n const normalizedToolCallId = toolCallId.trim();\n if (!normalizedSessionId || !normalizedToolCallId) {\n return;\n }\n const session = await this.ensureLiveSession(normalizedSessionId);\n await this.publishSessionEvent(session, {\n type: NcpEventType.MessageToolCallResult,\n payload: {\n sessionId: normalizedSessionId,\n toolCallId: normalizedToolCallId,\n content: result,\n },\n });\n };\n\n updateSessionMetadata = async (\n sessionId: string,\n metadata: Record<string, unknown>,\n ): Promise<boolean> => {\n this.assertNotDisposed();\n const normalizedSessionId = sessionId.trim();\n if (!normalizedSessionId) return false;\n const liveSession = this.liveSessions.has(normalizedSessionId);\n const storedSession = liveSession ? null : await this.ncpSessionManager.getSessionRecord(normalizedSessionId);\n if (!liveSession && !storedSession) return false;\n return await this.ncpSessionManager.updateSessionMetadata(normalizedSessionId, metadata);\n };\n\n appendSessionEvent = async (\n sessionId: string,\n event: NcpEndpointEvent,\n options: PublishSessionEventOptions = {},\n ): Promise<void> => {\n await this.publishSessionEvent(this.requireLiveSession(sessionId), event, options);\n };\n\n private readonly ensureLiveSession = async (\n sessionId: string,\n initialMetadata: Record<string, unknown> = {},\n ): Promise<LiveSession> => {\n const existing = this.liveSessions.get(sessionId);\n if (existing) {\n return existing;\n }\n\n const storedSession = await this.ncpSessionManager.getSessionRecord(sessionId);\n const stateManager = new DefaultNcpAgentConversationStateManager();\n stateManager.hydrate({\n sessionId,\n messages: storedSession?.messages.map((message) => structuredClone(message)) ?? [],\n });\n const metadata = {\n ...(storedSession?.metadata ? structuredClone(storedSession.metadata) : {}),\n ...structuredClone(initialMetadata),\n };\n const runtimeMetadata = this.agentRuntimeManager.resolveSessionMetadata(metadata);\n const runtimeMetadataPatch = pickRuntimeMetadataPatch(metadata, runtimeMetadata);\n if (Object.keys(runtimeMetadataPatch).length > 0) {\n await this.ncpSessionManager.updateSessionMetadata(sessionId, runtimeMetadataPatch);\n }\n const session: LiveSession = {\n sessionId,\n ...(readString(storedSession?.agentId) ?? readAgentId(metadata)\n ? { agentId: readString(storedSession?.agentId) ?? readAgentId(metadata) }\n : {}),\n stateManager,\n runtime: null as unknown as NcpAgentRuntime,\n activeExecution: null,\n };\n session.runtime = this.agentRuntimeManager.createRuntime({\n sessionId,\n ...(session.agentId ? { agentId: session.agentId } : {}),\n stateManager,\n sessionMetadata: runtimeMetadata,\n });\n this.liveSessions.set(sessionId, session);\n this.cleanups.push(async () => {\n session.activeExecution?.controller.abort();\n await disposeRuntime(session.runtime);\n this.liveSessions.delete(sessionId);\n });\n return session;\n };\n\n private readonly requireLiveSession = (sessionId: string): LiveSession => {\n const session = this.liveSessions.get(sessionId);\n if (!session) {\n throw new Error(`Session ${sessionId} is not live.`);\n }\n return session;\n };\n\n private readonly publishSessionEvent = async (\n session: LiveSession,\n event: NcpEndpointEvent,\n options: PublishSessionEventOptions = {},\n ): Promise<void> => {\n if (options.dispatchToStateManager !== false) {\n await session.stateManager.dispatch(event);\n }\n if (options.persistSession !== false) {\n await this.persistLiveSessionEvent(session, event);\n }\n this.eventBus.emit(eventKeys.ncpEvent, event, {\n emittedAt: new Date().toISOString(),\n source: \"session-run\",\n });\n };\n\n private readonly persistLiveSessionEvent = async (session: LiveSession, event: NcpEndpointEvent): Promise<void> => {\n if (!isDurableSessionEvent(event)) {\n return;\n }\n await this.ncpSessionManager.appendSessionEvent({\n sessionId: session.sessionId,\n event,\n });\n };\n\n private readonly assertNotDisposed = (): void => {\n if (this.disposed) {\n throw new Error(\"Session run manager has already been disposed.\");\n }\n };\n\n private publishSessionRunStatus = (payload: { sessionKey: string; status: \"running\" | \"idle\" }): void => {\n this.eventBus.emit(eventKeys.sessionRunStatus, payload, {\n emittedAt: new Date().toISOString(),\n source: \"session-run\",\n });\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AgentSessionEventRecord } from \"@nextclaw/ncp-toolkit\";\nimport {\n createNcpAgentSessionJournalMetadataEntry,\n isRecord,\n normalizeNcpAgentId,\n safeNcpSessionFilename,\n toIsoString,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\n\nexport type NcpAgentSessionActivitySnapshot = {\n metadata: Record<string, unknown>;\n agentId?: string;\n createdAt: string;\n updatedAt: string;\n};\n\nexport class NcpAgentSessionMetadataStore {\n constructor(private readonly journalDir: string) {}\n\n write = async (record: AgentSessionEventRecord): Promise<void> => {\n await mkdir(this.journalDir, { recursive: true });\n const targetPath = this.metadataPath(record.sessionId);\n const tempPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n await writeFile(tempPath, `${JSON.stringify(createNcpAgentSessionJournalMetadataEntry(record))}\\n`, \"utf-8\");\n await rename(tempPath, targetPath);\n } catch (error) {\n await rm(tempPath, { force: true });\n throw error;\n }\n };\n\n read = async (\n sessionId: string,\n activitySnapshot: NcpAgentSessionActivitySnapshot,\n ): Promise<NcpAgentSessionActivitySnapshot> => {\n try {\n const parsed = JSON.parse(await readFile(this.metadataPath(sessionId), \"utf-8\")) as unknown;\n if (!isRecord(parsed) || parsed._type !== \"metadata\" || !isRecord(parsed.metadata)) {\n throw new Error(`invalid ncp agent session metadata sidecar: ${sessionId}`);\n }\n const createdAt = toIsoString(parsed.created_at, activitySnapshot.createdAt);\n const agentId = normalizeNcpAgentId(typeof parsed.agent_id === \"string\" ? parsed.agent_id : undefined);\n return {\n metadata: structuredClone(parsed.metadata),\n ...(agentId ? { agentId } : {}),\n createdAt,\n updatedAt: activitySnapshot.updatedAt,\n };\n } catch (error) {\n const code = error && typeof error === \"object\" && \"code\" in error ? error.code : undefined;\n if (code === \"ENOENT\") {\n return activitySnapshot;\n }\n throw error;\n }\n };\n\n delete = async (sessionId: string): Promise<void> => {\n await rm(this.metadataPath(sessionId), { force: true });\n };\n\n private metadataPath = (sessionId: string): string => {\n return join(this.journalDir, `${safeNcpSessionFilename(sessionId.replace(/:/g, \"_\"))}.metadata.json`);\n };\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { NcpSessionSummary } from \"@nextclaw/ncp\";\nimport {\n createNcpAgentSessionSummary,\n type LoadedNcpAgentJournalSession,\n NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n NCP_AGENT_SESSION_JOURNAL_INDEX_FILE,\n type NcpAgentSessionJournalIndex,\n type NcpAgentSessionJournalReplayEvent,\n readNcpSessionSummaryActivityAt,\n upsertNcpAgentSessionSummaryEvent,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\n\nfunction stripSummaryMetadata(summary: NcpSessionSummary): NcpSessionSummary {\n const { metadata: _metadata, ...nextSummary } = summary;\n void _metadata;\n return nextSummary;\n}\n\nexport class NcpAgentSessionSummaryIndexStore {\n private summaryIndex: Map<string, NcpSessionSummary> | null = null;\n\n constructor(\n private readonly journalDir: string,\n private readonly loadSession: (sessionId: string) => Promise<LoadedNcpAgentJournalSession | null>,\n ) {}\n\n has = async (sessionId: string): Promise<boolean> => (await this.load()).has(sessionId);\n\n list = async (): Promise<NcpSessionSummary[]> => {\n const index = await this.load();\n return [...index.values()]\n .map((summary) => structuredClone(summary))\n .sort((left, right) => readNcpSessionSummaryActivityAt(right).localeCompare(readNcpSessionSummaryActivityAt(left)));\n };\n\n upsert = async (summary: NcpSessionSummary): Promise<void> => {\n const index = await this.load();\n index.set(summary.sessionId, stripSummaryMetadata(structuredClone(summary)));\n await this.persist();\n };\n\n upsertForEvent = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n updatedAt: string;\n }): Promise<void> => {\n const { event, sessionId, updatedAt } = params;\n const index = await this.load();\n const summary = upsertNcpAgentSessionSummaryEvent({\n current: index.get(sessionId),\n sessionId,\n event,\n updatedAt,\n });\n index.set(summary.sessionId, stripSummaryMetadata(summary));\n await this.persist();\n };\n\n remove = async (sessionId: string): Promise<void> => {\n const index = await this.load();\n index.delete(sessionId);\n await this.persist();\n };\n\n private load = async (): Promise<Map<string, NcpSessionSummary>> => {\n if (this.summaryIndex) {\n return this.summaryIndex;\n }\n try {\n const parsed = JSON.parse(await readFile(this.indexPath(), \"utf-8\")) as NcpAgentSessionJournalIndex;\n if (parsed.version === NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION && Array.isArray(parsed.records)) {\n this.summaryIndex = new Map(parsed.records.map((record) => [\n record.sessionId,\n stripSummaryMetadata(structuredClone(record)),\n ]));\n return this.summaryIndex;\n }\n } catch {\n // Rebuild below.\n }\n this.summaryIndex = await this.rebuild();\n await this.persist();\n return this.summaryIndex;\n };\n\n private rebuild = async (): Promise<Map<string, NcpSessionSummary>> => {\n const records = new Map<string, NcpSessionSummary>();\n let entries: string[] = [];\n try {\n entries = await readdir(this.journalDir);\n } catch {\n return records;\n }\n for (const entry of entries) {\n if (!entry.endsWith(\".jsonl\")) {\n continue;\n }\n const sessionId = entry.replace(/\\.jsonl$/, \"\").replace(/_/g, \":\");\n const loaded = await this.loadSession(sessionId);\n if (loaded) {\n records.set(sessionId, stripSummaryMetadata(createNcpAgentSessionSummary(loaded.record)));\n }\n }\n return records;\n };\n\n private persist = async (): Promise<void> => {\n const records = [...(this.summaryIndex?.values() ?? [])]\n .map((summary) => stripSummaryMetadata(structuredClone(summary)))\n .sort((left, right) => readNcpSessionSummaryActivityAt(right).localeCompare(readNcpSessionSummaryActivityAt(left)));\n await mkdir(this.journalDir, { recursive: true });\n await writeFile(\n this.indexPath(),\n `${JSON.stringify({ version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION, records })}\\n`,\n \"utf-8\",\n );\n };\n\n private indexPath = (): string => resolve(this.journalDir, NCP_AGENT_SESSION_JOURNAL_INDEX_FILE);\n}\n","import { appendFile, mkdir, readFile, unlink, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { AgentSessionRecord } from \"@nextclaw/ncp-toolkit\";\nimport type { NcpMessage, NcpSessionSummary } from \"@nextclaw/ncp\";\nimport {\n createNcpAgentSessionSummary,\n isRecord,\n type LoadedNcpAgentJournalSession,\n NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE,\n type NcpAgentSessionJournalEventEntry,\n type NcpAgentSessionJournalReplayEvent,\n normalizeNcpAgentId,\n normalizeNcpSessionId,\n replayNcpAgentSessionEvents,\n safeNcpSessionFilename,\n toIsoString,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\nimport { NcpAgentSessionMetadataStore } from \"./ncp-agent-session-metadata.store.js\";\nimport { NcpAgentSessionSummaryIndexStore } from \"./ncp-agent-session-summary-index.store.js\";\n\ntype ParsedNcpAgentSessionJournal = {\n metadata: Record<string, unknown>;\n agentId?: string;\n createdAt: string;\n updatedAt: string;\n nextSeq: number;\n events: NcpAgentSessionJournalReplayEvent[];\n};\n\nfunction serializeJournalEntry(entry: NcpAgentSessionJournalEventEntry): string {\n const serialized = JSON.stringify(entry);\n if (!serialized) {\n throw new Error(\"ncp agent session journal entry serialization produced empty output\");\n }\n const parsed = JSON.parse(serialized) as unknown;\n if (!isRecord(parsed)) {\n throw new Error(\"ncp agent session journal entry serialization produced a non-object entry\");\n }\n return serialized;\n}\n\nexport class NcpAgentSessionJournalStore {\n private readonly sessions = new Map<string, LoadedNcpAgentJournalSession>();\n private readonly nextSeqBySession = new Map<string, number>();\n private readonly writeChains = new Map<string, Promise<void>>();\n private readonly metadataStore: NcpAgentSessionMetadataStore;\n private readonly summaryIndexStore: NcpAgentSessionSummaryIndexStore;\n\n constructor(private readonly journalDir: string) {\n this.metadataStore = new NcpAgentSessionMetadataStore(journalDir);\n this.summaryIndexStore = new NcpAgentSessionSummaryIndexStore(\n journalDir,\n async (sessionId) => this.loadSession(sessionId),\n );\n }\n\n appendSessionEvent = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n }): Promise<void> => {\n const sessionId = normalizeNcpSessionId(params.sessionId);\n if (!sessionId) {\n return;\n }\n const previous = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.appendSessionEventNow({\n ...params,\n sessionId,\n }));\n this.writeChains.set(sessionId, next.catch(() => undefined));\n await next;\n };\n\n getSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const normalizedSessionId = normalizeNcpSessionId(sessionId);\n if (!normalizedSessionId) {\n return null;\n }\n const cached = this.sessions.get(normalizedSessionId);\n if (cached) {\n return structuredClone(cached.record);\n }\n const loaded = await this.loadSession(normalizedSessionId);\n if (!loaded) {\n return null;\n }\n this.sessions.set(normalizedSessionId, loaded);\n return structuredClone(loaded.record);\n };\n\n listSessionSummaries = async (): Promise<NcpSessionSummary[]> => {\n const summaries = await this.summaryIndexStore.list();\n return await Promise.all(summaries.map(this.withMetadata));\n };\n\n listSessionMessages = async (sessionId: string): Promise<NcpMessage[]> => {\n const session = await this.getSession(sessionId);\n return session ? session.messages.map((message) => structuredClone(message)) : [];\n };\n\n setSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const sessionId = normalizeNcpSessionId(params.sessionId);\n if (!sessionId) {\n return false;\n }\n const previous = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.setSessionMetadataNow({\n ...params,\n sessionId,\n }));\n this.writeChains.set(sessionId, next.then(() => undefined, () => undefined));\n return await next;\n };\n\n updateSessionMetadata = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const sessionId = normalizeNcpSessionId(params.sessionId);\n if (!sessionId) {\n return false;\n }\n const previous = this.writeChains.get(sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.updateSessionMetadataNow({\n ...params,\n sessionId,\n }));\n this.writeChains.set(sessionId, next.then(() => undefined, () => undefined));\n return await next;\n };\n\n private setSessionMetadataNow = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const { metadata, sessionId } = params;\n const loaded = this.sessions.get(sessionId) ?? await this.loadSession(sessionId);\n if (!loaded) {\n return false;\n }\n const nextRecord: AgentSessionRecord = {\n ...loaded.record,\n metadata: structuredClone(metadata),\n };\n await this.metadataStore.write(nextRecord);\n this.sessions.set(sessionId, {\n record: nextRecord,\n nextSeq: loaded.nextSeq,\n });\n this.nextSeqBySession.set(sessionId, loaded.nextSeq);\n await this.summaryIndexStore.upsert(createNcpAgentSessionSummary(nextRecord));\n return true;\n };\n\n private updateSessionMetadataNow = async (params: {\n sessionId: string;\n metadata: Record<string, unknown>;\n }): Promise<boolean> => {\n const loaded = this.sessions.get(params.sessionId) ?? await this.loadSession(params.sessionId);\n if (!loaded) {\n return false;\n }\n return await this.setSessionMetadataNow({\n ...params,\n metadata: {\n ...(loaded.record.metadata ? structuredClone(loaded.record.metadata) : {}),\n ...structuredClone(params.metadata),\n },\n });\n };\n\n importSessionSnapshot = async (record: AgentSessionRecord): Promise<void> => {\n const sessionId = normalizeNcpSessionId(record.sessionId);\n if (!sessionId) {\n return;\n }\n await this.ensureJournalDir();\n const nextRecord = structuredClone({ ...record, sessionId });\n await this.metadataStore.write(nextRecord);\n const entries = nextRecord.messages.map((message, index): NcpAgentSessionJournalEventEntry => ({\n _type: \"event\",\n version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n seq: index + 1,\n timestamp: message.timestamp ?? nextRecord.updatedAt,\n event: {\n type: NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE,\n payload: {\n sessionId,\n message: structuredClone(message),\n },\n },\n }));\n await writeFile(\n this.sessionPath(sessionId),\n entries.length > 0 ? `${entries.map(serializeJournalEntry).join(\"\\n\")}\\n` : \"\",\n \"utf-8\",\n );\n const nextSeq = nextRecord.messages.length + 1;\n this.sessions.set(sessionId, {\n record: nextRecord,\n nextSeq,\n });\n this.nextSeqBySession.set(sessionId, nextSeq);\n await this.summaryIndexStore.upsert(createNcpAgentSessionSummary(nextRecord));\n };\n\n deleteSession = async (sessionId: string): Promise<AgentSessionRecord | null> => {\n const normalizedSessionId = normalizeNcpSessionId(sessionId);\n if (!normalizedSessionId) {\n return null;\n }\n const existing = await this.getSession(normalizedSessionId);\n this.sessions.delete(normalizedSessionId);\n this.nextSeqBySession.delete(normalizedSessionId);\n try {\n await unlink(this.sessionPath(normalizedSessionId));\n } catch {\n // The journal may already be absent when deleting a legacy-only session.\n }\n await this.metadataStore.delete(normalizedSessionId);\n await this.summaryIndexStore.remove(normalizedSessionId);\n return existing;\n };\n\n hasSession = async (sessionId: string): Promise<boolean> => {\n const normalizedSessionId = normalizeNcpSessionId(sessionId);\n if (!normalizedSessionId) {\n return false;\n }\n return this.summaryIndexStore.has(normalizedSessionId);\n };\n\n private appendSessionEventNow = async (params: {\n sessionId: string;\n event: NcpAgentSessionJournalReplayEvent;\n }): Promise<void> => {\n const { event, sessionId } = params;\n const updatedAt = new Date().toISOString();\n await this.ensureJournalDir();\n const existing = this.sessions.get(sessionId)\n ?? (this.nextSeqBySession.has(sessionId) ? null : await this.loadSession(sessionId));\n const nextSeq = this.nextSeqBySession.get(sessionId) ?? existing?.nextSeq ?? 1;\n const path = this.sessionPath(sessionId);\n const entry: NcpAgentSessionJournalEventEntry = {\n _type: \"event\",\n version: NCP_AGENT_SESSION_JOURNAL_ENTRY_VERSION,\n seq: nextSeq,\n timestamp: updatedAt,\n event: structuredClone(event),\n };\n await this.appendJournalEntry(path, entry);\n this.nextSeqBySession.set(sessionId, nextSeq + 1);\n this.sessions.delete(sessionId);\n await this.summaryIndexStore.upsertForEvent({\n sessionId,\n event,\n updatedAt,\n });\n };\n\n private withMetadata = async (summary: NcpSessionSummary): Promise<NcpSessionSummary> => {\n const snapshot = await this.metadataStore.read(summary.sessionId, {\n ...(summary.agentId ? { agentId: summary.agentId } : {}),\n createdAt: summary.createdAt ?? summary.updatedAt,\n updatedAt: summary.updatedAt,\n metadata: {},\n });\n return {\n ...summary,\n ...(!summary.agentId && snapshot.agentId ? { agentId: snapshot.agentId } : {}),\n ...(Object.keys(snapshot.metadata).length > 0 ? { metadata: snapshot.metadata } : {}),\n };\n };\n\n private loadSession = async (sessionId: string): Promise<LoadedNcpAgentJournalSession | null> => {\n let raw: string;\n try {\n raw = await readFile(this.sessionPath(sessionId), \"utf-8\");\n } catch {\n return null;\n }\n\n const parsedJournal = this.parseSessionJournal(raw);\n const sessionMetadata = await this.metadataStore.read(sessionId, parsedJournal);\n const { agentId, createdAt, updatedAt, metadata } = sessionMetadata;\n const { events, nextSeq } = parsedJournal;\n const messages = await replayNcpAgentSessionEvents(events);\n const record: AgentSessionRecord = {\n sessionId,\n ...(agentId ? { agentId } : {}),\n messages,\n createdAt,\n updatedAt,\n metadata,\n };\n this.nextSeqBySession.set(sessionId, nextSeq);\n return {\n record,\n nextSeq,\n };\n };\n\n private parseSessionJournal = (raw: string): ParsedNcpAgentSessionJournal => {\n let metadata: Record<string, unknown> = {};\n let agentId: string | undefined;\n let createdAt = new Date().toISOString();\n let updatedAt = createdAt;\n let nextSeq = 1;\n const events: NcpAgentSessionJournalReplayEvent[] = [];\n for (const [index, line] of raw.split(\"\\n\").entries()) {\n if (!line.trim()) {\n continue;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(line) as unknown;\n } catch (error) {\n console.warn(\n `[ncp-agent-session-journal] skipped corrupted journal line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`\n );\n continue;\n }\n if (!isRecord(parsed)) {\n continue;\n }\n if (parsed._type === \"metadata\") {\n metadata = isRecord(parsed.metadata) ? structuredClone(parsed.metadata) : {};\n agentId = normalizeNcpAgentId(typeof parsed.agent_id === \"string\" ? parsed.agent_id : undefined);\n createdAt = toIsoString(parsed.created_at, createdAt);\n updatedAt = toIsoString(parsed.updated_at, updatedAt);\n continue;\n }\n if (parsed._type === \"event\" && isRecord(parsed.event)) {\n const seq = Number(parsed.seq);\n nextSeq = Math.max(nextSeq, Number.isFinite(seq) ? Math.trunc(seq) + 1 : nextSeq);\n updatedAt = toIsoString(parsed.timestamp, updatedAt);\n const event = structuredClone(parsed.event) as NcpAgentSessionJournalReplayEvent;\n events.push(event);\n }\n }\n return { metadata, ...(agentId ? { agentId } : {}), createdAt, updatedAt, nextSeq, events };\n };\n\n private appendJournalEntry = async (\n path: string,\n entry: NcpAgentSessionJournalEventEntry,\n ): Promise<void> => {\n await appendFile(path, `${serializeJournalEntry(entry)}\\n`, \"utf-8\");\n };\n\n private ensureJournalDir = async (): Promise<void> => {\n await mkdir(this.journalDir, { recursive: true });\n };\n\n private sessionPath = (sessionId: string): string => {\n return join(this.journalDir, `${safeNcpSessionFilename(sessionId.replace(/:/g, \"_\"))}.jsonl`);\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n buildSessionRequestToolResult,\n readOptionalString,\n readParentSessionId,\n summarizeSessionRequestTask,\n createCompletedSessionRequest,\n createFailedSessionRequest,\n createRunningSessionRequest,\n type DispatchRequestParams,\n type RequestSessionParams,\n type SessionRequestDispatcher,\n type SessionRequestPayload,\n type SessionRequestRecord,\n type SessionRequestResultContext,\n type SessionRequestToolResult,\n type SpawnSessionAndRequestParams,\n} from \"@nextclaw/core\";\nimport type { AgentSessionRecord } from \"@nextclaw/ncp-toolkit\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport {\n NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE,\n NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE,\n NCP_SESSION_REQUEST_FAILED_EVENT_TYPE,\n type NcpSessionRequestJournalEvent,\n type NcpSessionRequestJournalEventType,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\n\nexport type SessionRequestManagerOptions = {\n dispatcher: SessionRequestDispatcher;\n ncpSessionManager: NcpSessionManager;\n};\n\nfunction readRecordLabel(record: AgentSessionRecord): string | undefined {\n return readOptionalString(record.metadata?.label) ?? undefined;\n}\n\nexport class SessionRequestManager {\n constructor(private readonly options: SessionRequestManagerOptions) {}\n\n spawnSessionAndRequest = async (\n params: SpawnSessionAndRequestParams,\n ): Promise<SessionRequestToolResult> => {\n const {\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n sourceSessionMetadata,\n metadataOverrides,\n task,\n title,\n model,\n runtime,\n handoffDepth,\n sessionType,\n thinkingLevel,\n projectRoot,\n agentId,\n parentSessionId,\n notify,\n } = params;\n const requestId = randomUUID();\n const createdSession = await this.options.ncpSessionManager.createSession({\n sourceSessionId,\n ...(parentSessionId ? { parentSessionId } : {}),\n task,\n title,\n sourceSessionMetadata,\n ...(metadataOverrides ? { metadataOverrides } : {}),\n agentId,\n model,\n runtime,\n thinkingLevel,\n sessionType,\n projectRoot,\n requestId,\n });\n\n return this.dispatchRequest({\n requestId,\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId: createdSession.sessionId,\n task,\n title: createdSession.title ?? summarizeSessionRequestTask(task),\n handoffDepth: handoffDepth ?? 0,\n notify,\n agentId: createdSession.agentId,\n isChildSession: Boolean(parentSessionId),\n ...(parentSessionId ? { parentSessionId } : {}),\n spawnedByRequestId: requestId,\n });\n };\n\n requestSession = async (\n params: RequestSessionParams,\n ): Promise<SessionRequestToolResult> => {\n const {\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId,\n task,\n title,\n notify,\n handoffDepth,\n } = params;\n const normalizedTargetSessionId = targetSessionId.trim();\n\n if (normalizedTargetSessionId === sourceSessionId.trim()) {\n throw new Error(\"sessions_request cannot target the current session.\");\n }\n const targetSession = await this.options.ncpSessionManager.getSessionRecord(normalizedTargetSessionId);\n if (!targetSession) {\n throw new Error(`Target session not found: ${targetSessionId}`);\n }\n const parentSessionId = readParentSessionId(targetSession.metadata);\n\n return this.dispatchRequest({\n requestId: randomUUID(),\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId: normalizedTargetSessionId,\n task,\n title:\n readOptionalString(title) ??\n readRecordLabel(targetSession) ??\n summarizeSessionRequestTask(task),\n handoffDepth: handoffDepth ?? 0,\n notify,\n agentId: targetSession.agentId,\n isChildSession: Boolean(parentSessionId),\n parentSessionId: parentSessionId ?? undefined,\n spawnedByRequestId: undefined,\n });\n };\n\n private dispatchRequest = async (\n params: DispatchRequestParams,\n ): Promise<SessionRequestToolResult> => {\n const {\n requestId,\n sourceSessionId,\n sourceToolCallId,\n updateToolCallResult,\n targetSessionId,\n task,\n title,\n handoffDepth,\n notify,\n agentId,\n isChildSession,\n parentSessionId,\n spawnedByRequestId,\n } = params;\n const request = createRunningSessionRequest({\n requestId,\n sourceSessionId,\n targetSessionId,\n sourceToolCallId,\n handoffDepth,\n notify,\n title,\n task,\n isChildSession,\n parentSessionId,\n });\n const resultContext: SessionRequestResultContext = {\n task,\n title,\n updateToolCallResult,\n agentId,\n isChildSession,\n parentSessionId,\n spawnedByRequestId,\n };\n const payload = this.toSessionRequestPayload(request, resultContext);\n\n if (notify === \"final_reply\") {\n return await this.runRequest(payload);\n }\n\n void this.runRequestAndUpdateToolCallResult(payload);\n\n return this.buildToolResult({\n ...payload,\n message: `Session request started. You'll receive the final reply when it finishes.`,\n });\n };\n\n private toSessionRequestPayload = (\n request: SessionRequestRecord,\n resultContext: SessionRequestResultContext,\n ): SessionRequestPayload => ({\n request,\n resultContext,\n });\n\n private buildToolResult = (\n payload: SessionRequestPayload & { message?: string },\n ): SessionRequestToolResult => {\n const {\n task,\n title,\n agentId,\n isChildSession,\n parentSessionId,\n spawnedByRequestId,\n } = payload.resultContext;\n return buildSessionRequestToolResult({\n request: payload.request,\n task,\n title,\n isChildSession,\n ...(agentId ? { agentId } : {}),\n ...(parentSessionId ? { parentSessionId } : {}),\n ...(spawnedByRequestId ? { spawnedByRequestId } : {}),\n ...(payload.message ? { message: payload.message } : {}),\n });\n };\n\n private appendRequestEvents = async (\n request: SessionRequestRecord,\n type: NcpSessionRequestJournalEventType,\n ): Promise<void> => {\n await this.appendRequestEvent(request.sourceSessionId, type, request);\n await this.appendRequestEvent(request.targetSessionId, type, request);\n };\n\n private runRequest = async (\n payload: SessionRequestPayload,\n ): Promise<SessionRequestToolResult> => {\n const { request, resultContext } = payload;\n const acceptedWrites: Promise<void>[] = [];\n try {\n const dispatchResult = await this.options.dispatcher.dispatch({\n request,\n task: resultContext.task,\n onAccepted: (messageId) => {\n acceptedWrites.push(this.appendAcceptedRequestEvent(request, messageId));\n },\n });\n await Promise.all(acceptedWrites);\n const completedRequest = createCompletedSessionRequest({\n request,\n finalResponseMessageId: dispatchResult.finalResponseMessageId,\n finalResponseText: dispatchResult.finalResponseText,\n });\n await this.appendRequestEvents(completedRequest, NCP_SESSION_REQUEST_COMPLETED_EVENT_TYPE);\n return this.buildToolResult(this.toSessionRequestPayload(completedRequest, resultContext));\n } catch (error) {\n await Promise.all(acceptedWrites);\n const failedRequest = createFailedSessionRequest({\n request,\n error,\n });\n await this.appendRequestEvents(failedRequest, NCP_SESSION_REQUEST_FAILED_EVENT_TYPE);\n return this.buildToolResult(this.toSessionRequestPayload(failedRequest, resultContext));\n }\n };\n\n private runRequestAndUpdateToolCallResult = async (\n payload: SessionRequestPayload,\n ): Promise<void> => {\n try {\n const result = await this.runRequest(payload);\n await payload.resultContext.updateToolCallResult(result);\n } catch (error) {\n console.error(\n `[session-request] Background request ${payload.request.requestId} crashed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n };\n\n private appendAcceptedRequestEvent = async (\n request: SessionRequestRecord,\n messageId: string,\n ): Promise<void> => {\n const acceptedRequest: SessionRequestRecord = {\n ...request,\n targetMessageId: messageId,\n };\n await this.appendRequestEvent(request.sourceSessionId, NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE, acceptedRequest);\n await this.appendRequestEvent(request.targetSessionId, NCP_SESSION_REQUEST_ACCEPTED_EVENT_TYPE, acceptedRequest);\n };\n\n private appendRequestEvent = async (\n sessionId: string,\n type: NcpSessionRequestJournalEventType,\n request: SessionRequestRecord,\n ): Promise<void> => {\n const event: NcpSessionRequestJournalEvent = {\n type,\n payload: {\n sessionId,\n request: structuredClone(request),\n },\n };\n await this.options.ncpSessionManager.appendSessionEvent({\n sessionId,\n event,\n });\n };\n}\n","import { NcpEventType, type NcpMessage } from \"@nextclaw/ncp\";\nimport {\n eventKeys,\n ingressKeys,\n type AgentRunSessionMessageRequestPayload,\n type EventBus,\n type Ingress,\n type Unsubscribe,\n} from \"@nextclaw/shared\";\nimport type {\n SessionRequestDispatcher,\n SessionRequestRecord,\n} from \"@nextclaw/core\";\n\nexport type AgentRuntimeSessionRequestDispatcherOptions = {\n eventBus: EventBus;\n ingress: Ingress;\n};\n\nfunction extractSessionMessageText(message: NcpMessage): string | undefined {\n const parts = message.parts\n .flatMap((part) => part.type === \"text\" || part.type === \"rich-text\" ? [part.text] : [])\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n return parts.length > 0 ? parts.join(\"\\n\\n\") : undefined;\n}\n\nexport function waitForAgentRuntimeSessionReply(input: {\n eventBus: EventBus;\n onAccepted: (messageId: string) => void;\n requestId: string;\n}): {\n dispose: Unsubscribe;\n promise: Promise<NcpMessage>;\n} {\n let acceptedMessageId: string | null = null;\n const completedMessagesById = new Map<string, NcpMessage>();\n let unsubscribe: Unsubscribe = () => undefined;\n const acceptMessageId = (messageId: string): void => {\n acceptedMessageId = messageId;\n input.onAccepted(messageId);\n };\n const promise = new Promise<NcpMessage>((resolve, reject) => {\n unsubscribe = input.eventBus.on(eventKeys.ncpEvent, (event) => {\n switch (event.type) {\n case NcpEventType.MessageAccepted:\n if (event.payload.correlationId === input.requestId) {\n acceptMessageId(event.payload.messageId);\n }\n return;\n case NcpEventType.MessageCompleted:\n if (event.payload.correlationId === input.requestId || event.payload.message.id === acceptedMessageId) {\n unsubscribe();\n resolve(event.payload.message);\n return;\n }\n completedMessagesById.set(event.payload.message.id, event.payload.message);\n return;\n case NcpEventType.RunFinished:\n if (\n (event.payload.correlationId === input.requestId ||\n event.payload.messageId === acceptedMessageId) &&\n event.payload.messageId\n ) {\n acceptMessageId(event.payload.messageId);\n const completedMessage = completedMessagesById.get(event.payload.messageId);\n if (completedMessage) {\n unsubscribe();\n resolve(completedMessage);\n }\n }\n return;\n case NcpEventType.MessageFailed:\n if (event.payload.correlationId === input.requestId || event.payload.messageId === acceptedMessageId) {\n unsubscribe();\n reject(new Error(event.payload.error.message));\n }\n return;\n case NcpEventType.RunError:\n if (\n event.payload.correlationId === input.requestId ||\n event.payload.messageId === acceptedMessageId\n ) {\n unsubscribe();\n reject(new Error(event.payload.error ?? \"Session request failed.\"));\n }\n return;\n }\n });\n });\n return {\n dispose: unsubscribe,\n promise,\n };\n}\n\nexport async function dispatchAgentRuntimeSessionRequest(input: {\n ingress: Ingress;\n request: SessionRequestRecord;\n task: string;\n}): Promise<void> {\n await input.ingress.handle<AgentRunSessionMessageRequestPayload, unknown>({\n type: ingressKeys.agentRun.sessionMessageRequest,\n payload: {\n message: {\n id: `${input.request.targetSessionId}:user:session-request:${input.request.requestId}`,\n sessionId: input.request.targetSessionId,\n role: \"user\",\n status: \"final\",\n timestamp: new Date().toISOString(),\n parts: [{ type: \"text\", text: input.task }],\n metadata: { session_request_id: input.request.requestId },\n },\n requestId: input.request.requestId,\n sessionId: input.request.targetSessionId,\n },\n }, { source: \"session-request\" });\n}\n\nexport function createAgentRuntimeSessionRequestDispatcher(\n options: AgentRuntimeSessionRequestDispatcherOptions,\n): SessionRequestDispatcher {\n return {\n dispatch: async (input) => {\n const reply = waitForAgentRuntimeSessionReply({\n eventBus: options.eventBus,\n onAccepted: input.onAccepted,\n requestId: input.request.requestId,\n });\n try {\n await dispatchAgentRuntimeSessionRequest({\n ingress: options.ingress,\n request: input.request,\n task: input.task,\n });\n const message = await reply.promise;\n return {\n finalResponseMessageId: message.id,\n finalResponseText: extractSessionMessageText(message),\n };\n } catch (error) {\n reply.dispose();\n throw error;\n }\n },\n };\n}\n","import type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport type { SessionRepository } from \"@kernel/features/agent-run/repositories/session.repository.js\";\nimport {\n ContextCompactionPreflightService,\n type ContextCompactionPreflightResult,\n} from \"@kernel/features/context-compaction/index.js\";\nimport {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpMessage,\n} from \"@nextclaw/ncp\";\n\nexport type AgentRunContextCompactionInput = {\n sessionId: string;\n agentId: string;\n messages: readonly NcpMessage[];\n metadata: Record<string, unknown>;\n};\n\nexport class AgentRunContextCompactionManager {\n private readonly preflightService: ContextCompactionPreflightService;\n\n constructor(\n configManager: ConfigManager,\n providerManager: LlmProviderRuntime,\n private readonly sessionRepository: SessionRepository,\n ) {\n this.preflightService = new ContextCompactionPreflightService({\n configManager,\n providerManager,\n });\n }\n\n runPreflight = async (\n input: AgentRunContextCompactionInput,\n ): Promise<readonly NcpEndpointEvent[]> => {\n const beginResult = this.preflightService.begin({\n inputMessages: [],\n requestMetadata: input.metadata,\n sessionId: input.sessionId,\n sessionMessages: input.messages,\n storedAgentId: input.agentId,\n storedMetadata: input.metadata,\n });\n const events = await this.toEvents(input.sessionId, beginResult);\n if (!beginResult.pendingCompaction) {\n return events;\n }\n const finishResult = await this.preflightService.finish(beginResult.pendingCompaction);\n return [\n ...events,\n ...(await this.toEvents(input.sessionId, finishResult)),\n ];\n };\n\n private toEvents = async (\n sessionId: string,\n result: ContextCompactionPreflightResult,\n ): Promise<NcpEndpointEvent[]> => {\n if (Object.keys(result.metadataPatch).length > 0) {\n await this.sessionRepository.patchSessionMetadata(sessionId, result.metadataPatch);\n }\n if (!result.timelineMessage) {\n return [];\n }\n return [\n {\n type: NcpEventType.MessageSent,\n payload: {\n sessionId,\n message: result.timelineMessage,\n },\n },\n ];\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n eventKeys,\n ingressKeys,\n type AgentRunSendIngressPayload,\n type AgentRunSessionMessageRequestPayload,\n type EventBus,\n type Ingress,\n type IngressEnvelope,\n} from \"@nextclaw/shared\";\nimport {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpMessage,\n type NcpMessageAbortPayload,\n type NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport {\n catchError,\n from,\n lastValueFrom,\n tap,\n} from \"rxjs\";\nimport { resolveDefaultAgentProfileId } from \"@nextclaw/core\";\nimport { readMessageTask } from \"@kernel/utils/session-run.utils.js\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type {\n AgentRuntimeManager,\n} from \"./agent-runtime.manager.js\";\nimport type { ContextProviderManager } from \"./context-provider.manager.js\";\nimport type {\n SessionRunManager,\n} from \"./session-run.manager.js\";\nimport type { ToolProviderManager } from \"./tool-provider.manager.js\";\nimport type { SessionRepository } from \"@kernel/features/agent-run/repositories/session.repository.js\";\nimport type {\n AgentRunAbortRequest,\n AgentRunAccepted,\n AgentRunRequest,\n AgentRunSpec,\n} from \"@kernel/features/agent-run/types/agent-run.types.js\";\n\nfunction toAgentRunRequest(envelope: AgentRunSendIngressPayload): AgentRunRequest {\n const metadata = envelope.metadata ?? {};\n const requestMetadata = {\n agentRuntimeId: metadata.agentRuntimeId,\n agentId: metadata.agentId,\n projectRoot: metadata.projectRoot,\n channel: metadata.channel,\n correlationId: envelope.correlationId,\n metadata: structuredClone(metadata),\n model: metadata.model,\n maxTokens: metadata.maxTokens,\n thinkingEffort: metadata.thinkingEffort,\n };\n if (Array.isArray(envelope.content)) {\n return {\n ...requestMetadata,\n sessionId: envelope.sessionId,\n message: {\n sessionId: envelope.sessionId ?? \"\",\n id: `user-message-${randomUUID()}`,\n role: \"user\",\n status: \"final\",\n timestamp: new Date().toISOString(),\n parts: structuredClone(envelope.content),\n },\n };\n }\n const sourceMessage = envelope.message;\n if (!sourceMessage) {\n throw new Error(\"Invalid agent run send request.\");\n }\n const messageSessionId = sourceMessage.sessionId;\n const message: NcpMessage = {\n ...sourceMessage,\n sessionId: messageSessionId ?? envelope.sessionId ?? \"\",\n id: sourceMessage.id ?? `user-message-${randomUUID()}`,\n role: sourceMessage.role ?? \"user\",\n status: sourceMessage.status ?? \"final\",\n timestamp: sourceMessage.timestamp ?? new Date().toISOString(),\n parts: structuredClone(sourceMessage.parts),\n };\n return {\n ...requestMetadata,\n sessionId: envelope.sessionId ?? messageSessionId,\n message,\n };\n}\n\nfunction toSessionMessageRequest(payload: AgentRunSessionMessageRequestPayload): AgentRunRequest {\n return {\n sessionId: payload.sessionId,\n message: {\n ...payload.message,\n sessionId: payload.sessionId,\n },\n correlationId: payload.requestId,\n };\n}\n\nfunction toRunHandle(accepted: AgentRunAccepted): NcpRunHandle {\n return {\n sessionId: accepted.sessionId,\n userMessageId: accepted.userMessageId,\n assistantMessageId: null,\n runId: accepted.runId,\n correlationId: accepted.correlationId,\n };\n}\n\nfunction findCompletedAssistantMessage(messages: readonly NcpMessage[], messageId?: string): NcpMessage | null {\n return [...messages]\n .reverse()\n .find((message) =>\n message.role === \"assistant\" &&\n message.status === \"final\" &&\n (!messageId || message.id === messageId)) ?? null;\n}\n\nexport class AgentRunRequestManager {\n readonly cleanups: Array<() => void> = [];\n private started = false;\n\n constructor(\n private readonly agentRuntimeManager: AgentRuntimeManager,\n private readonly configManager: ConfigManager,\n private readonly contextProviderManager: ContextProviderManager,\n private readonly eventBus: EventBus,\n private readonly ingress: Ingress,\n private readonly sessionRepository: SessionRepository,\n private readonly sessionRunManager: SessionRunManager,\n private readonly toolProviderManager: ToolProviderManager,\n ) {}\n\n start = (): void => {\n if (this.started) {\n return;\n }\n this.started = true;\n this.cleanups.push(\n this.ingress.addHandler(ingressKeys.agentRun.send, this.handleSendRequest),\n this.ingress.addHandler(ingressKeys.agentRun.abort, this.handleAbortRequest),\n this.ingress.addHandler(ingressKeys.agentRun.sessionMessageRequest, this.handleSessionMessageRequest),\n );\n };\n\n dispose = (): void => {\n while (this.cleanups.length > 0) {\n this.cleanups.pop()?.();\n }\n this.started = false;\n };\n\n private handleSendRequest = async (\n envelope: IngressEnvelope<AgentRunSendIngressPayload>,\n ): Promise<NcpRunHandle> => {\n if (!envelope.payload) {\n throw new Error(\"Invalid agent run send request.\");\n }\n return toRunHandle(await this.send(toAgentRunRequest(envelope.payload)));\n };\n\n private handleAbortRequest = async (\n envelope: IngressEnvelope<NcpMessageAbortPayload>,\n ): Promise<void> => {\n if (!envelope.payload?.sessionId) {\n throw new Error(\"Invalid agent run abort request.\");\n }\n await this.abort({ sessionId: envelope.payload.sessionId });\n };\n\n private handleSessionMessageRequest = async (\n envelope: IngressEnvelope<AgentRunSessionMessageRequestPayload>,\n ): Promise<NcpRunHandle> => {\n if (!envelope.payload) {\n throw new Error(\"Invalid agent run session message request.\");\n }\n return toRunHandle(await this.send(toSessionMessageRequest(envelope.payload)));\n };\n\n private send = async (request: AgentRunRequest): Promise<AgentRunAccepted> => {\n const session = await this.sessionRepository.getOrCreateSession({\n sessionId: request.sessionId,\n agentId: request.agentId,\n agentRuntimeId: request.agentRuntimeId,\n channel: request.channel,\n metadata: request.metadata,\n model: request.model,\n projectRoot: request.projectRoot,\n task: readMessageTask(request.message),\n thinkingEffort: request.thinkingEffort,\n });\n const sessionRun =\n this.sessionRunManager.getSessionRun(session.sessionId) ??\n await this.sessionRunManager.createSessionRun(session.sessionId);\n const message: NcpMessage = {\n ...request.message,\n sessionId: session.sessionId,\n };\n const providerRequest: AgentRunRequest = {\n ...request,\n sessionId: session.sessionId,\n message,\n };\n sessionRun.inbox.enqueue(message);\n const activeRun = sessionRun.beginRun();\n\n const model = request.model ?? session.model ?? this.configManager.getDefaultModel();\n const agentId = request.agentId ?? session.agentId ??\n resolveDefaultAgentProfileId(this.configManager.loadConfig());\n const spec: AgentRunSpec = {\n runId: activeRun.runId,\n agentId,\n model,\n maxTokens: request.maxTokens ?? this.configManager.getModelMaxTokens(model),\n thinkingEffort: request.thinkingEffort ?? session.thinkingEffort ?? null,\n correlationId: request.correlationId,\n };\n\n const runtime = this.agentRuntimeManager.getOrCreate({\n agentRuntimeId: session.agentRuntimeId,\n session,\n sessionRun,\n });\n const contextBlocks = await this.contextProviderManager.buildContext(providerRequest);\n const tools = await this.toolProviderManager.buildTools(providerRequest);\n let messageCompletedSeen = false;\n lastValueFrom(\n from(runtime.run(spec, {\n contextBlocks,\n sessionRun,\n signal: activeRun.signal,\n tools,\n })).pipe(\n tap((event) => {\n const eventsToPublish: NcpEndpointEvent[] = [];\n if (event.type === NcpEventType.MessageCompleted) {\n messageCompletedSeen = true;\n }\n if (event.type === NcpEventType.RunFinished && !messageCompletedSeen) {\n const message = findCompletedAssistantMessage(\n sessionRun.getSnapshot().messages,\n event.payload.messageId,\n );\n if (!message) {\n throw new Error(`Run finished without a final assistant message for session \"${session.sessionId}\".`);\n }\n eventsToPublish.push({\n type: NcpEventType.MessageCompleted,\n payload: {\n sessionId: event.payload.sessionId ?? session.sessionId,\n message,\n correlationId: event.payload.correlationId,\n },\n });\n messageCompletedSeen = true;\n }\n eventsToPublish.push(event);\n for (const eventToPublish of eventsToPublish) {\n this.eventBus.emit(eventKeys.ncpEvent, eventToPublish, {\n emittedAt: new Date().toISOString(),\n source: \"agent-run-request\",\n });\n }\n }),\n catchError(async (error) => {\n const event: NcpEndpointEvent = {\n type: NcpEventType.RunError,\n payload: {\n error: error instanceof Error ? error.message : String(error),\n runId: spec.runId,\n sessionId: session.sessionId,\n correlationId: spec.correlationId,\n },\n };\n await sessionRun.applyEvents([event]);\n this.eventBus.emit(eventKeys.ncpEvent, event, {\n emittedAt: new Date().toISOString(),\n source: \"agent-run-request\",\n });\n }),\n ),\n { defaultValue: undefined },\n );\n\n return {\n sessionId: session.sessionId,\n userMessageId: message.id,\n runId: spec.runId,\n correlationId: request.correlationId,\n };\n };\n\n private abort = async (request: AgentRunAbortRequest): Promise<void> => {\n const sessionRun = this.sessionRunManager.getSessionRun(request.sessionId);\n sessionRun?.abortRun(request.runId);\n };\n}\n","import type {\n NcpEndpointEvent,\n NcpTool,\n} from \"@nextclaw/ncp\";\nimport type { SessionRun } from \"./session-run.manager.js\";\nimport type {\n AgentRunSpec,\n ContextBlock,\n} from \"@kernel/features/agent-run/types/agent-run.types.js\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport type { AgentRunSession } from \"@kernel/features/agent-run/repositories/session.repository.js\";\nimport type {\n AgentRuntimeEntry,\n AgentRuntimeSessionTypeDescribeParams,\n AgentRuntimeSessionTypeOption,\n} from \"@kernel/features/runtime-registry/index.js\";\n\nexport type AgentRuntimeRunOptions = {\n sessionRun: SessionRun;\n contextBlocks: readonly ContextBlock[];\n tools: readonly NcpTool[];\n signal?: AbortSignal;\n};\n\nexport type AgentRuntime = {\n run: (\n spec: AgentRunSpec,\n options: AgentRuntimeRunOptions,\n ) => AsyncIterable<NcpEndpointEvent>;\n dispose?: () => Promise<void> | void;\n};\n\nexport type AgentRuntimeRegistration = {\n kind: string;\n label: string;\n defaultReuseScope: AgentRuntimeReuseScope;\n createRuntime: (params: AgentRuntimeCreateParams) => AgentRuntime;\n describeSessionTypeForEntry?: (params: {\n entry: AgentRuntimeEntry;\n describeParams?: AgentRuntimeSessionTypeDescribeParams;\n }) => Promise<Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\"> | null | undefined>\n | Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\">\n | null\n | undefined;\n};\n\nexport type AgentRuntimeReuseScope = \"global\" | \"session\";\n\nexport type AgentRuntimeCreateParams = {\n entry: AgentRuntimeEntry;\n session: AgentRunSession;\n sessionRun: SessionRun;\n};\n\ntype AgentRuntimeCacheParams = {\n agentRuntimeId: string;\n session: AgentRunSession;\n sessionRun: SessionRun;\n};\n\nexport class AgentRuntimeManager {\n private readonly providers = new Map<string, AgentRuntimeRegistration>();\n private readonly entries = new Map<string, AgentRuntimeEntry>();\n private readonly globalRuntimes = new Map<string, AgentRuntime>();\n private readonly sessionRuntimes = new Map<string, AgentRuntime>();\n\n register = (registration: AgentRuntimeRegistration): (() => Promise<void>) => {\n const kind = this.normalizeId(registration.kind);\n if (this.providers.has(kind)) {\n throw new Error(`Agent runtime provider is already registered: ${kind}`);\n }\n const normalizedRegistration = {\n ...registration,\n kind,\n };\n this.providers.set(kind, normalizedRegistration);\n return async () => {\n if (this.providers.get(kind) !== normalizedRegistration) {\n return;\n }\n this.providers.delete(kind);\n await this.disposeAllRuntimes();\n };\n };\n\n applyEntries = (entries: readonly AgentRuntimeEntry[]): void => {\n this.entries.clear();\n for (const entry of entries) {\n this.entries.set(this.normalizeId(entry.id), {\n ...entry,\n id: this.normalizeId(entry.id),\n type: this.normalizeId(entry.type),\n });\n }\n };\n\n getOrCreate = (params: AgentRuntimeCacheParams): AgentRuntime => {\n const { agentRuntimeId, session, sessionRun } = params;\n const entry = this.getEntry(agentRuntimeId);\n const provider = this.getProvider(entry.type);\n const reuseScope = this.resolveReuseScope(entry, provider);\n const cacheKey = reuseScope === \"global\"\n ? entry.id\n : `${entry.id}:${session.sessionId}`;\n const cache = reuseScope === \"global\"\n ? this.globalRuntimes\n : this.sessionRuntimes;\n const existing = cache.get(cacheKey);\n if (existing) {\n return existing;\n }\n const agentRuntime = provider.createRuntime({\n entry,\n session,\n sessionRun,\n });\n cache.set(cacheKey, agentRuntime);\n return agentRuntime;\n };\n\n listSessionTypes = async (\n _params?: AgentRuntimeSessionTypeDescribeParams,\n ): Promise<{\n defaultType: string;\n options: AgentRuntimeSessionTypeOption[];\n }> => {\n const entries = [...this.entries.values()].filter((entry) => entry.enabled !== false);\n const options = await Promise.all(entries.map(async (entry) => {\n const provider = this.providers.get(entry.type);\n const descriptor = provider?.describeSessionTypeForEntry\n ? await provider.describeSessionTypeForEntry({ entry, describeParams: _params })\n : null;\n return {\n value: entry.id,\n label: entry.label,\n icon: descriptor?.icon ?? entry.icon ?? null,\n ready: provider ? descriptor?.ready ?? true : false,\n reason: provider ? descriptor?.reason ?? null : \"runtime_provider_unavailable\",\n reasonMessage: provider\n ? descriptor?.reasonMessage ?? null\n : `Runtime provider unavailable for type \"${entry.type}\".`,\n recommendedModel: descriptor?.recommendedModel ?? null,\n cta: descriptor?.cta ?? null,\n ...(descriptor?.supportedModels ? { supportedModels: descriptor.supportedModels } : {}),\n } satisfies AgentRuntimeSessionTypeOption;\n }));\n return {\n defaultType: this.entries.has(DEFAULT_AGENT_RUNTIME_ENTRY_ID)\n ? DEFAULT_AGENT_RUNTIME_ENTRY_ID\n : entries[0]?.id ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID,\n options,\n };\n };\n\n dispose = async (): Promise<void> => {\n await this.disposeAllRuntimes();\n this.providers.clear();\n this.entries.clear();\n };\n\n private normalizeId = (agentRuntimeId: string): string => {\n const normalizedId = agentRuntimeId.trim();\n if (!normalizedId) {\n throw new Error(\"Agent runtime id is required.\");\n }\n return normalizedId;\n };\n\n private getEntry = (agentRuntimeId: string): AgentRuntimeEntry => {\n const normalizedId = this.normalizeId(agentRuntimeId);\n const entry = this.entries.get(normalizedId);\n if (!entry || entry.enabled === false) {\n throw new Error(`Agent runtime entry is not registered: ${normalizedId}`);\n }\n return entry;\n };\n\n private getProvider = (kind: string): AgentRuntimeRegistration => {\n const provider = this.providers.get(this.normalizeId(kind));\n if (!provider) {\n throw new Error(`Agent runtime provider is not registered: ${kind}`);\n }\n return provider;\n };\n\n private resolveReuseScope = (\n entry: AgentRuntimeEntry,\n provider: AgentRuntimeRegistration,\n ): AgentRuntimeReuseScope => {\n return entry.config?.reuseScope === \"session\" || entry.config?.reuseScope === \"global\"\n ? entry.config.reuseScope\n : provider.defaultReuseScope;\n };\n\n private disposeAllRuntimes = async (): Promise<void> => {\n for (const runtime of [...this.globalRuntimes.values(), ...this.sessionRuntimes.values()]) {\n await runtime.dispose?.();\n }\n this.globalRuntimes.clear();\n this.sessionRuntimes.clear();\n };\n}\n","import type {\n AgentRunRequest,\n ContextBlock,\n ContextProvider,\n} from \"@kernel/features/agent-run/types/agent-run.types.js\";\n\nexport class ContextProviderManager {\n private readonly providers = new Set<ContextProvider>();\n\n register = (provider: ContextProvider): (() => void) => {\n this.providers.add(provider);\n return () => {\n this.providers.delete(provider);\n };\n };\n\n buildContext = async (request: AgentRunRequest): Promise<readonly ContextBlock[]> => {\n const blocks: ContextBlock[] = [];\n for (const provider of [...this.providers]) {\n blocks.push(...await provider.provide(request));\n }\n return blocks;\n };\n\n dispose = (): void => {\n this.providers.clear();\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n NcpEventType,\n type NcpAgentConversationStateManager,\n type NcpEndpointEvent,\n type NcpMessage,\n} from \"@nextclaw/ncp\";\nimport { DefaultNcpAgentConversationStateManager } from \"@nextclaw/ncp-toolkit\";\nimport type { SessionRepository } from \"@kernel/features/agent-run/repositories/session.repository.js\";\n\nexport type SessionRunSnapshot = {\n messages: readonly NcpMessage[];\n};\n\nexport type SessionRunSeed = {\n sessionId: string;\n messages: readonly NcpMessage[];\n};\n\nexport type SessionRunActiveRun = {\n runId: string;\n signal: AbortSignal;\n};\n\nexport class MessageInbox<T> {\n private readonly messages: T[] = [];\n\n enqueue = (message: T): void => {\n this.messages.push(message);\n };\n\n drain = (): T[] => {\n return this.messages.splice(0, this.messages.length);\n };\n\n isEmpty = (): boolean => this.messages.length === 0;\n}\n\nfunction isConversationStateEvent(event: NcpEndpointEvent): boolean {\n return event.type !== NcpEventType.ContextWindowUpdated;\n}\n\nexport class SessionRun {\n readonly inbox = new MessageInbox<NcpMessage>();\n readonly sessionId: string;\n private activeRunId: string | null = null;\n private activeRunController: AbortController | null = null;\n\n constructor(\n seed: SessionRunSeed,\n private readonly stateManager: NcpAgentConversationStateManager = new DefaultNcpAgentConversationStateManager(),\n ) {\n this.sessionId = seed.sessionId;\n this.stateManager.hydrate({\n sessionId: seed.sessionId,\n messages: seed.messages,\n });\n }\n\n getSnapshot = (): SessionRunSnapshot => {\n const snapshot = this.stateManager.getSnapshot();\n return {\n messages: snapshot.streamingMessage ? [...snapshot.messages, snapshot.streamingMessage] : snapshot.messages,\n };\n };\n\n applyEvents = async (events: readonly NcpEndpointEvent[]): Promise<void> => {\n this.applyRunEvents(events);\n const conversationEvents = events.filter(isConversationStateEvent);\n if (conversationEvents.length > 0) {\n await this.stateManager.dispatchBatch(conversationEvents);\n }\n };\n\n beginRun = (): SessionRunActiveRun => {\n if (this.activeRunId) {\n throw new Error(`Session ${this.sessionId} already has an active run.`);\n }\n const runId = `agent-run-${randomUUID()}`;\n const controller = new AbortController();\n this.activeRunId = runId;\n this.activeRunController = controller;\n return {\n runId,\n signal: controller.signal,\n };\n };\n\n abortRun = (runId?: string): boolean => {\n if (!this.activeRunId || !this.activeRunController) {\n return false;\n }\n if (runId && this.activeRunId !== runId) {\n return false;\n }\n this.activeRunController.abort();\n return true;\n };\n\n dispose = (): void => {\n this.activeRunController?.abort();\n this.activeRunController = null;\n this.activeRunId = null;\n };\n\n private applyRunEvents = (events: readonly NcpEndpointEvent[]): void => {\n for (const event of events) {\n if (event.type === NcpEventType.RunStarted && event.payload.runId) {\n this.activeRunId = event.payload.runId;\n }\n if (\n event.type === NcpEventType.MessageAbort ||\n ((event.type === NcpEventType.RunFinished || event.type === NcpEventType.RunError) &&\n (!event.payload.runId || event.payload.runId === this.activeRunId))\n ) {\n this.activeRunId = null;\n this.activeRunController = null;\n }\n }\n };\n}\n\nexport class SessionRunManager {\n private readonly runs = new Map<string, SessionRun>();\n\n constructor(private readonly sessionRepository: SessionRepository) {}\n\n getSessionRun = (sessionId: string): SessionRun | null =>\n this.runs.get(sessionId) ?? null;\n\n createSessionRun = async (sessionId: string): Promise<SessionRun> => {\n if (this.runs.has(sessionId)) {\n throw new Error(`Session run already exists: ${sessionId}`);\n }\n const messages = await this.sessionRepository.listSessionMessages(sessionId);\n const seed = {\n messages,\n sessionId,\n };\n const run = new SessionRun(seed);\n this.runs.set(sessionId, run);\n return run;\n };\n\n deleteSessionRun = (sessionId: string): boolean => {\n const run = this.runs.get(sessionId);\n if (!run) {\n return false;\n }\n run.dispose();\n return this.runs.delete(sessionId);\n };\n\n dispose = (): void => {\n for (const run of this.runs.values()) {\n run.dispose();\n }\n this.runs.clear();\n };\n}\n","import type { NcpTool } from \"@nextclaw/ncp\";\nimport type {\n AgentRunRequest,\n ToolProvider,\n} from \"@kernel/features/agent-run/types/agent-run.types.js\";\n\nexport class ToolProviderManager {\n private readonly providers = new Set<ToolProvider>();\n\n register = (provider: ToolProvider): (() => void) => {\n this.providers.add(provider);\n return () => {\n this.providers.delete(provider);\n };\n };\n\n buildTools = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const tools: NcpTool[] = [];\n for (const provider of [...this.providers]) {\n tools.push(...await provider.provide(request));\n }\n return tools;\n };\n\n dispose = (): void => {\n this.providers.clear();\n };\n}\n","import {\n eventKeys,\n type EventBus,\n} from \"@nextclaw/shared\";\nimport {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpMessage,\n} from \"@nextclaw/ncp\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport type { ThinkingEffort } from \"@kernel/features/agent-run/types/agent-run.types.js\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\n\nexport type AgentRunSession = {\n sessionId: string;\n agentId?: string;\n agentRuntimeId: string;\n metadata: Record<string, unknown>;\n model?: string;\n projectRoot?: string;\n thinkingEffort?: ThinkingEffort | null;\n};\n\nexport type CreateAgentRunSessionParams = {\n sessionId?: string;\n agentId?: string;\n agentRuntimeId?: string;\n channel?: string;\n metadata?: Record<string, unknown>;\n model?: string;\n projectRoot?: string;\n task?: string;\n thinkingEffort?: ThinkingEffort | null;\n};\n\nfunction readString(value: unknown): string | undefined {\n const trimmed = typeof value === \"string\" ? value.trim() : \"\";\n return trimmed || undefined;\n}\n\nfunction readEventSessionId(event: NcpEndpointEvent): string | undefined {\n return \"payload\" in event && \"sessionId\" in event.payload\n ? readString(event.payload.sessionId)\n : undefined;\n}\n\nfunction isDurableSessionEvent(event: NcpEndpointEvent): boolean {\n return event.type !== NcpEventType.ContextWindowUpdated;\n}\n\nfunction readThinkingEffort(metadata: Record<string, unknown> | undefined): ThinkingEffort | null {\n return readString(metadata?.thinkingEffort) ?? null;\n}\n\nfunction readProjectRoot(metadata: Record<string, unknown> | undefined): string | undefined {\n return readString(metadata?.project_root) ?? readString(metadata?.projectRoot);\n}\n\nexport class SessionRepository {\n readonly cleanups: Array<() => void> = [];\n private started = false;\n\n constructor(\n private readonly eventBus: EventBus,\n private readonly ncpSessionManager: NcpSessionManager,\n ) {}\n\n start = (): void => {\n if (this.started) {\n return;\n }\n this.started = true;\n this.cleanups.push(this.eventBus.on(eventKeys.ncpEvent, async (event) => {\n const sessionId = readEventSessionId(event);\n if (!sessionId || !isDurableSessionEvent(event)) {\n return;\n }\n await this.appendSessionEvent(sessionId, event);\n }));\n };\n\n dispose = (): void => {\n while (this.cleanups.length > 0) {\n this.cleanups.pop()?.();\n }\n this.started = false;\n };\n\n getSession = async (sessionId: string): Promise<AgentRunSession> => {\n const record = await this.ncpSessionManager.getSessionRecord(sessionId);\n if (!record) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n const agentRuntimeId = readString(record.metadata?.agentRuntimeId) ??\n DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n const model = readString(record.metadata?.model);\n return {\n sessionId: record.sessionId,\n agentId: record.agentId,\n agentRuntimeId,\n metadata: structuredClone(record.metadata ?? {}),\n model,\n projectRoot: readProjectRoot(record.metadata),\n thinkingEffort: readThinkingEffort(record.metadata),\n };\n };\n\n createSession = async (params: CreateAgentRunSessionParams): Promise<AgentRunSession> => {\n const {\n agentId,\n agentRuntimeId: requestedAgentRuntimeId,\n channel,\n metadata,\n model,\n projectRoot,\n sessionId,\n task,\n thinkingEffort,\n } = params;\n const agentRuntimeId = requestedAgentRuntimeId ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n const created = await this.ncpSessionManager.createSession({\n sourceSessionMetadata: {},\n sessionId,\n task: task ?? \"Session\",\n agentId,\n metadataOverrides: {\n ...structuredClone(metadata ?? {}),\n agentRuntimeId,\n channel,\n },\n model,\n projectRoot,\n runtime: agentRuntimeId,\n sessionType: agentRuntimeId,\n thinkingLevel: thinkingEffort ?? undefined,\n });\n return {\n sessionId: created.sessionId,\n agentId,\n agentRuntimeId,\n metadata: structuredClone(created.metadata ?? {}),\n model,\n projectRoot,\n thinkingEffort: thinkingEffort ?? null,\n };\n };\n\n getOrCreateSession = async (\n params: CreateAgentRunSessionParams,\n ): Promise<AgentRunSession> => {\n if (!params.sessionId) {\n return await this.createSession(params);\n }\n const existing = await this.ncpSessionManager.getSessionRecord(params.sessionId);\n if (existing) {\n return await this.getSession(params.sessionId);\n }\n return await this.createSession(params);\n };\n\n listSessionMessages = async (sessionId: string): Promise<readonly NcpMessage[]> => {\n return await this.ncpSessionManager.listSessionMessages(sessionId);\n };\n\n patchSessionMetadata = async (\n sessionId: string,\n patch: Record<string, unknown>,\n ): Promise<void> => {\n const updated = await this.ncpSessionManager.updateSessionMetadata(sessionId, patch);\n if (!updated) {\n throw new Error(`Session metadata was not updated: ${sessionId}`);\n }\n };\n\n private appendSessionEvent = async (\n sessionId: string,\n event: NcpEndpointEvent,\n ): Promise<void> => {\n await this.ncpSessionManager.appendSessionEvent({\n event,\n sessionId,\n });\n };\n}\n","import type { NcpMessage } from \"@nextclaw/ncp\";\nimport { projectNcpMessagesWithContextCompaction } from \"@kernel/features/context-compaction/index.js\";\n\nexport type AgentRunMessageProjectParams = {\n sessionId: string;\n messages: readonly NcpMessage[];\n};\n\nexport class AgentRunMessageProjector {\n project = (params: AgentRunMessageProjectParams): NcpMessage[] =>\n projectNcpMessagesWithContextCompaction({\n sessionId: params.sessionId,\n sessionMessages: params.messages,\n });\n}\n","import {\n ContextWindowBudgetService,\n findEffectiveAgentProfile,\n InputBudgetPruner,\n resolveDefaultAgentProfileId,\n type InputBudgetPruneResult,\n} from \"@nextclaw/core\";\nimport type { OpenAIChatMessage } from \"@nextclaw/ncp\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { AgentRunSpec } from \"@kernel/features/agent-run/types/agent-run.types.js\";\n\nexport type AgentRunModelInputBudgeterPruneParams = {\n spec: AgentRunSpec;\n messages: readonly OpenAIChatMessage[];\n};\n\nexport type AgentRunModelInputBudgeterPruneResult = Omit<\n InputBudgetPruneResult,\n \"messages\"\n> & {\n messages: OpenAIChatMessage[];\n};\n\nexport class AgentRunModelInputBudgeter {\n private readonly inputBudgetPruner = new InputBudgetPruner();\n\n constructor(private readonly configManager: ConfigManager) {}\n\n prune = async (\n params: AgentRunModelInputBudgeterPruneParams,\n ): Promise<AgentRunModelInputBudgeterPruneResult> => {\n const config = this.configManager.loadConfig();\n const defaultAgentId = resolveDefaultAgentProfileId(config);\n const profile =\n findEffectiveAgentProfile(config, params.spec.agentId) ??\n findEffectiveAgentProfile(config, defaultAgentId);\n const contextTokens = profile?.contextTokens ?? config.agents.defaults.contextTokens;\n const reservedContextTokens = ContextWindowBudgetService.resolveReservedContextTokens({\n contextTokens,\n configuredReservedContextTokens:\n profile?.reservedContextTokens ?? config.agents.defaults.reservedContextTokens,\n });\n const pruned = this.inputBudgetPruner.prune({\n messages: params.messages.map((message) => ({ ...message })),\n contextTokens,\n reserveTokensFloor: reservedContextTokens,\n softThresholdTokens: 0,\n });\n\n return {\n ...pruned,\n messages: pruned.messages as OpenAIChatMessage[],\n };\n };\n}\n","import {\n buildOpenAiFunctionTool,\n ncpMessageToOpenAiMessages,\n type LocalAssetStore,\n} from \"@nextclaw/ncp-agent-runtime\";\nimport type {\n AgentModelInputBuildRequest,\n AgentModelInputBuilder,\n} from \"@nextclaw/ncp-agent-runtime-next\";\nimport type {\n NcpLLMApiInput,\n NcpToolDefinition,\n OpenAIChatMessage,\n OpenAITool,\n} from \"@nextclaw/ncp\";\nimport type { AgentRunMessageProjector } from \"./agent-run-message-projector.service.js\";\nimport type { AgentRunModelInputBudgeter } from \"./agent-run-model-input-budgeter.service.js\";\n\nexport class AgentRunModelInputBuilder implements AgentModelInputBuilder {\n constructor(\n private readonly messageProjector: AgentRunMessageProjector,\n private readonly modelInputBudgeter: AgentRunModelInputBudgeter,\n private readonly assetStore: LocalAssetStore | null = null,\n ) {}\n\n build = async (request: AgentModelInputBuildRequest): Promise<NcpLLMApiInput> => {\n const contextContent = request.contextBlocks\n .map((block) => block.trim())\n .filter(Boolean)\n .join(\"\\n\\n\");\n const contextMessages: OpenAIChatMessage[] = contextContent\n ? [{ role: \"system\", content: contextContent }]\n : [];\n const projectedMessages = this.messageProjector.project({\n sessionId: request.sessionId,\n messages: request.messages,\n });\n const conversationMessages = projectedMessages.flatMap((message) =>\n ncpMessageToOpenAiMessages(message, {\n assetStore: this.assetStore,\n }),\n );\n const pruned = await this.modelInputBudgeter.prune({\n spec: request.spec,\n messages: [...contextMessages, ...conversationMessages],\n });\n const tools = request.tools.map((tool): OpenAITool =>\n buildOpenAiFunctionTool({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n } satisfies NcpToolDefinition),\n );\n\n return {\n messages: pruned.messages,\n tools: tools.length > 0 ? tools : undefined,\n model: request.spec.model,\n thinkingLevel: request.spec.thinkingEffort ?? null,\n max_tokens: request.spec.maxTokens,\n };\n };\n}\n","import { buildOpenAiFunctionTool } from \"@nextclaw/ncp-agent-runtime\";\nimport type {\n NcpAgentConversationStateManager,\n NcpAgentRunInput,\n NcpAgentRuntime,\n NcpEndpointEvent,\n NcpMessage,\n NcpTool,\n OpenAITool,\n} from \"@nextclaw/ncp\";\nimport { NcpEventType } from \"@nextclaw/ncp\";\nimport { DefaultNcpAgentConversationStateManager } from \"@nextclaw/ncp-toolkit\";\nimport type {\n AgentRuntime,\n AgentRuntimeRunOptions,\n} from \"@kernel/features/agent-run/managers/agent-runtime.manager.js\";\nimport type { AgentRunSession } from \"@kernel/features/agent-run/repositories/session.repository.js\";\nimport type { AgentRunSpec } from \"@kernel/features/agent-run/types/agent-run.types.js\";\n\nexport type NcpAgentRuntimeWrapperParams = {\n session: AgentRunSession;\n createRuntime: (params: {\n resolveTools: (input: NcpAgentRunInput) => ReadonlyArray<OpenAITool> | undefined;\n stateManager: NcpAgentConversationStateManager;\n }) => NcpAgentRuntime;\n};\n\nexport class NcpAgentRuntimeWrapper implements AgentRuntime {\n private readonly stateManager = new DefaultNcpAgentConversationStateManager();\n private runtime: NcpAgentRuntime | null = null;\n private currentTools: ReadonlyArray<OpenAITool> = [];\n\n constructor(private readonly params: NcpAgentRuntimeWrapperParams) {}\n\n run = async function* (\n this: NcpAgentRuntimeWrapper,\n spec: AgentRunSpec,\n options: AgentRuntimeRunOptions,\n ): AsyncIterable<NcpEndpointEvent> {\n const { sessionRun, tools } = options;\n this.currentTools = tools.map(this.toOpenAiTool);\n const messages = sessionRun.inbox.drain();\n for (const event of this.toMessageSentEvents(messages, spec, sessionRun.sessionId)) {\n yield await this.applyEvent(sessionRun, event);\n }\n const input: NcpAgentRunInput & { runId?: string } = {\n sessionId: sessionRun.sessionId,\n runId: spec.runId,\n messages,\n correlationId: spec.correlationId,\n metadata: this.buildMetadata(spec),\n };\n for await (const event of this.getRuntime().run(input, { signal: options.signal })) {\n yield await this.applyEvent(sessionRun, event);\n }\n this.currentTools = [];\n };\n\n dispose = async (): Promise<void> => {\n if (this.runtime && \"dispose\" in this.runtime && typeof this.runtime.dispose === \"function\") {\n await this.runtime.dispose();\n }\n this.runtime = null;\n this.currentTools = [];\n };\n\n private getRuntime = (): NcpAgentRuntime => {\n if (!this.runtime) {\n this.runtime = this.params.createRuntime({\n resolveTools: () => this.currentTools,\n stateManager: this.stateManager,\n });\n }\n return this.runtime;\n };\n\n private toMessageSentEvents = (\n messages: readonly NcpMessage[],\n spec: AgentRunSpec,\n sessionId: string,\n ): NcpEndpointEvent[] =>\n messages.map((message) => ({\n type: NcpEventType.MessageSent,\n payload: {\n sessionId,\n message,\n correlationId: spec.correlationId,\n },\n }));\n\n private buildMetadata = (spec: AgentRunSpec): Record<string, unknown> => ({\n ...this.params.session.metadata,\n agentId: spec.agentId,\n agentRuntimeId: this.params.session.agentRuntimeId,\n maxTokens: spec.maxTokens,\n model: spec.model,\n preferred_model: spec.model,\n thinkingEffort: spec.thinkingEffort,\n });\n\n private toOpenAiTool = (tool: NcpTool): OpenAITool =>\n buildOpenAiFunctionTool({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n });\n\n private applyEvent = async (\n sessionRun: AgentRuntimeRunOptions[\"sessionRun\"],\n event: NcpEndpointEvent,\n ): Promise<NcpEndpointEvent> => {\n await sessionRun.applyEvents([event]);\n return event;\n };\n}\n","import type { AgentRunSession } from \"@kernel/features/agent-run/repositories/session.repository.js\";\nimport type { AgentRunRequest } from \"@kernel/features/agent-run/types/agent-run.types.js\";\n\nfunction normalizeString(value: string | null | undefined): string | undefined {\n const normalized = value?.trim();\n return normalized || undefined;\n}\n\nexport function buildAgentRunRequestMetadata(params: {\n request: AgentRunRequest;\n session?: AgentRunSession | null;\n}): Record<string, unknown> {\n const { request, session } = params;\n const agentId = normalizeString(request.agentId ?? session?.agentId);\n const projectRoot = normalizeString(request.projectRoot ?? session?.projectRoot);\n const channel = normalizeString(request.channel);\n const model = normalizeString(request.model ?? session?.model);\n\n return {\n ...structuredClone(session?.metadata ?? {}),\n agentId,\n projectRoot,\n project_root: projectRoot,\n channel,\n model,\n thinkingEffort: request.thinkingEffort ?? session?.thinkingEffort,\n };\n}\n","import { access } from \"node:fs/promises\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport {\n ProviderRegistry,\n resolveProviderRuntime,\n type Config,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { BUILTIN_PROVIDER_PLUGINS } from \"@nextclaw/runtime\";\nimport type { NcpAgentRunInput, NcpProviderRuntimeRoute } from \"@nextclaw/ncp\";\nimport type { RuntimeFactoryParams } from \"@nextclaw/ncp-toolkit\";\nimport {\n HttpRuntimeConfigResolver,\n HttpRuntimeNcpAgentRuntime,\n} from \"@nextclaw/nextclaw-ncp-runtime-http-client\";\nimport {\n probeStdioRuntime,\n StdioRuntimeConfigResolver,\n StdioRuntimeNcpAgentRuntime,\n} from \"@nextclaw/nextclaw-ncp-runtime-stdio-client\";\nimport type {\n AgentRuntimeEntry,\n AgentRuntimeProviderRegistration,\n AgentRuntimeSessionTypeDescribeParams,\n AgentRuntimeSessionTypeOption,\n} from \"@kernel/features/runtime-registry/index.js\";\n\nconst NARP_API_MODE_HEADER = \"x-nextclaw-narp-api-mode\";\nexport const NARP_HTTP_RUNTIME_KIND = \"narp-http\";\nexport const NARP_STDIO_RUNTIME_KIND = \"narp-stdio\";\nconst BUILTIN_PROVIDER_REGISTRY = new ProviderRegistry(BUILTIN_PROVIDER_PLUGINS);\n\ntype SessionTypeDescriptor = Omit<AgentRuntimeSessionTypeOption, \"value\" | \"label\">;\n\nfunction readRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction resolveEntryIcon(\n entry: AgentRuntimeEntry,\n): SessionTypeDescriptor[\"icon\"] {\n return entry.icon ?? null;\n}\n\nfunction resolveRequestedModel(params: {\n input: NcpAgentRunInput;\n sessionMetadata: Record<string, unknown>;\n defaultModel?: string;\n configuredModel?: string;\n}): string | undefined {\n const { configuredModel, defaultModel, input, sessionMetadata } = params;\n const runMetadata = readRecord(input.metadata);\n return (\n readString(runMetadata?.preferred_model) ??\n readString(runMetadata?.preferredModel) ??\n readString(runMetadata?.model) ??\n readString(sessionMetadata.preferred_model) ??\n readString(sessionMetadata.preferredModel) ??\n readString(sessionMetadata.model) ??\n configuredModel ??\n defaultModel\n );\n}\n\nfunction resolveProviderApiMode(\n resolution: ReturnType<typeof resolveProviderRuntime>,\n): \"chat_completions\" | \"codex_responses\" | \"anthropic_messages\" {\n const wireApi = resolution.provider?.wireApi?.trim().toLowerCase();\n if (wireApi === \"responses\") {\n return \"codex_responses\";\n }\n if (wireApi === \"chat\") {\n return \"chat_completions\";\n }\n const providerName = resolution.providerName?.trim().toLowerCase();\n const apiBase = resolution.apiBase?.trim().toLowerCase() ?? \"\";\n if (providerName === \"anthropic\" || apiBase.includes(\"anthropic.com\")) {\n return \"anthropic_messages\";\n }\n return \"chat_completions\";\n}\n\nfunction buildProviderRoute(params: {\n config: Config;\n input: NcpAgentRunInput;\n sessionMetadata: Record<string, unknown>;\n defaultModel?: string;\n configuredModel?: string;\n}): NcpProviderRuntimeRoute | undefined {\n const model = resolveRequestedModel(params);\n if (!model) {\n return undefined;\n }\n const resolution = resolveProviderRuntime(params.config, model);\n if (!resolution.provider) {\n return undefined;\n }\n const apiBase =\n resolution.apiBase ??\n (resolution.providerName\n ? BUILTIN_PROVIDER_REGISTRY.findProviderByName(resolution.providerName)?.defaultApiBase ?? null\n : null);\n return {\n model: resolution.providerLocalModel,\n apiKey: resolution.apiKey,\n apiBase,\n headers: {\n ...(resolution.provider.extraHeaders ?? {}),\n [NARP_API_MODE_HEADER]: resolveProviderApiMode(resolution),\n },\n };\n}\n\nclass BuiltinHttpRuntimeSessionTypeService {\n private readonly pendingDescribeByMode = new Map<\n \"observation\" | \"probe\",\n Promise<SessionTypeDescriptor>\n >();\n\n constructor(private readonly entry: AgentRuntimeEntry, private readonly defaultModel?: string) {}\n\n describe = async (\n describeParams?: AgentRuntimeSessionTypeDescribeParams,\n ): Promise<SessionTypeDescriptor> => {\n const describeMode =\n describeParams?.describeMode === \"probe\" ? \"probe\" : \"observation\";\n const pending = this.pendingDescribeByMode.get(describeMode);\n if (pending) {\n return await pending;\n }\n const nextDescribe = this.describeInternal();\n this.pendingDescribeByMode.set(describeMode, nextDescribe);\n try {\n return await nextDescribe;\n } finally {\n this.pendingDescribeByMode.delete(describeMode);\n }\n };\n\n private describeInternal = async (): Promise<SessionTypeDescriptor> => {\n const resolver = new HttpRuntimeConfigResolver(this.entry.config ?? {});\n const config = resolver.resolve({\n defaultModel: this.defaultModel,\n });\n\n if (!config.baseUrl) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"base_url_missing\",\n reasonMessage: \"Configure the runtime entry baseUrl before starting an HTTP runtime session.\",\n recommendedModel: config.recommendedModel ?? null,\n cta: {\n kind: \"settings\",\n label: \"Configure HTTP Runtime\",\n },\n };\n }\n\n const shouldProbe = (config.capabilityProbe ?? true) && Boolean(config.healthcheckUrl);\n if (!shouldProbe) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: true,\n reason: null,\n reasonMessage: null,\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n }\n\n const controller = new AbortController();\n const timeoutMs = config.healthcheckTimeoutMs ?? 3000;\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(config.healthcheckUrl ?? \"\", {\n method: \"GET\",\n headers: config.headers,\n signal: controller.signal,\n });\n if (!response.ok) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"healthcheck_failed\",\n reasonMessage: `HTTP runtime healthcheck returned HTTP ${response.status}.`,\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n }\n return {\n icon: resolveEntryIcon(this.entry),\n ready: true,\n reason: null,\n reasonMessage: null,\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n } catch (error) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"healthcheck_unreachable\",\n reasonMessage:\n error instanceof Error\n ? error.message\n : \"Failed to reach the configured HTTP runtime healthcheck.\",\n recommendedModel: config.recommendedModel ?? null,\n ...(config.supportedModels ? { supportedModels: config.supportedModels } : {}),\n cta: null,\n };\n } finally {\n clearTimeout(timeout);\n }\n };\n}\n\nclass BuiltinStdioRuntimeSessionTypeService {\n private readonly pendingDescribeByMode = new Map<\n \"observation\" | \"probe\",\n Promise<SessionTypeDescriptor>\n >();\n\n constructor(private readonly entry: AgentRuntimeEntry) {}\n\n describe = async (\n describeParams?: AgentRuntimeSessionTypeDescribeParams,\n ): Promise<SessionTypeDescriptor> => {\n const describeMode =\n describeParams?.describeMode === \"probe\" ? \"probe\" : \"observation\";\n const pending = this.pendingDescribeByMode.get(describeMode);\n if (pending) {\n return await pending;\n }\n const nextDescribe = this.describeInternal(describeMode);\n this.pendingDescribeByMode.set(describeMode, nextDescribe);\n try {\n return await nextDescribe;\n } finally {\n this.pendingDescribeByMode.delete(describeMode);\n }\n };\n\n private describeInternal = async (\n describeMode: \"observation\" | \"probe\",\n ): Promise<SessionTypeDescriptor> => {\n const resolver = new StdioRuntimeConfigResolver(this.entry.config ?? {});\n try {\n const config = resolver.resolve();\n const executablePath = await resolveExecutablePath(config.command);\n if (!executablePath) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"command_missing\",\n reasonMessage: `Configured stdio command \"${config.command}\" is not available. Update the runtime entry command or install the required launcher first.`,\n cta: {\n kind: \"settings\",\n label: \"Configure Stdio Runtime\",\n },\n };\n }\n if (describeMode === \"probe\") {\n try {\n await probeStdioRuntime(config);\n } catch (error) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"probe_failed\",\n reasonMessage:\n error instanceof Error\n ? error.message\n : \"Configured stdio runtime could not complete the ACP probe.\",\n cta: {\n kind: \"settings\",\n label: \"Repair Stdio Runtime\",\n },\n };\n }\n }\n return {\n icon: resolveEntryIcon(this.entry),\n ready: true,\n reason: null,\n reasonMessage: null,\n cta: null,\n };\n } catch (error) {\n return {\n icon: resolveEntryIcon(this.entry),\n ready: false,\n reason: \"command_missing\",\n reasonMessage:\n error instanceof Error\n ? error.message\n : \"Configure a stdio command before starting this runtime.\",\n cta: {\n kind: \"settings\",\n label: \"Configure Stdio Runtime\",\n },\n };\n }\n };\n}\n\nasync function resolveExecutablePath(command: string): Promise<string | null> {\n if (command.includes(\"/\") || command.includes(\"\\\\\")) {\n return (await isExecutable(command)) ? command : null;\n }\n const searchPath = process.env.PATH ?? \"\";\n for (const directory of searchPath.split(delimiter)) {\n const trimmed = directory.trim();\n if (!trimmed) {\n continue;\n }\n const candidate = `${trimmed}/${command}`;\n if (await isExecutable(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n\nasync function isExecutable(filePath: string): Promise<boolean> {\n try {\n await access(filePath, fsConstants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport class BuiltinNarpRuntimeProviderService {\n constructor(\n private readonly configManager: Pick<ConfigManager, \"loadConfig\">,\n ) {}\n\n createProviders = (): AgentRuntimeProviderRegistration[] => {\n return [\n {\n kind: NARP_HTTP_RUNTIME_KIND,\n label: \"NARP HTTP\",\n createRuntime: this.createUnavailableRuntime,\n createRuntimeForEntry: ({ entry, runtimeParams }) =>\n this.createHttpRuntime(entry, runtimeParams),\n describeSessionTypeForEntry: ({ entry, describeParams }) =>\n new BuiltinHttpRuntimeSessionTypeService(\n entry,\n this.configManager.loadConfig().agents.defaults.model,\n ).describe(describeParams),\n },\n {\n kind: NARP_STDIO_RUNTIME_KIND,\n label: \"NARP Stdio\",\n createRuntime: this.createUnavailableRuntime,\n createRuntimeForEntry: ({ entry, runtimeParams }) =>\n this.createStdioRuntime(entry, runtimeParams),\n describeSessionTypeForEntry: ({ entry, describeParams }) =>\n new BuiltinStdioRuntimeSessionTypeService(entry).describe(describeParams),\n },\n ];\n };\n\n private createUnavailableRuntime = (): never => {\n throw new Error(\"[narp] runtime entry is required before creating this runtime\");\n };\n\n private createHttpRuntime = (\n entry: AgentRuntimeEntry,\n runtimeParams: RuntimeFactoryParams,\n ): HttpRuntimeNcpAgentRuntime => {\n const config = readRecord(entry.config) ?? {};\n const resolver = new HttpRuntimeConfigResolver(config);\n const resolvedConfig = resolver.resolve({\n defaultModel: this.configManager.loadConfig().agents.defaults.model,\n });\n return new HttpRuntimeNcpAgentRuntime({\n baseUrl: resolver.requireBaseUrl(),\n ...(resolvedConfig.basePath ? { basePath: resolvedConfig.basePath } : {}),\n ...(resolvedConfig.endpointId ? { endpointId: resolvedConfig.endpointId } : {}),\n ...(resolvedConfig.headers ? { headers: resolvedConfig.headers } : {}),\n resolveTools: runtimeParams.resolveTools,\n stateManager: runtimeParams.stateManager,\n resolveProviderRoute: (input) =>\n buildProviderRoute({\n config: this.configManager.loadConfig(),\n input,\n sessionMetadata: runtimeParams.sessionMetadata,\n defaultModel: this.configManager.loadConfig().agents.defaults.model,\n configuredModel: readString(config.model),\n }),\n });\n };\n\n private createStdioRuntime = (\n entry: AgentRuntimeEntry,\n runtimeParams: RuntimeFactoryParams,\n ): StdioRuntimeNcpAgentRuntime => {\n const config = readRecord(entry.config) ?? {};\n const resolver = new StdioRuntimeConfigResolver(config);\n const resolvedConfig = resolver.resolve();\n return new StdioRuntimeNcpAgentRuntime({\n ...resolvedConfig,\n sessionId: runtimeParams.sessionId,\n resolveTools: runtimeParams.resolveTools,\n stateManager: runtimeParams.stateManager,\n resolveProviderRoute: (input: NcpAgentRunInput) =>\n buildProviderRoute({\n config: this.configManager.loadConfig(),\n input,\n sessionMetadata: runtimeParams.sessionMetadata,\n defaultModel: this.configManager.loadConfig().agents.defaults.model,\n configuredModel: readString(config.model),\n }),\n });\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelBranch } from \"@kernel/contributions/kernel-branch/index.js\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport {\n AgentRunMessageProjector,\n AgentRunModelInputBudgeter,\n AgentRunModelInputBuilder,\n NcpAgentRuntimeWrapper,\n} from \"@kernel/features/agent-run/index.js\";\nimport {\n BuiltinNarpRuntimeProviderService,\n NARP_STDIO_RUNTIME_KIND,\n} from \"@kernel/features/narp-runtime/index.js\";\nimport { ProviderManagerNcpLLMApi } from \"@kernel/features/native-runtime/index.js\";\nimport {\n resolveAgentRuntimeEntries,\n type AgentRuntimeProviderRegistration,\n} from \"@kernel/features/runtime-registry/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { DefaultNcpAgentRuntime } from \"@nextclaw/ncp-agent-runtime-next\";\n\nexport class AgentRunRuntimeContribution implements KernelContribution {\n private readonly cleanups: Array<() => Promise<void>> = [];\n private readonly modelInputBuilder: AgentRunModelInputBuilder;\n\n constructor(\n private readonly kernel: NextclawKernel,\n private readonly branch: KernelBranch,\n ) {\n this.modelInputBuilder = new AgentRunModelInputBuilder(\n new AgentRunMessageProjector(),\n new AgentRunModelInputBudgeter(kernel.configManager),\n kernel.assetStore,\n );\n }\n\n start = (): void => {\n if (this.cleanups.length > 0) {\n return;\n }\n const { entries } = resolveAgentRuntimeEntries({\n config: this.kernel.configManager.loadConfig(),\n });\n this.branch.agentRuntimeManager.applyEntries(entries);\n this.cleanups.push(this.registerNativeRuntime());\n for (const provider of new BuiltinNarpRuntimeProviderService(\n this.kernel.configManager,\n ).createProviders()) {\n this.cleanups.push(this.registerNarpRuntime(provider));\n }\n };\n\n dispose = async (): Promise<void> => {\n while (this.cleanups.length > 0) {\n await this.cleanups.pop()?.();\n }\n };\n\n private registerNativeRuntime = (): (() => Promise<void>) =>\n this.branch.agentRuntimeManager.register({\n kind: DEFAULT_AGENT_RUNTIME_ENTRY_ID,\n label: \"Native\",\n defaultReuseScope: \"global\",\n createRuntime: () =>\n new DefaultNcpAgentRuntime({\n llmApi: new ProviderManagerNcpLLMApi(this.kernel.llmProviders),\n modelInputBuilder: this.modelInputBuilder,\n runPreflight: async ({ spec, sessionRun }) => {\n const session = await this.branch.sessionRepository.getSession(sessionRun.sessionId);\n return await this.branch.contextCompactionManager.runPreflight({\n agentId: spec.agentId,\n messages: sessionRun.getSnapshot().messages,\n metadata: session.metadata,\n sessionId: sessionRun.sessionId,\n });\n },\n }),\n });\n\n private registerNarpRuntime = (\n provider: AgentRuntimeProviderRegistration,\n ): (() => Promise<void>) =>\n this.branch.agentRuntimeManager.register({\n kind: provider.kind,\n label: provider.label,\n defaultReuseScope: provider.kind === NARP_STDIO_RUNTIME_KIND ? \"session\" : \"session\",\n describeSessionTypeForEntry: provider.describeSessionTypeForEntry,\n createRuntime: ({ entry, session }) => {\n if (!provider.createRuntimeForEntry) {\n throw new Error(`Agent runtime provider does not support entries: ${provider.kind}`);\n }\n return new NcpAgentRuntimeWrapper({\n session,\n createRuntime: ({ resolveTools, stateManager }) =>\n provider.createRuntimeForEntry!({\n entry,\n runtimeParams: {\n sessionId: session.sessionId,\n ...(session.agentId ? { agentId: session.agentId } : {}),\n resolveAssetContentPath: (assetUri) =>\n this.kernel.assetStore.resolveContentPath(assetUri),\n resolveTools,\n sessionMetadata: session.metadata,\n stateManager,\n },\n }),\n });\n },\n });\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelBranch } from \"@kernel/contributions/kernel-branch/index.js\";\nimport {\n ContextCompactionPreflightService,\n createContextWindowSignature,\n isContextWindowSnapshot,\n readContextWindowEventSessionId,\n shouldRefreshContextWindowDuringStream,\n shouldRefreshContextWindowImmediately,\n} from \"@kernel/features/context-compaction/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport {\n type NcpEndpointEvent,\n NcpEventType,\n} from \"@nextclaw/ncp\";\nimport {\n eventKeys,\n type Unsubscribe,\n} from \"@nextclaw/shared\";\n\nconst STREAM_REFRESH_DELAY_MS = 1500;\n\nfunction formatBackgroundError(error: unknown): string {\n if (error instanceof Error) {\n return error.stack ?? error.message;\n }\n return String(error);\n}\n\nexport class ContextWindowContribution implements KernelContribution {\n private readonly contextWindowPreview: ContextCompactionPreflightService;\n private readonly lastPublishedSignatureBySession = new Map<string, string>();\n private readonly pendingTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private stopped = true;\n private unsubscribeNcpEvent: Unsubscribe | null = null;\n\n constructor(\n private readonly kernel: NextclawKernel,\n private readonly branch: KernelBranch,\n ) {\n this.contextWindowPreview = new ContextCompactionPreflightService({\n configManager: kernel.configManager,\n });\n }\n\n start = (): void => {\n if (this.unsubscribeNcpEvent) {\n return;\n }\n this.stopped = false;\n this.unsubscribeNcpEvent = this.kernel.eventBus.on(eventKeys.ncpEvent, this.handleNcpEvent);\n };\n\n dispose = (): void => {\n this.unsubscribeNcpEvent?.();\n this.unsubscribeNcpEvent = null;\n this.stopped = true;\n for (const timer of this.pendingTimers.values()) {\n clearTimeout(timer);\n }\n this.pendingTimers.clear();\n this.lastPublishedSignatureBySession.clear();\n };\n\n private handleNcpEvent = (event: NcpEndpointEvent): void => {\n const sessionId = readContextWindowEventSessionId(event);\n if (!sessionId || !this.branch.sessionRunManager.getSessionRun(sessionId)) {\n return;\n }\n if (event.type === NcpEventType.ContextWindowUpdated) {\n this.rememberPublishedContextWindow(sessionId, event.payload.contextWindow);\n return;\n }\n if (shouldRefreshContextWindowImmediately(event)) {\n this.refreshNow(sessionId);\n return;\n }\n if (shouldRefreshContextWindowDuringStream(event)) {\n this.refreshSoon(sessionId);\n }\n };\n\n private refreshSoon = (sessionId: string): void => {\n if (this.pendingTimers.has(sessionId)) {\n return;\n }\n const timer = setTimeout(() => {\n this.pendingTimers.delete(sessionId);\n this.refreshNow(sessionId);\n }, STREAM_REFRESH_DELAY_MS);\n this.pendingTimers.set(sessionId, timer);\n };\n\n private refreshNow = (sessionId: string): void => {\n const timer = this.pendingTimers.get(sessionId);\n if (timer) {\n clearTimeout(timer);\n this.pendingTimers.delete(sessionId);\n }\n void this.publishContextWindow(sessionId).catch((error: unknown) => {\n console.error(`[kernel-branch-context-window] failed to refresh ${sessionId}: ${formatBackgroundError(error)}`);\n });\n };\n\n private publishContextWindow = async (sessionId: string): Promise<void> => {\n if (this.stopped) {\n return;\n }\n const sessionRun = this.branch.sessionRunManager.getSessionRun(sessionId);\n if (!sessionRun) {\n return;\n }\n const session = await this.branch.sessionRepository.getSession(sessionId);\n const contextWindow = this.contextWindowPreview.preview({\n requestMetadata: session.metadata,\n sessionId,\n sessionMessages: sessionRun.getSnapshot().messages,\n storedAgentId: session.agentId,\n storedMetadata: session.metadata,\n });\n if (!isContextWindowSnapshot(contextWindow) || this.stopped) {\n return;\n }\n const signature = createContextWindowSignature(contextWindow);\n if (this.lastPublishedSignatureBySession.get(sessionId) === signature) {\n return;\n }\n this.lastPublishedSignatureBySession.set(sessionId, signature);\n this.kernel.eventBus.emit(eventKeys.ncpEvent, {\n type: NcpEventType.ContextWindowUpdated,\n payload: {\n contextWindow,\n sessionId,\n },\n }, {\n emittedAt: new Date().toISOString(),\n source: \"kernel-branch-context-window\",\n });\n };\n\n private rememberPublishedContextWindow = (\n sessionId: string,\n contextWindow: Record<string, unknown>,\n ): void => {\n this.lastPublishedSignatureBySession.set(sessionId, createContextWindowSignature(contextWindow));\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelBranch } from \"@kernel/contributions/kernel-branch/index.js\";\nimport {\n buildAgentRunRequestMetadata,\n type AgentRunRequest,\n type ContextBlock,\n type ContextProvider,\n} from \"@kernel/features/agent-run/index.js\";\nimport {\n buildSessionOrchestrationSection,\n resolveNextclawNcpRunContext,\n} from \"@kernel/features/native-runtime/index.js\";\nimport {\n buildMinimalSystemExecutionPrompt,\n buildToolCatalogEntries,\n ContextBuilder,\n readSessionProjectRoot,\n} from \"@nextclaw/core\";\n\nexport class KernelContextProvider implements ContextProvider {\n constructor(\n private readonly kernel: NextclawKernel,\n private readonly branch: KernelBranch,\n ) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly ContextBlock[]> => {\n const session = request.sessionId\n ? await this.branch.sessionRepository.getSession(request.sessionId)\n : null;\n const sessionId = session?.sessionId ?? request.sessionId ?? request.message.sessionId ?? \"\";\n const requestMetadata = buildAgentRunRequestMetadata({ request, session });\n const runContext = resolveNextclawNcpRunContext({\n configManager: this.kernel.configManager,\n sessionId,\n requestMetadata,\n sessionMetadata: session?.metadata ?? requestMetadata,\n storedAgentId: request.agentId ?? session?.agentId,\n });\n const toolRegistry = this.kernel.toolManager.createRuntimeRegistry({\n updateToolCallResult: async () => undefined,\n });\n toolRegistry.prepareForRun(runContext.toolRunContext);\n\n return [\n this.buildSystemContextBlock({\n availableTools: buildToolCatalogEntries(toolRegistry.getToolDefinitions()),\n runContext,\n }),\n ];\n };\n\n private buildSystemContextBlock = (params: {\n availableTools: ReturnType<typeof buildToolCatalogEntries>;\n runContext: ReturnType<typeof resolveNextclawNcpRunContext>;\n }): ContextBlock => {\n const { availableTools, runContext } = params;\n const contextBuilder = new ContextBuilder(\n runContext.effectiveWorkspace,\n runContext.config.agents.context,\n {\n hostWorkspace: runContext.profile.workspace,\n sessionProjectRoot: readSessionProjectRoot(runContext.sessionMetadata),\n },\n );\n const systemPrompt = contextBuilder.buildSystemPrompt(\n undefined,\n runContext.sessionKey,\n availableTools,\n [\n buildSessionOrchestrationSection(),\n buildMinimalSystemExecutionPrompt(runContext.effectiveModel),\n ],\n );\n\n const lines = [\n systemPrompt,\n \"## Current Session\",\n `Channel: ${runContext.channel}`,\n `Chat ID: ${runContext.chatId}`,\n `Session: ${runContext.sessionKey}`,\n ];\n if (runContext.runtimeThinking) {\n lines.push(`Thinking policy: ${runContext.runtimeThinking}`);\n }\n return lines.join(\"\\n\");\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelBranch } from \"@kernel/contributions/kernel-branch/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { KernelContextProvider } from \"./providers/kernel-context.provider.js\";\n\nexport class ContextProviderContribution implements KernelContribution {\n private unregister: (() => void) | null = null;\n\n constructor(\n private readonly kernel: NextclawKernel,\n private readonly branch: KernelBranch,\n ) {}\n\n start = (): void => {\n if (this.unregister) {\n return;\n }\n this.unregister = this.branch.contextProviderManager.register(\n new KernelContextProvider(this.kernel, this.branch),\n );\n };\n\n dispose = (): void => {\n this.unregister?.();\n this.unregister = null;\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelBranch } from \"@kernel/contributions/kernel-branch/index.js\";\nimport {\n buildAgentRunRequestMetadata,\n type AgentRunRequest,\n type ToolProvider,\n} from \"@kernel/features/agent-run/index.js\";\nimport { resolveNextclawNcpRunContext } from \"@kernel/features/native-runtime/index.js\";\nimport {\n eventKeys,\n} from \"@nextclaw/shared\";\nimport {\n NcpEventType,\n type NcpTool,\n} from \"@nextclaw/ncp\";\n\nexport class KernelToolProvider implements ToolProvider {\n constructor(\n private readonly kernel: NextclawKernel,\n private readonly branch: KernelBranch,\n ) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const session = request.sessionId\n ? await this.branch.sessionRepository.getSession(request.sessionId)\n : null;\n const sessionId = session?.sessionId ?? request.sessionId ?? request.message.sessionId ?? \"\";\n const requestMetadata = buildAgentRunRequestMetadata({ request, session });\n const runContext = resolveNextclawNcpRunContext({\n configManager: this.kernel.configManager,\n sessionId,\n requestMetadata,\n sessionMetadata: session?.metadata ?? requestMetadata,\n storedAgentId: request.agentId ?? session?.agentId,\n });\n const toolRegistry = this.kernel.toolManager.createRuntimeRegistry({\n updateToolCallResult: async ({ result, sessionId: targetSessionId, toolCallId }) => {\n this.kernel.eventBus.emit(eventKeys.ncpEvent, {\n type: NcpEventType.MessageToolCallResult,\n payload: {\n sessionId: targetSessionId,\n toolCallId,\n content: result,\n },\n }, {\n emittedAt: new Date().toISOString(),\n source: \"agent-run-tool-provider\",\n });\n },\n });\n toolRegistry.prepareForRun(runContext.toolRunContext);\n return toolRegistry.listTools();\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelBranch } from \"@kernel/contributions/kernel-branch/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { KernelToolProvider } from \"./providers/kernel-tool.provider.js\";\n\nexport class ToolProviderContribution implements KernelContribution {\n private unregister: (() => void) | null = null;\n\n constructor(\n private readonly kernel: NextclawKernel,\n private readonly branch: KernelBranch,\n ) {}\n\n start = (): void => {\n if (this.unregister) {\n return;\n }\n this.unregister = this.branch.toolProviderManager.register(\n new KernelToolProvider(this.kernel, this.branch),\n );\n };\n\n dispose = (): void => {\n this.unregister?.();\n this.unregister = null;\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { AgentRunRuntimeContribution } from \"@kernel/contributions/kernel-branch/contributions/agent-run-runtime/index.js\";\nimport { ContextWindowContribution } from \"@kernel/contributions/kernel-branch/contributions/context-window/index.js\";\nimport { ContextProviderContribution } from \"@kernel/contributions/kernel-branch/contributions/context-provider/index.js\";\nimport { ToolProviderContribution } from \"@kernel/contributions/kernel-branch/contributions/tool-provider/index.js\";\nimport {\n AgentRunContextCompactionManager,\n AgentRunRequestManager,\n AgentRuntimeManager,\n ContextProviderManager,\n SessionRepository,\n SessionRunManager,\n ToolProviderManager,\n} from \"@kernel/features/agent-run/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport type { AgentRuntimeSessionTypeDescribeParams } from \"@kernel/features/runtime-registry/index.js\";\n\nexport class KernelBranch implements KernelContribution {\n readonly agentRuntimeManager = new AgentRuntimeManager();\n readonly contextCompactionManager: AgentRunContextCompactionManager;\n readonly contextProviderManager = new ContextProviderManager();\n readonly sessionRepository: SessionRepository;\n readonly sessionRunManager: SessionRunManager;\n readonly toolProviderManager = new ToolProviderManager();\n readonly agentRunRequestManager: AgentRunRequestManager;\n private readonly contributions: KernelContribution[];\n private started = false;\n\n constructor(private readonly kernel: NextclawKernel) {\n this.sessionRepository = new SessionRepository(\n kernel.eventBus,\n kernel.ncpSessionManager,\n );\n this.contextCompactionManager = new AgentRunContextCompactionManager(\n kernel.configManager,\n kernel.llmProviders,\n this.sessionRepository,\n );\n this.sessionRunManager = new SessionRunManager(this.sessionRepository);\n this.agentRunRequestManager = new AgentRunRequestManager(\n this.agentRuntimeManager,\n kernel.configManager,\n this.contextProviderManager,\n kernel.eventBus,\n kernel.ingress,\n this.sessionRepository,\n this.sessionRunManager,\n this.toolProviderManager,\n );\n this.contributions = [\n new ToolProviderContribution(kernel, this),\n new ContextProviderContribution(kernel, this),\n new ContextWindowContribution(kernel, this),\n new AgentRunRuntimeContribution(kernel, this),\n ];\n }\n\n start = (): void => {\n if (this.started) {\n return;\n }\n this.started = true;\n this.sessionRepository.start();\n for (const contribution of this.contributions) {\n contribution.start();\n }\n this.agentRunRequestManager.start();\n };\n\n listSessionTypes = (params?: AgentRuntimeSessionTypeDescribeParams) =>\n this.agentRuntimeManager.listSessionTypes(params);\n\n dispose = async (): Promise<void> => {\n if (!this.started) {\n return;\n }\n for (const contribution of [...this.contributions].reverse()) {\n await contribution.dispose?.();\n }\n this.agentRunRequestManager.dispose();\n this.toolProviderManager.dispose();\n this.contextProviderManager.dispose();\n await this.agentRuntimeManager.dispose();\n this.sessionRunManager.dispose();\n this.sessionRepository.dispose();\n this.started = false;\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { BuiltinNarpRuntimeProviderService } from \"@kernel/features/narp-runtime/index.js\";\nimport { NativeAgentRuntimeFactory } from \"@kernel/features/native-runtime/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\n\nexport class AgentRuntimeContribution implements KernelContribution {\n private cleanups: Array<() => void> = [];\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.cleanups.length > 0) {\n return;\n }\n const nativeRuntimeFactory = new NativeAgentRuntimeFactory({\n providerManager: this.kernel.llmProviders,\n configManager: this.kernel.configManager,\n llmUsage: this.kernel.llmUsage,\n assetStore: this.kernel.assetStore,\n updateToolCallResult: this.kernel.sessionRunManager.updateToolCallResult,\n toolManager: this.kernel.toolManager,\n });\n const builtinNarpRuntimeProviders = new BuiltinNarpRuntimeProviderService(\n this.kernel.configManager,\n ).createProviders();\n const nativeRegistration = this.kernel.agentRuntimeManager.registerRuntimeProvider({\n kind: \"native\",\n label: \"Native\",\n createRuntime: nativeRuntimeFactory.create,\n });\n this.cleanups = [\n () => nativeRegistration.dispose(),\n ...builtinNarpRuntimeProviders.map((provider) => {\n const registration = this.kernel.agentRuntimeManager.registerRuntimeProvider(provider);\n return () => registration.dispose();\n }),\n ];\n };\n\n dispose = (): void => {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n this.cleanups = [];\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport {\n createContextWindowSignature,\n isContextWindowSnapshot,\n readContextWindowEventSessionId,\n shouldRefreshContextWindowDuringStream,\n shouldRefreshContextWindowImmediately,\n} from \"@kernel/features/context-compaction/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { type NcpEndpointEvent, NcpEventType } from \"@nextclaw/ncp\";\nimport { eventKeys, type Unsubscribe } from \"@nextclaw/shared\";\n\nconst STREAM_REFRESH_DELAY_MS = 1500;\n\nfunction formatBackgroundError(error: unknown): string {\n if (error instanceof Error) {\n return error.stack ?? error.message;\n }\n return String(error);\n}\n\nexport class SessionContextWindowContribution implements KernelContribution {\n private unsubscribeNcpEvent: Unsubscribe | null = null;\n private stopped = true;\n private readonly pendingTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly lastPublishedSignatureBySession = new Map<string, string>();\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.unsubscribeNcpEvent) {\n return;\n }\n this.stopped = false;\n this.unsubscribeNcpEvent = this.kernel.eventBus.on(eventKeys.ncpEvent, this.handleNcpEvent);\n };\n\n dispose = (): void => {\n this.unsubscribeNcpEvent?.();\n this.unsubscribeNcpEvent = null;\n this.stopped = true;\n for (const timer of this.pendingTimers.values()) {\n clearTimeout(timer);\n }\n this.pendingTimers.clear();\n this.lastPublishedSignatureBySession.clear();\n };\n\n private handleNcpEvent = (event: NcpEndpointEvent): void => {\n const sessionId = readContextWindowEventSessionId(event);\n if (!sessionId) {\n return;\n }\n if (event.type === NcpEventType.ContextWindowUpdated) {\n this.rememberPublishedContextWindow(sessionId, event.payload.contextWindow);\n return;\n }\n if (shouldRefreshContextWindowImmediately(event)) {\n this.refreshNow(sessionId);\n return;\n }\n if (shouldRefreshContextWindowDuringStream(event)) {\n this.refreshSoon(sessionId);\n }\n };\n\n private refreshSoon = (sessionId: string): void => {\n if (this.pendingTimers.has(sessionId)) {\n return;\n }\n const timer = setTimeout(() => {\n this.pendingTimers.delete(sessionId);\n this.refreshNow(sessionId);\n }, STREAM_REFRESH_DELAY_MS);\n this.pendingTimers.set(sessionId, timer);\n };\n\n private refreshNow = (sessionId: string): void => {\n const timer = this.pendingTimers.get(sessionId);\n if (timer) {\n clearTimeout(timer);\n this.pendingTimers.delete(sessionId);\n }\n void this.publishContextWindow(sessionId).catch((error: unknown) => {\n console.error(`[session-context-window] failed to refresh ${sessionId}: ${formatBackgroundError(error)}`);\n });\n };\n\n private publishContextWindow = async (sessionId: string): Promise<void> => {\n if (this.stopped) {\n return;\n }\n const contextWindow = await this.kernel.ncpSessionManager.getContextWindow(\n sessionId,\n this.kernel.sessionRunManager.getLiveSessionRecord(sessionId),\n );\n if (!isContextWindowSnapshot(contextWindow) || this.stopped) {\n return;\n }\n const signature = createContextWindowSignature(contextWindow);\n if (this.lastPublishedSignatureBySession.get(sessionId) === signature) {\n return;\n }\n this.lastPublishedSignatureBySession.set(sessionId, signature);\n this.kernel.eventBus.emit(eventKeys.ncpEvent, {\n type: NcpEventType.ContextWindowUpdated,\n payload: {\n sessionId,\n contextWindow,\n },\n }, {\n emittedAt: new Date().toISOString(),\n source: \"session-context-window\",\n });\n };\n\n private rememberPublishedContextWindow = (\n sessionId: string,\n contextWindow: Record<string, unknown>,\n ): void => {\n this.lastPublishedSignatureBySession.set(sessionId, createContextWindowSignature(contextWindow));\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { AgentRuntimeContribution } from \"@kernel/contributions/agent-runtime/index.js\";\nimport { SessionContextWindowContribution } from \"@kernel/contributions/session-context-window/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport type { AgentRuntimeSessionTypeDescribeParams } from \"@kernel/features/runtime-registry/index.js\";\n\nexport class LegacyAgentRunContribution implements KernelContribution {\n private readonly contributions: KernelContribution[];\n private started = false;\n\n constructor(private readonly kernel: NextclawKernel) {\n this.contributions = [\n new AgentRuntimeContribution(kernel),\n new SessionContextWindowContribution(kernel),\n ];\n }\n\n start = (): void => {\n if (this.started) {\n return;\n }\n this.started = true;\n for (const contribution of this.contributions) {\n contribution.start();\n }\n this.kernel.agentRunRequestManager.start();\n };\n\n listSessionTypes = (params?: AgentRuntimeSessionTypeDescribeParams) =>\n this.kernel.agentRuntimeManager.listSessionTypes(params);\n\n dispose = async (): Promise<void> => {\n if (!this.started) {\n return;\n }\n await this.kernel.agentRunRequestManager.dispose();\n await this.kernel.sessionRunManager.dispose();\n for (const contribution of [...this.contributions].reverse()) {\n await contribution.dispose();\n }\n this.started = false;\n };\n}\n","import type { Config } from \"@nextclaw/core\";\n\nexport const LEARNING_LOOP_DISABLED_METADATA_KEY = \"learning_loop_disabled\";\nexport const LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY =\n \"learning_loop_last_tool_call_count\";\nexport const LEARNING_LOOP_LAST_REQUESTED_AT_METADATA_KEY =\n \"learning_loop_last_requested_at\";\nexport const LEARNING_LOOP_LAST_REVIEW_SESSION_ID_METADATA_KEY =\n \"learning_loop_last_review_session_id\";\nexport const LEARNING_LOOP_SOURCE_SESSION_ID_METADATA_KEY =\n \"learning_loop_source_session_id\";\nexport const LEARNING_LOOP_REQUESTED_SKILLS = [\"skill-creator\"];\nexport const DEFAULT_LEARNING_LOOP_TOOL_CALL_THRESHOLD = 15;\n\nexport type LearningLoopRuntimeConfig = {\n enabled: boolean;\n toolCallThreshold: number;\n};\n\nexport function readLearningLoopRuntimeConfig(\n config: Config,\n): LearningLoopRuntimeConfig {\n return {\n enabled: config.agents.learningLoop.enabled,\n toolCallThreshold:\n config.agents.learningLoop.toolCallThreshold ??\n DEFAULT_LEARNING_LOOP_TOOL_CALL_THRESHOLD,\n };\n}\n","function pluralizeToolCalls(value: number): string {\n return value === 1 ? \"1 tool call\" : `${value} tool calls`;\n}\n\nexport function buildLearningLoopTask(params: {\n sessionId: string;\n toolCallsSinceReview: number;\n currentToolCallCount: number;\n}): string {\n return [\n \"Run a background learning-loop review for the parent session.\",\n `Parent session id: ${params.sessionId}.`,\n `There have been ${pluralizeToolCalls(params.toolCallsSinceReview)} since the last learning-loop review (${params.currentToolCallCount} total so far).`,\n \"\",\n \"Your job is to extract only the reusable lesson.\",\n \"- Review the parent session history and, if helpful, use session_search to compare similar historical sessions.\",\n \"- Decide exactly one outcome: no_skill_change, patch_existing_skill, or create_new_skill.\",\n \"- Prefer patching an existing skill when the lesson extends an existing workflow.\",\n \"- Only create a new skill when the lesson is clearly reusable, repeatable, and likely to recur.\",\n \"- Do not create or patch a skill for one-off quirks, noisy transcripts, or narrow local accidents.\",\n \"\",\n \"If you decide to patch or create a skill:\",\n \"- Use the available file tools.\",\n \"- Keep the change minimal and maintainable.\",\n \"- Write the skill into the current workspace/project skills directory under skills/<slug>/SKILL.md.\",\n \"- Follow the built-in skill-creator guidance when it helps.\",\n \"\",\n \"If nothing reusable should be saved, stop without writing files.\",\n ].join(\"\\n\");\n}\n","import {\n readParentSessionId,\n type SessionRequestToolResult,\n type SpawnSessionAndRequestParams,\n} from \"@nextclaw/core\";\nimport { NcpEventType, type NcpEndpointEvent, type NcpMessage } from \"@nextclaw/ncp\";\nimport { eventKeys, type Unsubscribe } from \"@nextclaw/shared\";\nimport type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport {\n LEARNING_LOOP_DISABLED_METADATA_KEY,\n LEARNING_LOOP_LAST_REQUESTED_AT_METADATA_KEY,\n LEARNING_LOOP_LAST_REVIEW_SESSION_ID_METADATA_KEY,\n LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY,\n LEARNING_LOOP_REQUESTED_SKILLS,\n LEARNING_LOOP_SOURCE_SESSION_ID_METADATA_KEY,\n readLearningLoopRuntimeConfig,\n type LearningLoopRuntimeConfig,\n} from \"./config.js\";\nimport { buildLearningLoopTask } from \"./utils/learning-loop-prompt.utils.js\";\n\nexport type LearningLoopSessionRequester = {\n spawnSessionAndRequest: (\n params: SpawnSessionAndRequestParams,\n ) => Promise<SessionRequestToolResult>;\n};\n\ntype LearningLoopSessionStore = Pick<\n NcpSessionManager,\n \"getSessionRecord\" | \"updateSessionMetadata\"\n>;\n\nfunction countToolCallsFromMessage(message: NcpMessage): number {\n if (!Array.isArray(message.parts)) {\n return 0;\n }\n const seenIds = new Set<string>();\n let anonymousCount = 0;\n for (const part of message.parts) {\n if (!part || typeof part !== \"object\" || Array.isArray(part)) {\n continue;\n }\n const candidate = part as {\n type?: unknown;\n toolCallId?: unknown;\n };\n if (candidate.type !== \"tool-invocation\") {\n continue;\n }\n if (typeof candidate.toolCallId === \"string\" && candidate.toolCallId.trim()) {\n seenIds.add(candidate.toolCallId.trim());\n continue;\n }\n anonymousCount += 1;\n }\n return seenIds.size + anonymousCount;\n}\n\nfunction countSessionToolCalls(messages: readonly NcpMessage[]): number {\n return messages.reduce((count, message) => count + countToolCallsFromMessage(message), 0);\n}\n\nfunction readSessionLabel(metadata: Record<string, unknown>): string | undefined {\n const label = metadata.label;\n return typeof label === \"string\" && label.trim().length > 0 ? label.trim() : undefined;\n}\n\nfunction isLearningLoopDisabled(metadata: Record<string, unknown>): boolean {\n return metadata[LEARNING_LOOP_DISABLED_METADATA_KEY] === true;\n}\n\nfunction readLearningLoopLastToolCallCount(\n metadata: Record<string, unknown>,\n): number {\n const value = metadata[LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY];\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n}\n\nfunction readRunFinishedSessionId(event: NcpEndpointEvent): string | null {\n if (event.type !== NcpEventType.RunFinished) {\n return null;\n }\n return event.payload.sessionId?.trim() || null;\n}\n\nexport class LearningLoopContribution implements KernelContribution {\n private readonly sessionStore: LearningLoopSessionStore;\n private readonly sessionRequester: LearningLoopSessionRequester;\n private readonly inFlightSessionIds = new Set<string>();\n private unsubscribe: Unsubscribe | null = null;\n\n constructor(private readonly kernel: NextclawKernel) {\n this.sessionStore = kernel.ncpSessionManager;\n this.sessionRequester = kernel.sessionRequests;\n }\n\n start = (): void => {\n if (this.unsubscribe) {\n return;\n }\n this.unsubscribe = this.kernel.eventBus.on(eventKeys.ncpEvent, this.handleNcpEvent);\n };\n\n dispose = (): void => {\n this.unsubscribe?.();\n this.unsubscribe = null;\n this.inFlightSessionIds.clear();\n };\n\n private handleNcpEvent = (event: NcpEndpointEvent): void => {\n const sessionId = readRunFinishedSessionId(event);\n if (!sessionId) {\n return;\n }\n void this.handleRunFinishedInBackground(sessionId).catch((error) => {\n console.warn(\n `[learning-loop] Failed for ${sessionId}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n });\n };\n\n private handleRunFinishedInBackground = async (\n sessionId: string,\n ): Promise<void> => {\n if (this.inFlightSessionIds.has(sessionId)) {\n return;\n }\n const session = await this.sessionStore.getSessionRecord(sessionId);\n const metadata = session?.metadata ?? {};\n if (!session || readParentSessionId(metadata)) {\n return;\n }\n const runtimeConfig = this.readRuntimeConfig();\n if (!runtimeConfig.enabled || isLearningLoopDisabled(metadata)) {\n return;\n }\n const totalToolCalls = countSessionToolCalls(session.messages);\n const lastReviewedToolCallCount = readLearningLoopLastToolCallCount(\n metadata,\n );\n const toolCallsSinceReview = totalToolCalls - lastReviewedToolCallCount;\n if (toolCallsSinceReview < runtimeConfig.toolCallThreshold) {\n return;\n }\n\n this.inFlightSessionIds.add(sessionId);\n try {\n const reviewSession = await this.sessionRequester.spawnSessionAndRequest({\n sourceSessionId: sessionId,\n updateToolCallResult: async () => undefined,\n sourceSessionMetadata: metadata,\n metadataOverrides: {\n requested_skills: LEARNING_LOOP_REQUESTED_SKILLS,\n [LEARNING_LOOP_DISABLED_METADATA_KEY]: true,\n [LEARNING_LOOP_SOURCE_SESSION_ID_METADATA_KEY]: sessionId,\n },\n parentSessionId: sessionId,\n notify: \"none\",\n title: this.buildReviewTitle(metadata),\n task: buildLearningLoopTask({\n sessionId,\n toolCallsSinceReview,\n currentToolCallCount: totalToolCalls,\n }),\n });\n await this.sessionStore.updateSessionMetadata(sessionId, {\n [LEARNING_LOOP_LAST_TOOL_CALL_COUNT_METADATA_KEY]: totalToolCalls,\n [LEARNING_LOOP_LAST_REQUESTED_AT_METADATA_KEY]: new Date().toISOString(),\n [LEARNING_LOOP_LAST_REVIEW_SESSION_ID_METADATA_KEY]:\n reviewSession.sessionId,\n });\n } finally {\n this.inFlightSessionIds.delete(sessionId);\n }\n };\n\n private readRuntimeConfig = (): LearningLoopRuntimeConfig => {\n return readLearningLoopRuntimeConfig(this.kernel.configManager.loadConfig());\n };\n\n private buildReviewTitle = (metadata: Record<string, unknown>): string => {\n const label = readSessionLabel(metadata);\n return label ? `Learning loop: ${label}` : \"Learning loop\";\n };\n}\n","import { NcpEventType, type NcpEndpointEvent, type NcpMessage } from \"@nextclaw/ncp\";\nimport type {\n SessionActivityPreviewMetadata,\n SessionActivityPreviewProjection,\n} from \"@kernel/contributions/session-activity-preview/types/session-activity-preview.types.js\";\n\nconst PREVIEW_TEXT_MAX_LENGTH = 160;\n\nfunction readSessionId(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction compactPreviewText(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nfunction truncatePreviewText(value: string): string {\n const compacted = compactPreviewText(value);\n if (compacted.length <= PREVIEW_TEXT_MAX_LENGTH) {\n return compacted;\n }\n return compacted.slice(0, PREVIEW_TEXT_MAX_LENGTH - 1).trimEnd();\n}\n\nfunction readMessagePreviewText(message: NcpMessage): string | null {\n const chunks: string[] = [];\n for (const part of message.parts) {\n if ((part.type === \"text\" || part.type === \"rich-text\") && part.text.trim()) {\n chunks.push(part.text);\n }\n }\n const previewText = truncatePreviewText(chunks.join(\" \"));\n return previewText.length > 0 ? previewText : null;\n}\n\nfunction createProjection(\n sessionId: string | null,\n preview: SessionActivityPreviewMetadata,\n): SessionActivityPreviewProjection | null {\n if (!sessionId) {\n return null;\n }\n return { sessionId, preview };\n}\n\nfunction formatErrorStatus(error: unknown): string {\n if (typeof error === \"string\" && error.trim()) {\n return `运行出错:${truncatePreviewText(error)}`;\n }\n if (error && typeof error === \"object\" && \"message\" in error) {\n const message = (error as { message?: unknown }).message;\n if (typeof message === \"string\" && message.trim()) {\n return `运行出错:${truncatePreviewText(message)}`;\n }\n }\n return \"运行出错\";\n}\n\nexport function createSessionActivityPreviewFromNcpEvent(\n event: NcpEndpointEvent,\n timestamp: string,\n): SessionActivityPreviewProjection | null {\n switch (event.type) {\n case NcpEventType.RunStarted:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: \"正在处理...\",\n timestamp,\n });\n case NcpEventType.RunFinished:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"completed\",\n timestamp,\n });\n case NcpEventType.RunError:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"failed\",\n statusText: formatErrorStatus(event.payload.error),\n timestamp,\n });\n case NcpEventType.MessageSent: {\n const text = readMessagePreviewText(event.payload.message);\n if (!text || event.payload.message.role !== \"user\") {\n return null;\n }\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: text,\n timestamp: event.payload.message.timestamp || timestamp,\n });\n }\n case NcpEventType.MessageCompleted: {\n const text = readMessagePreviewText(event.payload.message);\n if (!text || event.payload.message.role !== \"assistant\") {\n return null;\n }\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"completed\",\n replyText: text,\n timestamp: event.payload.message.timestamp || timestamp,\n });\n }\n case NcpEventType.MessageFailed:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"failed\",\n statusText: formatErrorStatus(event.payload.error),\n timestamp,\n });\n case NcpEventType.MessageToolCallStart:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: `正在调用工具:${event.payload.toolName}`,\n timestamp,\n });\n case NcpEventType.MessageToolCallEnd:\n case NcpEventType.MessageToolCallResult:\n return createProjection(readSessionId(event.payload.sessionId), {\n state: \"running\",\n statusText: \"工具调用完成\",\n timestamp,\n });\n default:\n return null;\n }\n}\n","import type {\n SessionActivityPreviewMetadata,\n SessionActivityPreviewProjection,\n SessionActivityPreviewState,\n} from \"@kernel/contributions/session-activity-preview/types/session-activity-preview.types.js\";\n\nexport const SESSION_ACTIVITY_PREVIEW_METADATA_KEY = \"last_activity_preview\";\n\nconst SESSION_ACTIVITY_PREVIEW_STATES = new Set<SessionActivityPreviewState>([\n \"running\",\n \"completed\",\n \"failed\",\n \"idle\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction readOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction readSessionActivityPreviewMetadata(value: unknown): SessionActivityPreviewMetadata | null {\n if (!isRecord(value)) {\n return null;\n }\n const state = value.state;\n const timestamp = readOptionalString(value.timestamp);\n if (!SESSION_ACTIVITY_PREVIEW_STATES.has(state as SessionActivityPreviewState) || !timestamp) {\n return null;\n }\n return {\n state: state as SessionActivityPreviewState,\n timestamp,\n ...(readOptionalString(value.statusText) ? { statusText: readOptionalString(value.statusText) } : {}),\n ...(readOptionalString(value.replyText) ? { replyText: readOptionalString(value.replyText) } : {}),\n };\n}\n\nfunction compareIsoTimestamp(left: string, right: string): number {\n const leftTime = Date.parse(left);\n const rightTime = Date.parse(right);\n if (!Number.isFinite(leftTime) || !Number.isFinite(rightTime)) {\n return left.localeCompare(right);\n }\n return leftTime - rightTime;\n}\n\nfunction mergeSessionActivityPreview(\n current: SessionActivityPreviewMetadata | null,\n incoming: SessionActivityPreviewMetadata,\n): SessionActivityPreviewMetadata {\n if (current && compareIsoTimestamp(incoming.timestamp, current.timestamp) < 0) {\n return incoming.replyText && !current.replyText ? { ...current, replyText: incoming.replyText } : current;\n }\n return {\n state: incoming.state,\n timestamp: incoming.timestamp,\n ...(incoming.statusText ?? (incoming.state === \"completed\" ? current?.statusText : undefined)\n ? { statusText: incoming.statusText ?? current?.statusText }\n : {}),\n ...(incoming.replyText ?? current?.replyText ? { replyText: incoming.replyText ?? current?.replyText } : {}),\n };\n}\n\nfunction areSessionActivityPreviewsEqual(\n left: SessionActivityPreviewMetadata | null,\n right: SessionActivityPreviewMetadata,\n): boolean {\n return Boolean(left) &&\n left?.state === right.state &&\n left.timestamp === right.timestamp &&\n left.statusText === right.statusText &&\n left.replyText === right.replyText;\n}\n\nexport function writeSessionActivityPreviewMetadata(\n metadata: Record<string, unknown> | undefined,\n projection: SessionActivityPreviewProjection,\n): Record<string, unknown> | null {\n const current = readSessionActivityPreviewMetadata(metadata?.[SESSION_ACTIVITY_PREVIEW_METADATA_KEY]);\n const next = mergeSessionActivityPreview(current, projection.preview);\n if (areSessionActivityPreviewsEqual(current, next)) {\n return null;\n }\n return {\n ...(metadata ?? {}),\n [SESSION_ACTIVITY_PREVIEW_METADATA_KEY]: next,\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { eventKeys, type Unsubscribe } from \"@nextclaw/shared\";\nimport type { SessionActivityPreviewProjection } from \"./types/session-activity-preview.types.js\";\nimport { createSessionActivityPreviewFromNcpEvent } from \"./utils/session-activity-preview-ncp-event.utils.js\";\nimport { writeSessionActivityPreviewMetadata } from \"./utils/session-activity-preview-metadata.utils.js\";\n\nexport class SessionActivityPreviewContribution implements KernelContribution {\n private unsubscribeNcpEvent: Unsubscribe | null = null;\n private readonly metadataWriteChains = new Map<string, Promise<void>>();\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.unsubscribeNcpEvent) {\n return;\n }\n this.unsubscribeNcpEvent = this.kernel.eventBus.on(eventKeys.ncpEvent, (event) => {\n const projection = createSessionActivityPreviewFromNcpEvent(event, new Date().toISOString());\n if (!projection) {\n return;\n }\n this.updatePreview(projection);\n });\n };\n\n dispose = (): void => {\n this.unsubscribeNcpEvent?.();\n this.unsubscribeNcpEvent = null;\n this.metadataWriteChains.clear();\n };\n\n private updatePreview = (projection: SessionActivityPreviewProjection): void => {\n const previous = this.metadataWriteChains.get(projection.sessionId) ?? Promise.resolve();\n const next = previous.then(() => this.updatePreviewMetadata(projection));\n this.metadataWriteChains.set(projection.sessionId, next.catch(() => undefined));\n void next\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(\n `[session-activity-preview] failed to update ${projection.sessionId}: ${message}`,\n );\n });\n };\n\n private updatePreviewMetadata = async (projection: SessionActivityPreviewProjection): Promise<void> => {\n const session = await this.kernel.ncpSessionManager.getSessionRecord(projection.sessionId);\n const nextMetadata = writeSessionActivityPreviewMetadata(session?.metadata, projection);\n if (!nextMetadata) {\n return;\n }\n await this.kernel.ncpSessionManager.updateSessionMetadata(projection.sessionId, nextMetadata);\n };\n}\n","import { Tool, type ToolExecutionContext } from \"@nextclaw/core\";\nimport type { SessionRequestManager } from \"@kernel/features/session-request/index.js\";\n\nfunction readRequiredString(params: Record<string, unknown>, key: string): string {\n const value = params[key];\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(`${key} must be a non-empty string.`);\n }\n return value.trim();\n}\n\nfunction readOptionalString(params: Record<string, unknown>, key: string): string | undefined {\n const value = params[key];\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nexport class SessionRequestTool extends Tool {\n private sourceSessionId = \"\";\n private handoffDepth = 0;\n\n constructor(private readonly manager: SessionRequestManager) {\n super();\n }\n\n get name(): string {\n return \"sessions_request\";\n }\n\n get description(): string {\n return \"Send one task to another session. Use notify to control whether this session should continue after the target session finishes.\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n target: {\n type: \"object\",\n description: \"Target session reference. Pass an object like {\\\"session_id\\\":\\\"...\\\"}, not a bare string.\",\n properties: {\n session_id: {\n type: \"string\",\n description: \"Existing target session id.\",\n },\n },\n required: [\"session_id\"],\n },\n task: {\n type: \"string\",\n description: \"Task to send to the target session.\",\n },\n notify: {\n type: \"string\",\n enum: [\"none\", \"final_reply\"],\n description: \"Whether the current session should continue after the target session finishes. Use \\\"final_reply\\\" to continue after the target session reaches its final reply.\",\n },\n title: {\n type: \"string\",\n description: \"Optional card title override.\",\n },\n },\n required: [\"target\", \"task\", \"notify\"],\n };\n }\n\n setContext = (params: {\n sourceSessionId: string;\n handoffDepth?: number;\n }): void => {\n this.sourceSessionId = params.sourceSessionId;\n this.handoffDepth = params.handoffDepth ?? 0;\n };\n\n execute = async (\n params: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<unknown> => {\n const target = params.target;\n if (!target || typeof target !== \"object\" || Array.isArray(target)) {\n throw new Error(\"target must be an object.\");\n }\n const task = readRequiredString(params, \"task\");\n const notifyMode = readOptionalString(params, \"notify\")?.toLowerCase();\n if (notifyMode !== \"none\" && notifyMode !== \"final_reply\") {\n throw new Error('notify must be \"none\" or \"final_reply\".');\n }\n const { toolCallId, updateToolCallResult } = context;\n\n return this.manager.requestSession({\n sourceSessionId: this.sourceSessionId,\n ...(toolCallId ? { sourceToolCallId: toolCallId } : {}),\n updateToolCallResult,\n targetSessionId: readRequiredString(target as Record<string, unknown>, \"session_id\"),\n task,\n title: readOptionalString(params, \"title\"),\n notify: notifyMode,\n handoffDepth: this.handoffDepth,\n });\n };\n}\n","import { Tool } from \"@nextclaw/core\";\nimport type { NcpMessage, NcpSessionSummary } from \"@nextclaw/ncp\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\n\nconst DEFAULT_LIMIT = 20;\nconst MAX_MESSAGE_LIMIT = 20;\nconst HISTORY_MAX_BYTES = 80 * 1024;\nconst HISTORY_TEXT_MAX_CHARS = 4000;\n\nfunction toInt(value: unknown, fallback: number): number {\n const parsed = typeof value === \"number\" || typeof value === \"string\" ? Number(value) : NaN;\n return Number.isFinite(parsed) ? Math.max(0, Math.trunc(parsed)) : fallback;\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction messageText(message: NcpMessage): string {\n const text = message.parts\n .map((part) => (part.type === \"text\" || part.type === \"rich-text\" || part.type === \"reasoning\" ? part.text : \"\"))\n .filter(Boolean)\n .join(\"\\n\");\n if (text) return text;\n return JSON.stringify(message.parts, null, 2);\n}\n\nfunction sanitizeMessage(message: NcpMessage) {\n const content = messageText(message);\n const truncated = content.length > HISTORY_TEXT_MAX_CHARS;\n return {\n role: message.role,\n content: truncated ? `${content.slice(0, HISTORY_TEXT_MAX_CHARS)}\\n...(truncated)...` : content,\n timestamp: message.timestamp,\n ...(truncated ? { truncated: true } : {}),\n };\n}\n\nfunction capHistory(items: unknown[]): unknown[] {\n const text = JSON.stringify(items);\n if (Buffer.byteLength(text, \"utf8\") <= HISTORY_MAX_BYTES) return items;\n const last = items.at(-1);\n return last && Buffer.byteLength(JSON.stringify([last]), \"utf8\") <= HISTORY_MAX_BYTES\n ? [last]\n : [{ role: \"assistant\", content: \"[sessions_history omitted: message too large]\" }];\n}\n\nfunction sessionLabel(summary: NcpSessionSummary): string | undefined {\n return readString(summary.metadata?.label) ?? readString(summary.metadata?.session_label);\n}\n\nexport class SessionsListTool extends Tool {\n constructor(private readonly sessions: NcpSessionManager) {\n super();\n }\n\n get name(): string {\n return \"sessions_list\";\n }\n\n get description(): string {\n return \"List available sessions with timestamps.\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n sessionKey: { type: \"string\", description: \"Only include the exact session key\" },\n limit: { type: \"integer\", minimum: 1, description: \"Maximum number of sessions to return\" },\n messageLimit: { type: \"integer\", minimum: 0, description: \"Include last N messages (max 20)\" },\n },\n };\n }\n\n execute = async (params: Record<string, unknown>): Promise<string> => {\n const { limit, messageLimit, sessionKey } = params;\n const exactSessionKey = readString(sessionKey);\n const summaries = exactSessionKey\n ? [await this.sessions.getSession(exactSessionKey)].filter((summary): summary is NcpSessionSummary => Boolean(summary))\n : await this.sessions.listSessions();\n const maxSessions = toInt(limit, DEFAULT_LIMIT);\n const maxMessages = Math.min(toInt(messageLimit, 0), MAX_MESSAGE_LIMIT);\n const result: Record<string, unknown>[] = [];\n\n for (const summary of summaries) {\n const entry: Record<string, unknown> = {\n key: summary.sessionId,\n sessionId: summary.sessionId,\n agentId: summary.agentId,\n label: sessionLabel(summary),\n createdAt: summary.createdAt,\n updatedAt: summary.updatedAt,\n status: summary.status,\n };\n if (maxMessages > 0) {\n entry.messages = (await this.sessions.listSessionMessages(summary.sessionId))\n .filter((message) => message.role !== \"tool\")\n .slice(-maxMessages)\n .map(sanitizeMessage);\n }\n result.push(entry);\n if (result.length >= maxSessions) break;\n }\n return JSON.stringify({ sessions: result }, null, 2);\n };\n}\n\nexport class SessionsHistoryTool extends Tool {\n constructor(private readonly sessions: NcpSessionManager) {\n super();\n }\n\n get name(): string {\n return \"sessions_history\";\n }\n\n get description(): string {\n return \"Fetch recent messages from a session\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n sessionKey: { type: \"string\", description: \"Session id\" },\n limit: { type: \"integer\", minimum: 1, description: \"Maximum number of messages to return\" },\n includeTools: { type: \"boolean\", description: \"Include tool messages\" },\n },\n required: [\"sessionKey\"],\n };\n }\n\n execute = async (params: Record<string, unknown>): Promise<string> => {\n const { includeTools, limit, sessionKey: rawSessionKey } = params;\n const sessionKey = readString(rawSessionKey);\n if (!sessionKey) return \"Error: sessionKey is required\";\n const session = await this.resolveSession(sessionKey);\n if (!session) return `Error: session '${sessionKey}' not found`;\n const messages = await this.sessions.listSessionMessages(session.sessionId);\n const filtered = includeTools === true ? messages : messages.filter((message) => message.role !== \"tool\");\n return JSON.stringify({\n sessionKey: session.sessionId,\n messages: capHistory(filtered.slice(-toInt(limit, DEFAULT_LIMIT)).map(sanitizeMessage)),\n }, null, 2);\n };\n\n private resolveSession = async (sessionKey: string): Promise<NcpSessionSummary | null> => {\n const exact = await this.sessions.getSession(sessionKey);\n if (exact) return exact;\n const summaries = await this.sessions.listSessions();\n return summaries.find((summary) =>\n summary.sessionId.endsWith(`:${sessionKey}`) || sessionLabel(summary) === sessionKey\n ) ?? null;\n };\n}\n","import type { NcpTool } from \"@nextclaw/ncp\";\nimport {\n DEFAULT_SESSION_SEARCH_LIMIT,\n MAX_SESSION_SEARCH_LIMIT,\n type SessionSearchRequest,\n type SessionSearchResult,\n} from \"@nextclaw/core\";\nimport { normalizeString } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction readOptionalInteger(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n return undefined;\n }\n return Math.trunc(value);\n}\n\nfunction readOptionalBoolean(value: unknown): boolean | undefined {\n return typeof value === \"boolean\" ? value : undefined;\n}\n\nexport class SessionSearchTool implements NcpTool {\n readonly name = \"session_search\";\n readonly description =\n \"Search prior sessions by keyword and return structured hits with snippets. Use it to recall earlier discussions before creating new plans or summaries.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"Keyword search query for prior session text or labels.\",\n },\n limit: {\n type: \"integer\",\n minimum: 1,\n maximum: MAX_SESSION_SEARCH_LIMIT,\n description: `Optional max hit count. Defaults to ${DEFAULT_SESSION_SEARCH_LIMIT}.`,\n },\n includeCurrentSession: {\n type: \"boolean\",\n description: \"Set true to include the current session in results. Defaults to false.\",\n },\n },\n required: [\"query\"],\n additionalProperties: false,\n };\n\n constructor(\n private readonly queryService: {\n search: (request: SessionSearchRequest) => Promise<SessionSearchResult>;\n },\n private readonly context: {\n currentSessionId?: string;\n },\n ) {}\n\n validateArgs = (args: Record<string, unknown>): string[] => {\n const issues: string[] = [];\n const query = normalizeString(args.query);\n const limit = readOptionalInteger(args.limit);\n const includeCurrentSession = readOptionalBoolean(args.includeCurrentSession);\n\n if (!query) {\n issues.push(\"query must be a non-empty string.\");\n }\n if (typeof args.limit !== \"undefined\" && typeof limit === \"undefined\") {\n issues.push(\"limit must be a finite integer.\");\n }\n if (typeof limit === \"number\" && (limit < 1 || limit > MAX_SESSION_SEARCH_LIMIT)) {\n issues.push(`limit must be between 1 and ${MAX_SESSION_SEARCH_LIMIT}.`);\n }\n if (\n typeof args.includeCurrentSession !== \"undefined\" &&\n typeof includeCurrentSession === \"undefined\"\n ) {\n issues.push(\"includeCurrentSession must be a boolean.\");\n }\n\n return issues;\n };\n\n execute = async (args: unknown): Promise<unknown> => {\n if (!isRecord(args)) {\n throw new Error(\"session_search requires an object argument.\");\n }\n\n const issues = this.validateArgs(args);\n if (issues.length > 0) {\n throw new Error(issues.join(\" \"));\n }\n\n return this.queryService.search({\n query: normalizeString(args.query) ?? \"\",\n limit: readOptionalInteger(args.limit),\n includeCurrentSession: readOptionalBoolean(args.includeCurrentSession),\n currentSessionId: this.context.currentSessionId,\n });\n };\n}\n","import {\n Tool,\n type SessionRequestNotifyMode,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport type { SessionRequestManager } from \"@kernel/features/session-request/index.js\";\n\nfunction readRequiredString(value: unknown, key: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new Error(`${key} must be a non-empty string.`);\n }\n return value.trim();\n}\n\nfunction readOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\ntype SessionSpawnScope = \"standalone\" | \"child\";\n\nfunction readSpawnScope(value: unknown): SessionSpawnScope {\n const normalized = readOptionalString(value)?.toLowerCase();\n if (!normalized || normalized === \"standalone\") {\n return \"standalone\";\n }\n if (normalized === \"child\") {\n return \"child\";\n }\n throw new Error('scope must be \"standalone\" or \"child\".');\n}\n\nfunction readSpawnNotify(value: unknown): SessionRequestNotifyMode | undefined {\n const notifyMode = readOptionalString(value)?.toLowerCase();\n if (!notifyMode && typeof value === \"undefined\") {\n return undefined;\n }\n if (notifyMode === \"none\" || notifyMode === \"final_reply\") {\n return notifyMode;\n }\n throw new Error('notify must be \"none\" or \"final_reply\".');\n}\n\nexport class SessionSpawnTool extends Tool {\n private sourceSessionId = \"\";\n private sourceSessionMetadata: Record<string, unknown> = {};\n private handoffDepth = 0;\n\n constructor(\n private readonly ncpSessionManager: NcpSessionManager,\n private readonly sessionRequestManager: SessionRequestManager,\n ) {\n super();\n }\n\n get name(): string {\n return \"sessions_spawn\";\n }\n\n get description(): string {\n return \"Create a new session. Use scope=\\\"child\\\" to create a child session of the current flow, and add notify when the new session should start immediately.\";\n }\n\n get parameters(): Record<string, unknown> {\n return {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description: \"Seed text used to title the new session. If notify is provided, this same task is also sent as the first request to that new session.\",\n },\n scope: {\n type: \"string\",\n enum: [\"standalone\", \"child\"],\n description: \"Whether the new session should be a standalone thread or a child session of the current session.\",\n },\n title: {\n type: \"string\",\n description: \"Optional explicit session title.\",\n },\n model: {\n type: \"string\",\n description: \"Optional model override for the new session.\",\n },\n runtime: {\n type: \"string\",\n description: \"Optional runtime override for the new session, for example native or codex.\",\n },\n agentId: {\n type: \"string\",\n description: \"Optional target agent id for the new session. Omit to use the default agent.\",\n },\n notify: {\n type: \"string\",\n enum: [\"none\", \"final_reply\"],\n description: \"Optional. Starts the new session immediately. Use \\\"final_reply\\\" to continue this session after the new session reaches its final reply, or \\\"none\\\" to let it run independently.\",\n },\n },\n required: [\"task\"],\n additionalProperties: false,\n };\n }\n\n setContext = (params: {\n sourceSessionId: string;\n sourceSessionMetadata: Record<string, unknown>;\n handoffDepth?: number;\n }): void => {\n this.sourceSessionId = params.sourceSessionId;\n this.sourceSessionMetadata = structuredClone(params.sourceSessionMetadata);\n this.handoffDepth = params.handoffDepth ?? 0;\n };\n\n execute = async (params: Record<string, unknown>, context: ToolExecutionContext): Promise<unknown> => {\n const {\n agentId: rawAgentId,\n model: rawModel,\n notify: rawNotify,\n runtime: rawRuntime,\n scope: rawScope,\n task: rawTask,\n title: rawTitle\n } = params;\n const task = readRequiredString(rawTask, \"task\");\n const scope = readSpawnScope(rawScope);\n const notify = readSpawnNotify(rawNotify);\n const parentSessionId = scope === \"child\" ? this.readParentSessionIdOrThrow() : undefined;\n const { toolCallId, updateToolCallResult } = context;\n\n if (notify) {\n return this.sessionRequestManager.spawnSessionAndRequest({\n sourceSessionId: this.sourceSessionId,\n ...(toolCallId ? { sourceToolCallId: toolCallId } : {}),\n updateToolCallResult,\n sourceSessionMetadata: this.sourceSessionMetadata,\n task,\n title: readOptionalString(rawTitle),\n agentId: readOptionalString(rawAgentId),\n model: readOptionalString(rawModel),\n runtime: readOptionalString(rawRuntime),\n handoffDepth: this.handoffDepth,\n ...(parentSessionId ? { parentSessionId } : {}),\n notify,\n });\n }\n\n const session = await this.ncpSessionManager.createSession({\n sourceSessionId: this.sourceSessionId,\n task,\n title: readOptionalString(rawTitle),\n sourceSessionMetadata: this.sourceSessionMetadata,\n agentId: readOptionalString(rawAgentId),\n model: readOptionalString(rawModel),\n runtime: readOptionalString(rawRuntime),\n ...(parentSessionId ? { parentSessionId } : {}),\n });\n\n return {\n kind: \"nextclaw.session\",\n sessionId: session.sessionId,\n ...(session.agentId ? { agentId: session.agentId } : {}),\n ...(session.parentSessionId ? { parentSessionId: session.parentSessionId } : {}),\n isChildSession: Boolean(session.parentSessionId),\n lifecycle: session.lifecycle,\n title: session.title,\n sessionType: session.sessionType,\n createdAt: session.createdAt,\n };\n };\n\n private readParentSessionIdOrThrow = (): string => {\n const sourceSessionId = this.sourceSessionId.trim();\n if (!sourceSessionId) {\n throw new Error('scope=\"child\" requires an active source session.');\n }\n return sourceSessionId;\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport {\n CronTool,\n EditFileTool,\n ExecTool,\n ExtensionToolAdapter,\n GatewayTool,\n ListDirTool,\n MemoryGetTool,\n MemorySearchTool,\n MessageTool,\n ReadFileTool,\n WebFetchTool,\n WebSearchTool,\n WriteFileTool,\n} from \"@nextclaw/core\";\nimport type {\n ToolRegistrationContext,\n ToolRunContext,\n} from \"@kernel/managers/tool.manager.js\";\nimport { createAssetTools } from \"@kernel/features/native-runtime/index.js\";\nimport { SessionRequestTool } from \"@kernel/tools/session-request.tools.js\";\nimport { SessionsHistoryTool, SessionsListTool } from \"@kernel/tools/session-history.tools.js\";\nimport { SessionSearchTool } from \"@kernel/tools/session-search.tools.js\";\nimport { SessionSpawnTool } from \"@kernel/tools/session-spawn.tools.js\";\nimport { normalizeString } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nfunction readMetadataAccountId(metadata: Record<string, unknown>): string | undefined {\n const candidates = [metadata.accountId, metadata.account_id];\n for (const candidate of candidates) {\n const normalized = normalizeString(candidate);\n if (normalized) {\n return normalized;\n }\n }\n return undefined;\n}\n\nexport class ToolContribution implements KernelContribution {\n private registration: { dispose: () => void } | null = null;\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.registration) {\n return;\n }\n this.registration = this.kernel.toolManager.provideTools({\n id: \"nextclaw-core-tools\",\n registerTools: this.registerTools,\n });\n };\n\n dispose = (): void => {\n this.registration?.dispose();\n this.registration = null;\n };\n\n private registerTools = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n this.registerDefaultTools(context, registry);\n this.registerExtensionTools(context, registry);\n for (const tool of createAssetTools({ assetStore: this.kernel.assetStore })) {\n registry.registerNcpTool(tool);\n }\n for (const tool of this.kernel.mcpManager.listToolsForRun({ agentId: context.agentId })) {\n registry.registerNcpTool(tool);\n }\n this.registerSessionSearchTool(context, registry);\n };\n\n private registerDefaultTools = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n const {\n channel,\n chatId,\n execTimeoutSeconds,\n handoffDepth,\n metadata,\n restrictToWorkspace,\n searchConfig,\n sessionId,\n workspace,\n } = context;\n const allowedDir = restrictToWorkspace ? workspace : undefined;\n registry.registerTool(new ReadFileTool(allowedDir));\n registry.registerTool(new WriteFileTool(allowedDir));\n registry.registerTool(new EditFileTool(allowedDir));\n registry.registerTool(new ListDirTool(allowedDir));\n\n const execTool = new ExecTool({\n workingDir: workspace,\n timeout: execTimeoutSeconds,\n restrictToWorkspace,\n });\n execTool.setContext({\n sessionKey: sessionId,\n channel,\n chatId,\n });\n registry.registerTool(execTool);\n\n registry.registerTool(new WebSearchTool(searchConfig));\n registry.registerTool(new WebFetchTool());\n this.registerMessagingTools({ channel, chatId, metadata }, registry);\n\n const sessionsSpawnTool = new SessionSpawnTool(\n this.kernel.ncpSessionManager,\n this.kernel.sessionRequests,\n );\n sessionsSpawnTool.setContext({\n sourceSessionId: sessionId,\n sourceSessionMetadata: metadata,\n handoffDepth,\n });\n registry.registerTool(sessionsSpawnTool);\n\n const sessionsRequestTool = new SessionRequestTool(this.kernel.sessionRequests);\n sessionsRequestTool.setContext({\n sourceSessionId: sessionId,\n handoffDepth,\n });\n registry.registerTool(sessionsRequestTool);\n\n registry.registerTool(new SessionsListTool(this.kernel.ncpSessionManager));\n registry.registerTool(new SessionsHistoryTool(this.kernel.ncpSessionManager));\n\n registry.registerTool(new MemorySearchTool(workspace));\n registry.registerTool(new MemoryGetTool(workspace));\n\n const gatewayTool = new GatewayTool(this.kernel.getGatewayController());\n gatewayTool.setContext({ sessionKey: sessionId });\n registry.registerTool(gatewayTool);\n };\n\n private registerMessagingTools = (\n context: Pick<ToolRunContext, \"channel\" | \"chatId\" | \"metadata\">,\n registry: ToolRegistrationContext,\n ): void => {\n const { channel, chatId, metadata } = context;\n const accountId = readMetadataAccountId(metadata);\n const messageTool = new MessageTool(\n (message) => this.kernel.messageBus.publishOutbound(message),\n { resolveChannels: this.resolveMessageChannels },\n );\n messageTool.setContext(channel, chatId, accountId ?? null);\n registry.registerTool(messageTool);\n\n const cronTool = new CronTool(this.kernel.automation);\n cronTool.setContext(channel, chatId, accountId ?? null);\n registry.registerTool(cronTool);\n };\n\n private resolveMessageChannels = (): string[] => {\n const extensionRegistry = this.kernel.extensions.getExtensionRegistry();\n const channels = extensionRegistry?.channels ?? [];\n return [...new Set(channels.map((registration) => registration.channel.id.trim()).filter(Boolean))].sort();\n };\n\n private registerExtensionTools = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n const extensionRegistry = this.kernel.extensions.getExtensionRegistry();\n if (!extensionRegistry || extensionRegistry.tools.length === 0) {\n return;\n }\n\n const seen = new Set<string>();\n for (const registration of extensionRegistry.tools) {\n for (const alias of registration.names) {\n if (seen.has(alias) || registry.hasTool(alias)) {\n continue;\n }\n seen.add(alias);\n registry.registerTool(\n new ExtensionToolAdapter({\n registration,\n alias,\n config: context.config,\n workspaceDir: context.workspace,\n contextProvider: registry.getExtensionToolRunContext,\n diagnostics: extensionRegistry.diagnostics,\n }),\n );\n }\n }\n };\n\n private registerSessionSearchTool = (\n context: ToolRunContext,\n registry: ToolRegistrationContext,\n ): void => {\n if (!this.kernel.sessionSearch.isReady()) {\n return;\n }\n registry.registerNcpTool(\n new SessionSearchTool(\n { search: this.kernel.sessionSearch.search },\n { currentSessionId: context.sessionId },\n ),\n );\n };\n}\n","import { AgentManager } from \"@kernel/managers/agent.manager.js\";\nimport { AgentRunRequestManager } from \"@kernel/managers/agent-run-request.manager.js\";\nimport { AgentRuntimeManager } from \"@kernel/managers/agent-runtime.manager.js\";\nimport { AutomationManager } from \"@kernel/managers/automation.manager.js\";\nimport { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { ExtensionManager } from \"@kernel/managers/extension.manager.js\";\nimport { LlmProviderManager } from \"@kernel/managers/llm-provider.manager.js\";\nimport { LlmUsageManager } from \"@kernel/managers/llm-usage.manager.js\";\nimport { McpManager } from \"@kernel/managers/mcp.manager.js\";\nimport { NcpSessionManager } from \"@kernel/managers/ncp-session.manager.js\";\nimport { SkillManager } from \"@kernel/managers/skill.manager.js\";\nimport { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport { ToolManager } from \"@kernel/managers/tool.manager.js\";\nimport { NcpAgentSessionJournalStore } from \"@kernel/stores/ncp-agent-session-journal.store.js\";\nimport {\n createAgentRuntimeSessionRequestDispatcher,\n SessionRequestManager,\n} from \"@kernel/features/session-request/index.js\";\nimport { KernelBranch } from \"@kernel/contributions/kernel-branch/index.js\";\nimport { LegacyAgentRunContribution } from \"@kernel/contributions/legacy-agent-run/index.js\";\nimport { LearningLoopContribution } from \"@kernel/contributions/learning-loop/index.js\";\nimport { SessionActivityPreviewContribution } from \"@kernel/contributions/session-activity-preview/index.js\";\nimport { ToolContribution } from \"@kernel/contributions/tool-contribution/index.js\";\nimport { ContextCompactionManager } from \"@kernel/features/context-compaction/index.js\";\nimport type { AgentRuntimeSessionTypeDescribeParams } from \"@kernel/features/runtime-registry/index.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { LocalAssetStore } from \"@nextclaw/ncp-agent-runtime\";\nimport {\n ChannelManager,\n ensureDir,\n expandHome,\n type GatewayController,\n getDataDir,\n getSessionsPath,\n getWorkspacePath,\n MessageBus,\n SessionManager,\n SessionSearchManager,\n} from \"@nextclaw/core\";\nimport { EventBus, Ingress } from \"@nextclaw/shared\";\nimport { resolve } from \"node:path\";\n\nexport type NextclawKernelOptions = {\n homeDir?: string;\n configPath?: string;\n};\n\ntype AgentRunChain = \"branch\" | \"legacy\";\ntype AgentRunContribution = KernelContribution & {\n listSessionTypes: (params?: AgentRuntimeSessionTypeDescribeParams) => ReturnType<AgentRuntimeManager[\"listSessionTypes\"]>;\n};\n\nconst AGENT_RUN_CHAIN: AgentRunChain = \"branch\";\n\nfunction resolveKernelSessionsDir(options: NextclawKernelOptions): string {\n const homeDir = options.homeDir?.trim();\n if (homeDir) {\n return ensureDir(resolve(expandHome(homeDir), \"sessions\"));\n }\n return getSessionsPath();\n}\n\nfunction resolveKernelAutomationStorePath(options: NextclawKernelOptions): string {\n const homeDir = options.homeDir?.trim();\n if (homeDir) {\n return resolve(expandHome(homeDir), \"cron\", \"jobs.json\");\n }\n return resolve(getDataDir(), \"cron\", \"jobs.json\");\n}\n\ntype NextclawKernelRuntimeControl<\n TGatewayInput,\n TUiInput,\n TStartInput,\n> = {\n gateway: (input: TGatewayInput) => Promise<void>;\n ui: (input: TUiInput) => Promise<void>;\n start: (input: TStartInput) => Promise<void>;\n restart: (input: TStartInput) => Promise<void>;\n serve: (input: TStartInput) => Promise<void>;\n stop: () => Promise<void>;\n};\n\nclass NextclawKernelControlManager<\n TGatewayInput,\n TUiInput,\n TStartInput,\n> {\n private runtimeControl: NextclawKernelRuntimeControl<\n TGatewayInput,\n TUiInput,\n TStartInput\n > | null = null;\n\n installRuntimeControl = (\n runtimeControl: NextclawKernelRuntimeControl<\n TGatewayInput,\n TUiInput,\n TStartInput\n >,\n ) => {\n this.runtimeControl = runtimeControl;\n };\n\n requireRuntimeControl = () => {\n if (!this.runtimeControl) {\n throw new Error(\"Kernel runtime control is not installed.\");\n }\n return this.runtimeControl;\n };\n}\n\nexport class NextclawKernel {\n readonly eventBus: EventBus = new EventBus();\n readonly ingress: Ingress = new Ingress();\n readonly messageBus: MessageBus = new MessageBus();\n readonly llmProviders: LlmProviderManager = new LlmProviderManager();\n readonly llmUsage: LlmUsageManager = new LlmUsageManager();\n readonly configManager: ConfigManager;\n readonly agents: AgentManager;\n readonly sessions: SessionManager;\n readonly control: NextclawKernelControlManager<\n unknown,\n unknown,\n unknown\n >;\n readonly toolManager: ToolManager;\n readonly skills: SkillManager;\n readonly automation: AutomationManager;\n readonly channels: ChannelManager;\n readonly sessionRequests: SessionRequestManager;\n readonly sessionSearch: SessionSearchManager;\n readonly assetStore: LocalAssetStore;\n readonly mcpManager: McpManager;\n readonly ncpSessionManager: NcpSessionManager;\n readonly extensions: ExtensionManager;\n readonly agentRunRequestManager: AgentRunRequestManager;\n readonly sessionRunManager: SessionRunManager;\n readonly agentRuntimeManager: AgentRuntimeManager;\n private readonly ncpAgentSessionJournalStore: NcpAgentSessionJournalStore;\n private readonly agentRunContribution: AgentRunContribution;\n private readonly contributions: KernelContribution[];\n private gatewayController: GatewayController | undefined;\n\n constructor(options: NextclawKernelOptions = {}) {\n const sessionsDir = resolveKernelSessionsDir(options);\n this.sessions = new SessionManager({\n sessionsDir,\n });\n this.sessionSearch = new SessionSearchManager({\n databasePath: resolve(getDataDir(), \"session-search.db\"),\n sessionsDir,\n });\n this.ncpAgentSessionJournalStore = new NcpAgentSessionJournalStore(\n resolve(sessionsDir, \".ncp-agent-journal\"),\n );\n this.automation = new AutomationManager({\n storePath: resolveKernelAutomationStorePath(options),\n });\n this.assetStore = new LocalAssetStore({\n rootDir: resolve(getDataDir(), \"assets\"),\n });\n this.agents = new AgentManager();\n this.control = new NextclawKernelControlManager<\n unknown,\n unknown,\n unknown\n >();\n this.toolManager = new ToolManager();\n this.channels = new ChannelManager({\n bus: this.messageBus,\n sessionManager: this.sessions,\n });\n this.configManager = new ConfigManager({\n configPath: options.configPath,\n channels: this.channels,\n providerManager: this.llmProviders,\n });\n this.extensions = new ExtensionManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n ingress: this.ingress,\n messageBus: this.messageBus,\n sessionManager: this.sessions,\n });\n this.skills = new SkillManager({\n workspace: getWorkspacePath(this.configManager.config.agents.defaults.workspace),\n });\n this.mcpManager = new McpManager(this.configManager.loadConfig);\n this.configManager.installRuntimeHooks({\n resolveChannelConfig: this.extensions.toConfigView,\n getExtensionChannels: () => this.extensions.getExtensionRegistry().channels,\n reloadMcp: async ({ config }) => await this.mcpManager.applyConfig(config),\n });\n this.agentRuntimeManager = new AgentRuntimeManager({\n configManager: this.configManager,\n assetStore: this.assetStore,\n });\n this.ncpSessionManager = new NcpSessionManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n journalStore: this.ncpAgentSessionJournalStore,\n sessionSearch: this.sessionSearch,\n });\n this.sessionRequests = new SessionRequestManager({\n ncpSessionManager: this.ncpSessionManager,\n dispatcher: createAgentRuntimeSessionRequestDispatcher({\n eventBus: this.eventBus,\n ingress: this.ingress,\n }),\n });\n this.sessionRunManager = new SessionRunManager({\n agentRuntimeManager: this.agentRuntimeManager,\n eventBus: this.eventBus,\n ncpSessionManager: this.ncpSessionManager,\n });\n this.agentRunRequestManager = new AgentRunRequestManager({\n contextCompactionManager: new ContextCompactionManager({\n configManager: this.configManager,\n providerManager: this.llmProviders,\n sessionRunManager: this.sessionRunManager,\n }),\n ingress: this.ingress,\n ncpSessionManager: this.ncpSessionManager,\n sessionRunManager: this.sessionRunManager,\n });\n this.agentRunContribution =\n AGENT_RUN_CHAIN === \"branch\"\n ? new KernelBranch(this)\n : new LegacyAgentRunContribution(this);\n this.contributions = [\n new ToolContribution(this),\n new SessionActivityPreviewContribution(this),\n new LearningLoopContribution(this),\n this.agentRunContribution,\n ];\n }\n\n listSessionTypes = (params?: AgentRuntimeSessionTypeDescribeParams) =>\n this.agentRunContribution.listSessionTypes(params);\n\n provideGatewayController = (gatewayController: GatewayController): void => {\n this.gatewayController = gatewayController;\n };\n\n getGatewayController = (): GatewayController | undefined => this.gatewayController;\n\n start = async (): Promise<void> => {\n void this.sessionSearch.start();\n this.mcpManager.start();\n for (const contribution of this.contributions) {\n contribution.start();\n }\n };\n\n dispose = async (): Promise<void> => {\n for (const contribution of [...this.contributions].reverse()) {\n await contribution.dispose();\n }\n this.ncpSessionManager.dispose();\n await this.agentRuntimeManager.dispose();\n await this.mcpManager.dispose();\n await this.sessionSearch.dispose();\n };\n\n}\n","import type { InboundAttachment } from \"@nextclaw/core\";\nimport {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpMessage,\n type NcpMessagePart,\n type NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport {\n eventKeys,\n ingressKeys,\n type AgentRunSendIngressPayload,\n type EventBus,\n type Ingress,\n} from \"@nextclaw/shared\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { extractTextFromNcpMessage } from \"@kernel/utils/ncp-message-bridge.utils.js\";\n\nexport type AssetApi = {\n putBytes: (input: {\n fileName: string;\n mimeType?: string | null;\n bytes: Uint8Array;\n createdAt?: Date;\n }) => Promise<{ uri: string }>;\n resolveContentPath?: (uri: string) => string | null;\n};\n\nexport type BuildAgentRunSendPayloadParams = {\n sessionId: string;\n content: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n assetApi?: AssetApi;\n};\n\nexport type AgentRunReplyOptions = {\n abortSignal?: AbortSignal;\n onAssistantDelta?: (delta: string) => void;\n onEvent?: (event: NcpEndpointEvent) => void;\n missingCompletedMessageError?: string;\n runErrorMessage?: string;\n};\n\nexport type AgentRunStreamOptions = {\n abortSignal?: AbortSignal;\n onEvent?: (event: NcpEndpointEvent) => void;\n};\n\nexport type AgentRunReply = {\n handle: NcpRunHandle;\n text: string;\n completedMessage: NcpMessage;\n};\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction resolveAttachmentName(attachment: InboundAttachment): string {\n const explicitName = normalizeOptionalString(attachment.name);\n if (explicitName) {\n return explicitName;\n }\n const explicitPath = normalizeOptionalString(attachment.path);\n if (explicitPath) {\n return basename(explicitPath);\n }\n const explicitUrl = normalizeOptionalString(attachment.url);\n if (explicitUrl) {\n try {\n const parsed = new URL(explicitUrl);\n return basename(parsed.pathname) || \"asset.bin\";\n } catch {\n return basename(explicitUrl) || \"asset.bin\";\n }\n }\n return \"asset.bin\";\n}\n\nasync function attachmentToPart(\n attachment: InboundAttachment,\n assetApi?: AssetApi,\n): Promise<NcpMessagePart> {\n const assetUri = normalizeOptionalString(attachment.assetUri);\n if (assetUri) {\n return createFilePartFromAssetUri(attachment, assetUri);\n }\n\n const remoteUrl = normalizeOptionalString(attachment.url);\n const localPath = normalizeOptionalString(attachment.path);\n if (localPath) {\n return await createFilePartFromLocalPath(attachment, localPath, assetApi);\n }\n\n if (remoteUrl) {\n return createFilePartFromRemoteUrl(attachment, remoteUrl);\n }\n\n throw new Error(\n `Unsupported attachment payload for \"${resolveAttachmentName(attachment)}\".`,\n );\n}\n\nfunction createBaseFilePart(attachment: InboundAttachment): {\n name?: string;\n mimeType?: string;\n sizeBytes?: number;\n} {\n return {\n ...(attachment.name ? { name: attachment.name } : {}),\n ...(attachment.mimeType ? { mimeType: attachment.mimeType } : {}),\n ...(typeof attachment.size === \"number\"\n ? { sizeBytes: attachment.size }\n : {}),\n };\n}\n\nfunction createFilePartFromAssetUri(\n attachment: InboundAttachment,\n assetUri: string,\n): NcpMessagePart {\n return {\n type: \"file\",\n assetUri,\n ...createBaseFilePart(attachment),\n };\n}\n\nasync function createFilePartFromLocalPath(\n attachment: InboundAttachment,\n localPath: string,\n assetApi?: AssetApi,\n): Promise<NcpMessagePart> {\n if (!assetApi) {\n throw new Error(\"NCP asset api is unavailable for local attachments.\");\n }\n\n const fileName = resolveAttachmentName(attachment);\n const bytes = await readFile(localPath);\n const stored = await assetApi.putBytes({\n fileName,\n mimeType: attachment.mimeType ?? null,\n bytes,\n });\n return {\n type: \"file\",\n assetUri: stored.uri,\n name: attachment.name ?? fileName,\n ...(attachment.mimeType ? { mimeType: attachment.mimeType } : {}),\n ...(typeof attachment.size === \"number\"\n ? { sizeBytes: attachment.size }\n : {}),\n };\n}\n\nfunction createFilePartFromRemoteUrl(\n attachment: InboundAttachment,\n remoteUrl: string,\n): NcpMessagePart {\n return {\n type: \"file\",\n url: remoteUrl,\n name: attachment.name ?? resolveAttachmentName(attachment),\n ...(attachment.mimeType ? { mimeType: attachment.mimeType } : {}),\n ...(typeof attachment.size === \"number\"\n ? { sizeBytes: attachment.size }\n : {}),\n };\n}\n\nexport async function buildUserMessageParts(params: {\n content: string;\n attachments?: InboundAttachment[];\n assetApi?: AssetApi;\n}): Promise<NcpMessagePart[]> {\n const { assetApi, attachments, content } = params;\n const parts: NcpMessagePart[] = [];\n if (content.length > 0) {\n parts.push({\n type: \"text\",\n text: content,\n });\n }\n\n for (const attachment of attachments ?? []) {\n parts.push(await attachmentToPart(attachment, assetApi));\n }\n\n return parts;\n}\n\nexport async function buildAgentRunSendPayload(\n params: BuildAgentRunSendPayloadParams,\n): Promise<AgentRunSendIngressPayload> {\n const { assetApi, attachments, content, metadata, sessionId } = params;\n return {\n sessionId,\n content: await buildUserMessageParts({\n content,\n attachments,\n assetApi,\n }),\n metadata: structuredClone(metadata ?? {}),\n };\n}\n\nfunction readEventCorrelationId(event: NcpEndpointEvent): string | undefined {\n if (!(\"payload\" in event)) {\n return undefined;\n }\n const correlationId = \"correlationId\" in event.payload\n ? event.payload.correlationId\n : undefined;\n return typeof correlationId === \"string\" && correlationId.length > 0\n ? correlationId\n : undefined;\n}\n\nfunction readEventSessionId(event: NcpEndpointEvent): string | undefined {\n if (!(\"payload\" in event)) {\n return undefined;\n }\n const sessionId = \"sessionId\" in event.payload\n ? event.payload.sessionId\n : undefined;\n return typeof sessionId === \"string\" && sessionId.length > 0\n ? sessionId\n : undefined;\n}\n\nfunction readEventRunId(event: NcpEndpointEvent): string | undefined {\n if (!(\"payload\" in event)) {\n return undefined;\n }\n const runId = \"runId\" in event.payload ? event.payload.runId : undefined;\n return typeof runId === \"string\" && runId.length > 0 ? runId : undefined;\n}\n\nfunction isTerminalEvent(event: NcpEndpointEvent): boolean {\n return event.type === NcpEventType.MessageFailed ||\n event.type === NcpEventType.RunError ||\n event.type === NcpEventType.RunFinished;\n}\n\nfunction isRunEventMatch(params: {\n correlationId: string;\n event: NcpEndpointEvent;\n runId?: string;\n sessionId?: string;\n}): boolean {\n const eventCorrelationId = readEventCorrelationId(params.event);\n if (eventCorrelationId) {\n return eventCorrelationId === params.correlationId;\n }\n if (!params.sessionId || !params.runId) {\n return false;\n }\n return readEventSessionId(params.event) === params.sessionId &&\n readEventRunId(params.event) === params.runId;\n}\n\nclass AsyncEventQueue<T> implements AsyncIterable<T> {\n private readonly values: T[] = [];\n private readonly waiters: Array<(result: IteratorResult<T>) => void> = [];\n private closed = false;\n private failure: unknown;\n private hasFailure = false;\n\n push = (value: T): void => {\n if (this.closed || this.hasFailure) {\n return;\n }\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter({ done: false, value });\n return;\n }\n this.values.push(value);\n };\n\n close = (): void => {\n if (this.closed) {\n return;\n }\n this.closed = true;\n while (this.waiters.length > 0) {\n this.waiters.shift()?.({ done: true, value: undefined as T });\n }\n };\n\n fail = (error: unknown): void => {\n if (this.closed || this.hasFailure) {\n return;\n }\n this.hasFailure = true;\n this.failure = error;\n while (this.waiters.length > 0) {\n this.waiters.shift()?.({ done: true, value: undefined as T });\n }\n };\n\n next = async (): Promise<IteratorResult<T>> => {\n if (this.values.length > 0) {\n return {\n done: false,\n value: this.values.shift() as T,\n };\n }\n if (this.hasFailure) {\n throw this.failure;\n }\n if (this.closed) {\n return {\n done: true,\n value: undefined as T,\n };\n }\n return await new Promise<IteratorResult<T>>((resolve) => {\n this.waiters.push(resolve);\n });\n };\n\n [Symbol.asyncIterator] = (): AsyncIterator<T> => ({\n next: this.next,\n });\n}\n\nclass AgentRunObserver {\n private readonly queue = new AsyncEventQueue<NcpEndpointEvent>();\n private readonly unsubscribe: () => void;\n private abortCleanup?: () => void;\n private completedMessage?: NcpMessage;\n private disposed = false;\n private runId?: string;\n private sessionId?: string;\n\n constructor(\n private readonly options: {\n abortSignal?: AbortSignal;\n correlationId: string;\n eventBus: Pick<EventBus, \"on\">;\n ingress: Pick<Ingress, \"handle\">;\n onEvent?: (event: NcpEndpointEvent) => void;\n },\n ) {\n this.unsubscribe = options.eventBus.on(eventKeys.ncpEvent, this.handleEvent);\n }\n\n attachHandle = (handle: NcpRunHandle): void => {\n this.sessionId = handle.sessionId;\n this.runId = handle.runId ?? undefined;\n const { abortSignal } = this.options;\n if (!abortSignal) {\n return;\n }\n const abort = (): void => {\n void this.options.ingress.handle(\n {\n type: ingressKeys.agentRun.abort,\n payload: {\n sessionId: handle.sessionId,\n correlationId: this.options.correlationId,\n },\n },\n { source: \"agent-run-client\" },\n );\n };\n if (abortSignal.aborted) {\n abort();\n return;\n }\n abortSignal.addEventListener(\"abort\", abort, { once: true });\n this.abortCleanup = () => abortSignal.removeEventListener(\"abort\", abort);\n };\n\n stream = async function* (this: AgentRunObserver): AsyncGenerator<NcpEndpointEvent> {\n for await (const event of this.queue) {\n yield event;\n }\n };\n\n waitForReply = async (options: AgentRunReplyOptions = {}): Promise<NcpMessage> => {\n for await (const event of this.queue) {\n if (event.type === NcpEventType.MessageTextDelta) {\n options.onAssistantDelta?.(event.payload.delta);\n continue;\n }\n if (event.type === NcpEventType.MessageCompleted) {\n this.completedMessage = event.payload.message;\n continue;\n }\n if (event.type === NcpEventType.MessageFailed) {\n throw new Error(event.payload.error.message);\n }\n if (event.type === NcpEventType.RunError) {\n throw new Error(event.payload.error ?? options.runErrorMessage ?? \"NCP run failed.\");\n }\n if (event.type === NcpEventType.RunFinished) {\n if (!this.completedMessage) {\n throw new Error(\n options.missingCompletedMessageError ??\n \"NCP run completed without a final assistant message.\",\n );\n }\n return this.completedMessage;\n }\n }\n throw new Error(\n options.missingCompletedMessageError ??\n \"NCP run completed without a final assistant message.\",\n );\n };\n\n dispose = (): void => {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.abortCleanup?.();\n this.unsubscribe();\n this.queue.close();\n };\n\n private handleEvent = (event: NcpEndpointEvent): void => {\n if (this.disposed || !isRunEventMatch({\n correlationId: this.options.correlationId,\n event,\n runId: this.runId,\n sessionId: this.sessionId,\n })) {\n return;\n }\n this.options.onEvent?.(event);\n this.queue.push(event);\n if (isTerminalEvent(event)) {\n this.queue.close();\n }\n };\n}\n\nexport class AgentRunClient {\n constructor(\n private readonly options: {\n eventBus: Pick<EventBus, \"on\">;\n ingress: Pick<Ingress, \"handle\">;\n },\n ) {}\n\n send = async (input: AgentRunSendIngressPayload): Promise<NcpRunHandle> => {\n return await this.sendWithCorrelation(input, randomUUID());\n };\n\n sendAndWaitForReply = async (\n input: AgentRunSendIngressPayload,\n options: AgentRunReplyOptions = {},\n ): Promise<AgentRunReply> => {\n const correlationId = randomUUID();\n const observer = this.prepareObserver(correlationId, options);\n try {\n const handle = await this.sendWithCorrelation(input, correlationId);\n observer.attachHandle(handle);\n const completedMessage = await observer.waitForReply(options);\n return {\n handle,\n completedMessage,\n text: extractTextFromNcpMessage(completedMessage),\n };\n } finally {\n observer.dispose();\n }\n };\n\n sendAndStreamEvents = async function* (\n this: AgentRunClient,\n input: AgentRunSendIngressPayload,\n options: AgentRunStreamOptions = {},\n ): AsyncGenerator<NcpEndpointEvent> {\n const correlationId = randomUUID();\n const observer = this.prepareObserver(correlationId, options);\n try {\n const handle = await this.sendWithCorrelation(input, correlationId);\n observer.attachHandle(handle);\n for await (const event of observer.stream()) {\n yield event;\n }\n } finally {\n observer.dispose();\n }\n };\n\n private prepareObserver = (\n correlationId: string,\n options: AgentRunReplyOptions | AgentRunStreamOptions,\n ): AgentRunObserver => {\n return new AgentRunObserver({\n abortSignal: options.abortSignal,\n correlationId,\n eventBus: this.options.eventBus,\n ingress: this.options.ingress,\n onEvent: options.onEvent,\n });\n };\n\n private sendWithCorrelation = async (\n input: AgentRunSendIngressPayload,\n correlationId: string,\n ): Promise<NcpRunHandle> => {\n return await this.options.ingress.handle<AgentRunSendIngressPayload, NcpRunHandle>(\n {\n type: ingressKeys.agentRun.send,\n payload: {\n ...input,\n correlationId,\n },\n },\n { source: \"agent-run-client\" },\n );\n };\n}\n","import type {\n BaseChannel,\n InboundAttachment,\n InboundMessage,\n} from \"@nextclaw/core\";\nimport type {\n ChatTarget,\n NcpReplyInput,\n} from \"@nextclaw/ncp-toolkit\";\nimport type { NcpEndpointEvent } from \"@nextclaw/ncp\";\nimport {\n buildAgentRunSendPayload,\n type AgentRunClient,\n type AssetApi,\n} from \"./nextclaw-ncp-runner.utils.js\";\n\ntype ReplyCapableChannel = BaseChannel<Record<string, unknown>> & {\n consumeNcpReply(input: NcpReplyInput): Promise<void>;\n};\n\ntype ChannelReplyRoute = {\n target: ChatTarget;\n channel: ReplyCapableChannel;\n};\n\ntype ResolvedInboundRoute = {\n accountId?: string | null;\n};\n\nexport type ChannelReplyRouterDispatchParams = {\n agentRunClient: AgentRunClient;\n assetApi?: AssetApi;\n route: ChannelReplyRoute;\n sessionId: string;\n content: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n abortSignal?: AbortSignal;\n onEvent?: (event: NcpEndpointEvent) => void;\n};\n\nfunction readString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nexport function isReplyCapableChannel(\n channel: BaseChannel<Record<string, unknown>> | null | undefined,\n): channel is ReplyCapableChannel {\n return (\n Boolean(channel) &&\n typeof (channel as Partial<ReplyCapableChannel>).consumeNcpReply === \"function\"\n );\n}\n\nexport function resolveChannelReplyRoute(params: {\n channel: BaseChannel<Record<string, unknown>> | null | undefined;\n message: InboundMessage;\n route: ResolvedInboundRoute;\n}): ChannelReplyRoute | null {\n const { channel, message, route } = params;\n if (!isReplyCapableChannel(channel)) {\n return null;\n }\n\n const metadata = structuredClone(message.metadata ?? {});\n const accountId =\n readString(route.accountId) ??\n readString(metadata.accountId) ??\n readString(metadata.account_id);\n\n return {\n target: {\n conversationId: message.chatId,\n ...(accountId ? { accountId } : {}),\n ...(Object.keys(metadata).length > 0 ? { metadata } : {}),\n },\n channel,\n };\n}\n\nexport async function dispatchChannelReplyRoute(\n params: ChannelReplyRouterDispatchParams,\n): Promise<void> {\n const {\n abortSignal,\n agentRunClient,\n assetApi,\n attachments,\n content,\n metadata,\n onEvent,\n route,\n sessionId,\n } = params;\n const input: NcpReplyInput = {\n target: {\n ...route.target,\n ...(assetApi?.resolveContentPath\n ? {\n resolveAssetContentPath:\n assetApi.resolveContentPath,\n }\n : {}),\n },\n eventStream: agentRunClient.sendAndStreamEvents(await buildAgentRunSendPayload({\n sessionId,\n content,\n attachments,\n metadata,\n assetApi,\n }), {\n abortSignal,\n onEvent,\n }),\n };\n await route.channel.consumeNcpReply(input);\n}\n","import type { AgentRouteResolver, InboundMessage } from \"@nextclaw/core\";\n\nconst LEGACY_RUN_METADATA_KEYS = [\n \"account_id\",\n \"agent_id\",\n \"chat_id\",\n \"preferred_model\",\n \"project_root\",\n \"runtime\",\n \"sender_id\",\n \"session_key\",\n \"session_type\",\n] as const;\n\nfunction stripLegacyRunMetadata(\n metadata: Record<string, unknown>,\n): Record<string, unknown> {\n const nextMetadata = structuredClone(metadata);\n for (const key of LEGACY_RUN_METADATA_KEYS) {\n delete nextMetadata[key];\n }\n return nextMetadata;\n}\n\nexport function buildRunMetadata(params: {\n message: Pick<InboundMessage, \"channel\" | \"chatId\" | \"metadata\" | \"senderId\">;\n route: ReturnType<AgentRouteResolver[\"resolveInbound\"]>;\n metadata?: Record<string, unknown>;\n}): Record<string, unknown> {\n const { message, metadata, route } = params;\n const metadataContext = stripLegacyRunMetadata({\n ...(message.metadata ?? {}),\n ...(metadata ?? {}),\n });\n return {\n ...metadataContext,\n channel: message.channel,\n chatId: message.chatId,\n accountId: route.accountId,\n agentId: route.agentId,\n sessionKey: route.sessionKey,\n senderId: message.senderId,\n };\n}\n","import {\n AgentRouteResolver,\n CommandRegistry,\n createAssistantStreamDeltaControlMessage,\n createAssistantStreamResetControlMessage,\n createTypingStopControlMessage,\n type ChannelManager,\n type Config,\n type InboundMessage,\n type MessageBus,\n type SessionManager,\n} from \"@nextclaw/core\";\nimport { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport {\n dispatchChannelReplyRoute,\n resolveChannelReplyRoute,\n} from \"@kernel/features/ncp-dispatch/utils/channel-reply.utils.js\";\nimport { buildRunMetadata } from \"@kernel/features/ncp-dispatch/utils/ncp-run-metadata.utils.js\";\nimport {\n buildAgentRunSendPayload,\n type AgentRunClient,\n type AgentRunReply,\n type AssetApi,\n} from \"@kernel/features/ncp-dispatch/utils/nextclaw-ncp-runner.utils.js\";\n\nexport type GatewayInboundLoopRuntime = {\n kernel: {\n channels: ChannelManager;\n assetStore: AssetApi;\n };\n agentRunClient: AgentRunClient;\n messageBus: MessageBus;\n sessionManager: SessionManager;\n configManager: {\n loadConfig: () => Config;\n };\n appEventBus?: EventBus;\n};\n\ntype GatewayRoute = ReturnType<AgentRouteResolver[\"resolveInbound\"]>;\n\nfunction formatUserFacingError(error: unknown, maxChars = 320): string {\n const raw = error instanceof Error ? error.message || error.name : String(error ?? \"Unknown error\");\n const normalized = raw.replace(/\\s+/g, \" \").trim();\n if (!normalized) {\n return \"Unknown error\";\n }\n return normalized.length <= maxChars\n ? normalized\n : `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;\n}\n\nexport class GatewayInboundProcessor {\n constructor(private runtime: GatewayInboundLoopRuntime) {}\n\n process = async (message: InboundMessage): Promise<void> => {\n try {\n const route = this.resolveRoute(message);\n const runMetadata = buildRunMetadata({\n message,\n route,\n });\n if (await this.dispatchSlashCommandMaybe(message, route, runMetadata)) {\n return;\n }\n if (await this.dispatchChannelReplyRouteMaybe(message, route, runMetadata)) {\n return;\n }\n if (message.channel !== \"system\") {\n await this.runtime.messageBus.publishOutbound(\n createAssistantStreamResetControlMessage(message),\n );\n }\n const result = await this.runtime.agentRunClient.sendAndWaitForReply(await buildAgentRunSendPayload({\n sessionId: route.sessionKey,\n content: message.content,\n attachments: message.attachments,\n metadata: runMetadata,\n assetApi: this.runtime.kernel.assetStore,\n }), {\n onAssistantDelta:\n message.channel !== \"system\"\n ? (delta) => {\n if (!delta) {\n return;\n }\n void this.runtime.messageBus.publishOutbound(\n createAssistantStreamDeltaControlMessage(message, delta),\n );\n }\n : undefined,\n missingCompletedMessageError: `session \"${route.sessionKey}\" completed without a final assistant message`,\n runErrorMessage: `session \"${route.sessionKey}\" failed`,\n });\n await this.publishLegacyReply(message, route, result);\n } catch (error) {\n await this.runtime.messageBus.publishOutbound({\n channel: message.channel,\n chatId: message.chatId,\n content: `Sorry, I encountered an error: ${formatUserFacingError(error)}`,\n media: [],\n metadata: {},\n });\n }\n };\n\n private resolveRoute = (message: InboundMessage): GatewayRoute => {\n const normalize = (value: unknown) =>\n typeof value === \"string\" ? value.trim() || undefined : undefined;\n return new AgentRouteResolver(this.runtime.configManager.loadConfig()).resolveInbound({\n message,\n forcedAgentId: normalize(message.metadata.target_agent_id),\n sessionKeyOverride: normalize(message.metadata.session_key_override),\n });\n };\n\n private dispatchSlashCommandMaybe = async (\n message: InboundMessage,\n route: GatewayRoute,\n runMetadata: Record<string, unknown>,\n ): Promise<boolean> => {\n if (message.channel === \"system\") {\n return false;\n }\n const trimmed = message.content.trim();\n if (!trimmed.startsWith(\"/\")) {\n return false;\n }\n const registry = new CommandRegistry(\n this.runtime.configManager.loadConfig(),\n this.runtime.sessionManager,\n );\n const result = await registry.executeText(trimmed, {\n channel: message.channel,\n chatId: message.chatId,\n senderId: message.senderId,\n sessionKey: route.sessionKey,\n });\n if (!result) {\n return false;\n }\n await this.runtime.messageBus.publishOutbound({\n channel: message.channel,\n chatId: message.chatId,\n content: result.content,\n media: [],\n metadata: runMetadata,\n });\n return true;\n };\n\n private dispatchChannelReplyRouteMaybe = async (\n message: InboundMessage,\n route: GatewayRoute,\n runMetadata: Record<string, unknown>,\n ): Promise<boolean> => {\n if (message.channel === \"system\") {\n return false;\n }\n\n const replyRoute = resolveChannelReplyRoute({\n channel: this.runtime.kernel.channels.getChannel(message.channel),\n message,\n route,\n });\n if (!replyRoute) {\n return false;\n }\n\n await dispatchChannelReplyRoute({\n agentRunClient: this.runtime.agentRunClient,\n assetApi: this.runtime.kernel.assetStore,\n route: replyRoute,\n sessionId: route.sessionKey,\n content: message.content,\n attachments: message.attachments,\n metadata: runMetadata,\n });\n return true;\n };\n\n private publishLegacyReply = async (\n message: InboundMessage,\n route: GatewayRoute,\n result: AgentRunReply,\n ): Promise<void> => {\n if (message.channel === \"system\") {\n this.runtime.appEventBus?.emit(eventKeys.sessionUpdated, { sessionKey: route.sessionKey }, {\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n });\n return;\n }\n\n const replyText = result.text.trim();\n if (!replyText) {\n await this.runtime.messageBus.publishOutbound(\n createTypingStopControlMessage(message),\n );\n return;\n }\n\n await this.runtime.messageBus.publishOutbound({\n channel: message.channel,\n chatId: message.chatId,\n content: result.text,\n media: [],\n metadata: buildRunMetadata({\n message,\n route,\n metadata: result.completedMessage.metadata,\n }),\n });\n };\n}\n\nexport async function runGatewayInboundLoop(\n runtime: GatewayInboundLoopRuntime,\n): Promise<void> {\n const processor = new GatewayInboundProcessor(runtime);\n while (true) {\n await processor.process(await runtime.messageBus.consumeInbound());\n }\n}\n","import {\n AgentRouteResolver,\n CommandRegistry,\n parseAgentScopedSessionKey,\n type Config,\n type InboundAttachment,\n type InboundMessage,\n} from \"@nextclaw/core\";\nimport { buildRunMetadata } from \"./ncp-run-metadata.utils.js\";\nimport {\n buildAgentRunSendPayload,\n type AgentRunClient,\n} from \"./nextclaw-ncp-runner.utils.js\";\nexport type DirectPromptDispatchParams = {\n config: Config;\n agentRunClient: AgentRunClient;\n content: string;\n sessionKey?: string;\n channel?: string;\n chatId?: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n agentId?: string;\n abortSignal?: AbortSignal;\n onAssistantDelta?: (delta: string) => void;\n};\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction createDirectInboundMessage(params: {\n content: string;\n channel?: string;\n chatId?: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n}): InboundMessage {\n const { attachments, channel, chatId, content, metadata } = params;\n return {\n channel: channel ?? \"cli\",\n senderId: \"user\",\n chatId: chatId ?? \"direct\",\n content,\n timestamp: new Date(),\n attachments: attachments ?? [],\n metadata: structuredClone(metadata ?? {}),\n };\n}\n\nasync function executeSlashCommandMaybe(params: {\n config: Config;\n rawContent: string;\n channel: string;\n chatId: string;\n sessionKey: string;\n}): Promise<string | null> {\n const { channel, chatId, config, rawContent, sessionKey } = params;\n const trimmed = rawContent.trim();\n if (!trimmed.startsWith(\"/\")) {\n return null;\n }\n const registry = new CommandRegistry(config);\n const result = await registry.executeText(rawContent, {\n channel,\n chatId,\n senderId: \"user\",\n sessionKey,\n });\n return result?.content ?? null;\n}\n\nfunction resolveDirectRoute(params: {\n config: Config;\n content: string;\n sessionKey?: string;\n channel?: string;\n chatId?: string;\n attachments?: InboundAttachment[];\n metadata?: Record<string, unknown>;\n agentId?: string;\n}): {\n message: InboundMessage;\n route: ReturnType<AgentRouteResolver[\"resolveInbound\"]>;\n} {\n const { agentId, config, sessionKey } = params;\n const message = createDirectInboundMessage(params);\n const forcedAgentId =\n normalizeOptionalString(agentId) ??\n parseAgentScopedSessionKey(sessionKey)?.agentId ??\n undefined;\n const routeResolver = new AgentRouteResolver(config);\n const route = routeResolver.resolveInbound({\n message,\n forcedAgentId,\n sessionKeyOverride: sessionKey,\n });\n return {\n message,\n route,\n };\n}\n\nexport async function dispatchPromptOverNcp(\n params: DirectPromptDispatchParams,\n): Promise<string> {\n const {\n abortSignal,\n agentId,\n attachments,\n channel,\n chatId,\n config,\n content,\n metadata,\n onAssistantDelta,\n agentRunClient,\n sessionKey,\n } = params;\n const { message, route } = resolveDirectRoute({\n config,\n content,\n sessionKey,\n channel,\n chatId,\n attachments,\n metadata,\n agentId,\n });\n const commandResult = await executeSlashCommandMaybe({\n config,\n rawContent: content,\n channel: message.channel,\n chatId: message.chatId,\n sessionKey: route.sessionKey,\n });\n if (commandResult) {\n return commandResult;\n }\n\n const result = await agentRunClient.sendAndWaitForReply(await buildAgentRunSendPayload({\n sessionId: route.sessionKey,\n content,\n attachments,\n metadata: buildRunMetadata({\n message,\n route,\n }),\n }), {\n abortSignal,\n onAssistantDelta,\n missingCompletedMessageError: `session \"${route.sessionKey}\" completed without a final assistant message`,\n runErrorMessage: `session \"${route.sessionKey}\" failed`,\n });\n return result.text;\n}\n","import type { SessionMessage } from \"@nextclaw/core\";\nimport { type NcpMessage, type NcpMessagePart, sanitizeAssistantReplyTags } from \"@nextclaw/ncp\";\nimport {\n ensureIsoTimestamp,\n normalizeString,\n} from \"./ncp-message-bridge.utils.js\";\n\ntype LegacyToolCall = {\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n};\n\nfunction tryParseJson(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nfunction toTextPart(text: string): NcpMessagePart | null {\n return text.length > 0 ? { type: \"text\", text } : null;\n}\n\nfunction contentToParts(content: unknown): NcpMessagePart[] {\n if (typeof content === \"string\") {\n const textPart = toTextPart(content);\n return textPart ? [textPart] : [];\n }\n if (Array.isArray(content)) {\n return content.length > 0\n ? [\n {\n type: \"extension\",\n extensionType: \"nextclaw.legacy.content-array\",\n data: structuredClone(content)\n }\n ]\n : [];\n }\n if (content && typeof content === \"object\") {\n return [\n {\n type: \"extension\",\n extensionType: \"nextclaw.legacy.content-object\",\n data: structuredClone(content)\n }\n ];\n }\n return [];\n}\n\nfunction normalizeToolResultPayload(value: unknown): unknown {\n if (typeof value !== \"string\") {\n return structuredClone(value);\n }\n const trimmed = value.trim();\n if (!trimmed) {\n return value;\n }\n if (!trimmed.startsWith(\"{\") && !trimmed.startsWith(\"[\")) {\n return value;\n }\n return tryParseJson(trimmed);\n}\n\nfunction parseLegacyToolCalls(value: unknown): LegacyToolCall[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((entry) => {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n return null;\n }\n const toolCall = entry as Record<string, unknown>;\n const id = normalizeString(toolCall.id);\n const rawFunction = toolCall.function;\n if (!id || !rawFunction || typeof rawFunction !== \"object\" || Array.isArray(rawFunction)) {\n return null;\n }\n const fn = rawFunction as Record<string, unknown>;\n const name = normalizeString(fn.name);\n const args = typeof fn.arguments === \"string\" ? fn.arguments : JSON.stringify(fn.arguments ?? {});\n if (!name) {\n return null;\n }\n return {\n id,\n type: \"function\" as const,\n function: {\n name,\n arguments: args\n }\n };\n })\n .filter((entry): entry is LegacyToolCall => entry !== null);\n}\n\nfunction createMessageId(sessionId: string, index: number, role: string, timestamp: string): string {\n return `${sessionId}:${role.trim().toLowerCase() || \"message\"}:${index}:${timestamp}`;\n}\n\nfunction resolveMessageId(params: {\n sessionId: string;\n index: number;\n role: string;\n timestamp: string;\n message: SessionMessage;\n}): string {\n const { index, message, role, sessionId, timestamp } = params;\n return normalizeString(message.ncp_message_id) ??\n createMessageId(sessionId, index, role, timestamp);\n}\n\nfunction isNcpMessagePart(value: unknown): value is NcpMessagePart {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value) && typeof (value as { type?: unknown }).type === \"string\";\n}\n\nfunction readStoredNcpParts(message: SessionMessage): NcpMessagePart[] | null {\n const rawParts = message.ncp_parts;\n if (!Array.isArray(rawParts)) {\n return null;\n }\n const parts = rawParts.filter((part): part is NcpMessagePart => isNcpMessagePart(part));\n if (parts.length !== rawParts.length) {\n return null;\n }\n return structuredClone(parts);\n}\n\nfunction readStoredNcpMetadata(message: SessionMessage): Record<string, unknown> | undefined {\n const rawMetadata = message.ncp_metadata;\n if (!rawMetadata || typeof rawMetadata !== \"object\" || Array.isArray(rawMetadata)) {\n return undefined;\n }\n return structuredClone(rawMetadata as Record<string, unknown>);\n}\n\nfunction buildAssistantMessage(params: { sessionId: string; index: number; message: SessionMessage }): NcpMessage {\n const { index, message, sessionId } = params;\n const timestamp = ensureIsoTimestamp(message.timestamp, new Date().toISOString());\n const replyTo =\n typeof message.reply_to === \"string\" && message.reply_to.trim().length > 0\n ? message.reply_to.trim()\n : undefined;\n const storedParts = readStoredNcpParts(message);\n if (storedParts) {\n return sanitizeAssistantReplyTags({\n id: resolveMessageId({ index, message, role: \"assistant\", sessionId, timestamp }),\n sessionId,\n role: \"assistant\",\n status: \"final\",\n timestamp,\n parts: storedParts,\n metadata: replyTo ? { reply_to: replyTo } : undefined,\n });\n }\n\n const toolCalls = parseLegacyToolCalls(message.tool_calls);\n const parts: NcpMessagePart[] = [...contentToParts(message.content)];\n if (typeof message.reasoning_content === \"string\") {\n parts.push({\n type: \"reasoning\",\n text: message.reasoning_content\n });\n }\n\n for (const toolCall of toolCalls) {\n parts.push({\n type: \"tool-invocation\",\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n state: \"call\",\n args: tryParseJson(toolCall.function.arguments)\n });\n }\n\n return sanitizeAssistantReplyTags({\n id: resolveMessageId({ index, message, role: \"assistant\", sessionId, timestamp }),\n sessionId,\n role: \"assistant\",\n status: \"final\",\n timestamp,\n parts,\n metadata: replyTo ? { reply_to: replyTo } : undefined,\n });\n}\n\nfunction buildGenericMessage(\n params: { sessionId: string; index: number; role: NcpMessage[\"role\"]; message: SessionMessage },\n): NcpMessage {\n const { index, message, role, sessionId } = params;\n const timestamp = ensureIsoTimestamp(message.timestamp, new Date().toISOString());\n const storedParts = readStoredNcpParts(message);\n const storedMetadata = readStoredNcpMetadata(message);\n if (storedParts) {\n return {\n id: resolveMessageId({ index, message, role, sessionId, timestamp }),\n sessionId,\n role,\n status: \"final\",\n timestamp,\n parts: storedParts,\n ...(storedMetadata ? { metadata: storedMetadata } : {}),\n };\n }\n return {\n id: resolveMessageId({ index, message, role, sessionId, timestamp }),\n sessionId,\n role,\n status: \"final\",\n timestamp,\n parts: contentToParts(message.content),\n ...(storedMetadata ? { metadata: storedMetadata } : {}),\n };\n}\n\nfunction attachToolResult(\n target: NcpMessage,\n toolCallId: string,\n result: unknown,\n toolName?: string,\n resultContentItems?: unknown,\n): NcpMessage {\n const normalizedResult = normalizeToolResultPayload(result);\n const normalizedContentItems = Array.isArray(resultContentItems)\n ? structuredClone(resultContentItems)\n : undefined;\n return {\n ...target,\n parts: target.parts.map((part) => {\n if (part.type !== \"tool-invocation\" || part.toolCallId !== toolCallId) {\n return part;\n }\n const alreadyHasResolvedResult =\n part.state === \"result\" && Object.prototype.hasOwnProperty.call(part, \"result\");\n if (alreadyHasResolvedResult) {\n return {\n ...part,\n ...(toolName ? { toolName } : {}),\n };\n }\n return {\n ...part,\n toolName: toolName ?? part.toolName,\n state: \"result\",\n result: normalizedResult,\n ...(normalizedContentItems ? { resultContentItems: normalizedContentItems } : {})\n };\n }),\n };\n}\n\nexport function toNcpMessages(sessionId: string, messages: SessionMessage[]): NcpMessage[] {\n const ncpMessages: NcpMessage[] = [];\n const assistantIndexByToolCallId = new Map<string, number>();\n\n messages.forEach((message, index) => {\n const role = normalizeString(message.role)?.toLowerCase() ?? \"assistant\";\n if (role === \"tool\") {\n const toolCallId = normalizeString(message.tool_call_id);\n if (toolCallId) {\n const assistantIndex = assistantIndexByToolCallId.get(toolCallId);\n if (assistantIndex !== undefined) {\n ncpMessages[assistantIndex] = attachToolResult(\n ncpMessages[assistantIndex] as NcpMessage,\n toolCallId,\n structuredClone(message.content),\n normalizeString(message.name) ?? undefined,\n message.ncp_tool_result_content_items\n );\n return;\n }\n }\n ncpMessages.push(\n buildGenericMessage({\n sessionId,\n index,\n role: \"tool\",\n message\n })\n );\n return;\n }\n\n if (role === \"assistant\") {\n const assistant = buildAssistantMessage({ sessionId, index, message });\n const assistantPosition = ncpMessages.push(assistant) - 1;\n for (const part of assistant.parts) {\n if (part.type === \"tool-invocation\" && part.toolCallId) {\n assistantIndexByToolCallId.set(part.toolCallId, assistantPosition);\n }\n }\n return;\n }\n\n const normalizedRole = (role === \"system\" || role === \"user\" || role === \"service\" ? role : \"user\") as NcpMessage[\"role\"];\n ncpMessages.push(\n buildGenericMessage({\n sessionId,\n index,\n role: normalizedRole,\n message\n })\n );\n });\n\n return ncpMessages;\n}\n\nexport function resolveLegacyEventType(message: SessionMessage): string {\n const role = normalizeString(message.role)?.toLowerCase() ?? \"\";\n if (role === \"assistant\" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0) {\n return \"assistant.tool_call\";\n }\n if (role === \"tool\") {\n return \"tool.result\";\n }\n if (role === \"assistant\") {\n return \"message.assistant\";\n }\n if (role === \"user\") {\n return \"message.user\";\n }\n if (role === \"system\") {\n return \"message.system\";\n }\n return `message.${role || \"other\"}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAGA,IAAa,eAAb,MAA0B;CACxB,mBAAmB;AACjB,QAAM,IAAI,MAAM,8CAA8C;;CAGhE,YAAY,YAAqB;AAE/B,QAAM,IAAI,MAAM,4CAA4C;;CAG9D,gBAAgB,YAAqB;AAEnC,QAAM,IAAI,MAAM,gDAAgD;;CAGlE,aAAa,UAAuB;AAElC,QAAM,IAAI,MAAM,6CAA6C;;CAG/D,eAAe,YAAqB;AAElC,QAAM,IAAI,MAAM,+CAA+C;;CAGjE,eAAe,SAAkB,YAAqB;AAGpD,QAAM,IAAI,MAAM,+CAA+C;;CAGjE,eAAe,SAAkB,YAAqB;AAGpD,QAAM,IAAI,MAAM,+CAA+C;;CAGjE,cAAc,SAAkB,WAAmB;AAGjD,QAAM,IAAI,MAAM,8CAA8C;;CAGhE,cAAc,SAAkB,WAAmB;AAGjD,QAAM,IAAI,MAAM,8CAA8C;;;;;ACyClE,SAAgBA,aAAW,OAAoC;AAE7D,SADgB,OAAO,UAAU,WAAW,MAAM,MAAM,GAAG,OACzC,KAAA;;AAGpB,SAAgB,YAAY,UAA0E;AACpG,QAAOA,aAAW,UAAU,SAAS,EAAE,aAAa,IAAIA,aAAW,UAAU,QAAQ,EAAE,aAAa;;AAGtG,SAAgB,gBAAgB,SAAkD;AAChF,QAAO,QAAQ,MAAM,SAAS,UAC3B,KAAK,SAAS,UAAU,KAAK,SAAS,eAAe,KAAK,SAAS,gBACpE,KAAK,KAAK,MAAM,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,GAAG,EAAE,CAC1C,CAAC,MAAM;;AAGX,SAAgB,mBACd,UACA,GAAG,MACiB;AACpB,QAAO,KAAK,KAAK,QAAQA,aAAW,WAAW,KAAK,CAAC,CAAC,KAAK,QAAQ;;AAGrE,SAAgB,YAAY,UAAgC,WAAuC;AACjG,QAAO;EAAE,GAAG;EAAU;EAAW,SAAS;GAAE,GAAG,SAAS;GAAS;GAAW;EAAE;;AAGhF,SAAgB,mBAAmB,OAAkC;AACnE,QAAO,MAAM,SAAS,aAAa,oBAAoB,MAAM,SAAS,aAAa,iBAAiB,MAAM,SAAS,aAAa;;AAGlI,SAAS,aAAa,SAAoC;CACxD,MAAM,WAAW,QAAQ,aAAa,aAAa;CACnD,MAAM,WAAW,SAAS,SAAS,KAAK,YAAY,gBAAgB,QAAQ,CAAC;AAC7E,KAAI,SAAS,oBAAoB,CAAC,SAAS,MAAM,YAAY,QAAQ,OAAO,SAAS,kBAAkB,GAAG,CACxG,UAAS,KAAK,gBAAgB,SAAS,iBAAiB,CAAC;AAE3D,QAAO;;AAGT,SAASC,0BAAwB,UAAgD;AAC/E,MAAK,MAAM,WAAW,UAAU;AAC9B,MAAI,QAAQ,SAAS,OACnB;AAEF,OAAK,MAAM,QAAQ,QAAQ,MACzB,KAAI,KAAK,SAAS,UAAU,KAAK,SAAS,aAAa;GACrD,MAAM,OAAOD,aAAW,KAAK,KAAK;AAClC,OAAI,KACF,QAAO,KAAK,SAAS,KAAK,GAAG,KAAK,MAAM,GAAG,GAAG,CAAC,OAAO;;;AAK9D,QAAO;;AAGT,SAAS,qBAAqB,QAGF;CAC1B,MAAM,EAAE,UAAU,aAAa;AAC/B,KAAIA,aAAW,SAAS,MAAM,CAC5B,QAAO;CAET,MAAM,QAAQC,0BAAwB,SAAS;AAC/C,QAAO,QAAQ;EAAE,GAAG;EAAU;EAAO,GAAG;;AAG1C,SAAgB,mBAAmB,SAAsB,WAAuC;CAC9F,MAAM,WAAW,aAAa,QAAQ;CACtC,MAAM,kBAAkB,QAAQ,iBAAiB,gBAAgB;CACjE,MAAM,WAAW,qBAAqB;EACpC,UAAU,EACR,GAAI,kBAAkB,gBAAgB,gBAAgB,GAAG,EAAE,EAC5D;EACD;EACD,CAAC;CACF,MAAM,UAAUD,aAAW,QAAQ,QAAQ,IAAI,YAAY,SAAS;AACpE,QAAO;EACL,WAAW,QAAQ;EACnB,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;EAC9B;EACA,WAAW;EACX;EACA;EACD;;AAGH,SAAgB,kBACd,OACA,UACkB;AAClB,KAAI,EAAE,aAAa,UAAU,CAAC,MAAM,WAAW,OAAO,MAAM,YAAY,SACtE,QAAO,gBAAgB,MAAM;CAE/B,MAAM,iBAAiB,QAAQ,SAAS,MAAM,KAC3C,MAAM,SAAS,aAAa,cAC3B,MAAM,SAAS,aAAa,eAC5B,MAAM,SAAS,aAAa,YAC5B,MAAM,SAAS,aAAa;AAChC,QAAO,gBAAgB;EACrB,GAAG;EACH,SAAS;GACP,GAAG,MAAM;GACT,WACE,eAAe,MAAM,WAAW,OAAO,MAAM,QAAQ,cAAc,WAC/D,MAAM,QAAQ,YACd,SAAS;GACf,GAAI,SAAS,kBACZ,EAAE,mBAAmB,MAAM,YAAY,OAAO,MAAM,QAAQ,kBAAkB,YAC3E,EAAE,eAAe,SAAS,eAAe,GACzC,EAAE;GACN,GAAI,iBAAiB,EAAE,OAAO,SAAS,OAAO,GAAG,EAAE;GACpD;EACF,CAAqB;;AAGxB,SAAS,0BAA0B,SAAsB,WAAsC;CAC7F,MAAM,sBAAsB,UAAU,MAAM;AAC5C,KAAI,CAAC,oBACH,QAAO;CAET,MAAM,WAAW,QAAQ,aAAa,aAAa,CAAC;AACpD,MAAK,IAAI,QAAQ,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EAC5D,MAAM,UAAU,SAAS;AACzB,MAAI,SAAS,OAAO,uBAAuB,QAAQ,SAAS,eAAe,QAAQ,WAAW,QAC5F,QAAO,gBAAgB,QAAQ;;AAGnC,QAAO;;AAGT,SAAgB,sBAAsB,QAOpC;CACA,MAAM,EAAE,OAAO,YAAY;AAC3B,KAAI,MAAM,SAAS,aAAa,kBAAkB;AAChD,MAAI,OAAO,qBACT,OAAM,IAAI,MAAM,+DAA+D,QAAQ,UAAU,IAAI;AAEvG,SAAO;GAAE,iBAAiB,CAAC,MAAM;GAAE,sBAAsB;GAAM;;AAEjE,KAAI,MAAM,SAAS,aAAa,aAAa;AAC3C,MAAI,OAAO,qBACT,QAAO;GAAE,iBAAiB,CAAC,MAAM;GAAE,sBAAsB;GAAM;EAEjE,MAAM,YAAY,MAAM,QAAQ,WAAW,MAAM;EACjD,MAAM,UAAU,YAAY,0BAA0B,SAAS,UAAU,GAAG;AAC5E,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,+DAA+D,QAAQ,UAAU,IAAI;EAEvG,MAAM,gBAAiB,MAAM,QAA8D;AAC3F,SAAO;GACL,iBAAiB,CACf;IACE,MAAM,aAAa;IACnB,SAAS;KACP,WAAW,QAAQ;KACnB;KACA,GAAI,gBAAgB,EAAE,eAAe,GAAG,EAAE;KAC3C;IACF,EACD,MACD;GACD,sBAAsB;GACvB;;AAEH,QAAO;EACL,iBAAiB,CAAC,MAAM;EACxB,sBAAsB,OAAO;EAC9B;;AAGH,SAAgB,eAAe,SAAgD;AAC7E,QAAQ,QAAqD,WAAW;;AAG1E,SAAgB,iBACd,QACA,UACuB;CACvB,IAAI,WAAW;CACf,IAAI,SAAS;AACb,QAAO,IAAI,SAAuB,SAAS,WAAW;EACpD,MAAM,oBAA0B;AAC9B,OAAI,SACF;AAEF,cAAW;AACX,WAAQ,OAAO;;AAEjB,GAAM,YAAY;AAChB,OAAI;AACF,eAAW,MAAM,SAAS,OACxB,KAAI,MAAM,SAAS,aAAa,YAAY;AAC1C,cAAS;MACP,GAAG;MACH,oBAAoB,MAAM,QAAQ,aAAa;MAC/C,OAAO,MAAM,QAAQ,SAAS;MAC/B;AACD,kBAAa;;AAGjB,iBAAa;YACN,OAAO;AACd,QAAI,CAAC,SACH,QAAO,MAAM;;MAGf;GACJ;;;;AC9RJ,SAAgB,qBAAqB,QAKlB;CACjB,MAAM,EAAE,YAAY,QAAQ,OAAO,OAAO,aAAa;CACvD,MAAM,QAAQ,iBAAiB,SAAS;AACxC,QAAO;EACL,SAAS;EACT,YAAY,+BAAc,IAAI,MAAM,EAAC,aAAa;EAClD;EACA,OAAO,uBAAuB,MAAM;EACpC;EACA,SAAS,qBAAqB,MAAM;EACrC;;AAGH,SAAgB,iBACd,OACwB;CACxB,MAAM,OAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE;AAChD,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,MAAM,IAAI,QAAQ,EAClE;AAEF,OAAK,OAAO,KAAK,MAAM,MAAM;;AAE/B,QAAO;;AAGT,SAAgB,qBAAqB,OAAwC;AAC3E,QAAO,OAAO,KAAK,MAAM,CAAC,SAAS;;AAGrC,SAAgB,qBACd,OACiB;CACjB,MAAM,eAAe,MAAM,iBAAiB,MAAM,gBAAgB;CAClE,MAAM,mBAAmB,MAAM,qBAAqB,MAAM,iBAAiB;CAC3E,MAAM,cAAc,MAAM,gBAAiB,eAAe;CAC1D,MAAM,kBAAkB,OAAO,KAAK,MAAM,CAAC,QAAQ,QACjD,IAAI,SAAS,gBAAgB,CAC9B;CACD,MAAM,eAAe,gBAAgB,QAClC,KAAK,QAAQ,KAAK,IAAI,KAAK,MAAM,QAAQ,EAAE,EAC5C,EACD;AACD,QAAO;EACL;EACA;EACA;EACA;EACA,UAAU,eAAe;EACzB;EACD;;AAGH,SAAgB,uBACd,OACe;AACf,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;;;AC3ExC,IAAa,gBAAb,MAA2B;CACzB,YAAY,UAAiD,EAAE,EAAE;AAApC,OAAA,UAAA;;CAE7B,IAAI,eAAuB;AACzB,SAAO,KAAK,QAAQ,gBAAgB,QAAQ,YAAY,EAAE,OAAO,iBAAiB;;CAGpF,IAAI,cAAsB;AACxB,SAAO,KAAK,QAAQ,eAAe,QAAQ,YAAY,EAAE,QAAQ,kBAAkB;;CAGrF,qBAA4C;AAC1C,MAAI,CAAC,WAAW,KAAK,aAAa,CAChC,QAAO;AAET,MAAI;GACF,MAAM,MAAM,aAAa,KAAK,cAAc,QAAQ;AACpD,UAAO,KAAK,MAAM,IAAI;UAChB;AACN,UAAO;;;CAIX,iBAAiB,aAAmC;AAClD,YAAU,QAAQ,KAAK,aAAa,EAAE,EAAE,WAAW,MAAM,CAAC;AAC1D,gBAAc,KAAK,cAAc,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;;CAGrE,sBAA4B;AAC1B,MAAI,WAAW,KAAK,aAAa,CAC/B,QAAO,KAAK,cAAc,EAAE,OAAO,MAAM,CAAC;;CAI9C,oBAAsC;AACpC,MAAI,CAAC,WAAW,KAAK,YAAY,CAC/B,QAAO,EAAE;AAEX,MAAI;AAEF,UADY,aAAa,KAAK,aAAa,QAAQ,CAEhD,MAAM,KAAK,CACX,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,EAAE,CACjC,SAAS,SAAS;AACjB,QAAI;AACF,YAAO,CAAC,KAAK,MAAM,KAAK,CAAmB;YACrC;AACN,YAAO,EAAE;;KAEX;UACE;AACN,UAAO,EAAE;;;CAIb,iBAAiB,WAAiC;AAChD,YAAU,QAAQ,KAAK,YAAY,EAAE,EAAE,WAAW,MAAM,CAAC;AACzD,iBAAe,KAAK,aAAa,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI;;CAGjE,qBAA2B;AACzB,MAAI,WAAW,KAAK,YAAY,CAC9B,QAAO,KAAK,aAAa,EAAE,OAAO,MAAM,CAAC;;;;;ACzC/C,IAAM,6BAAN,MAA+D;CAC7D,YACE,UACA,SACA,QACA;AAHiB,OAAA,WAAA;AACA,OAAA,UAAA;AACA,OAAA,SAAA;;CAGnB,OAAO,UAA0B;AAC/B,SAAO,KAAK,SAAS,IAAI,MAAM;;CAGjC,OAAO,OAAO,WAA+B;EAC3C,MAAM,WAAW,MAAM,KAAK,SAAS,KAAK,OAAO;AACjD,OAAK,QAAQ,OAAO;GAClB,QAAQ,KAAK;GACb,OAAO,OAAO,SAAS;GACvB,OAAO,SAAS;GACjB,CAAC;AACF,SAAO;;CAGT,aAAa,iBAEX,QACA;AACA,aAAW,MAAM,SAAS,KAAK,SAAS,WAAW,OAAO,EAAE;AAC1D,OAAI,MAAM,SAAS,OACjB,MAAK,QAAQ,OAAO;IAClB,QAAQ,KAAK;IACb,OAAO,OAAO,SAAS;IACvB,OAAO,MAAM,SAAS;IACvB,CAAC;AAEJ,SAAM;;;;AAKZ,IAAa,kBAAb,MAA6B;CAC3B;CAEA,YAAY,UAAkC,EAAE,EAAE;AAChD,OAAK,QAAQ,QAAQ,SAAS,IAAI,eAAe;;CAGnD,IAAI,eAAuB;AACzB,SAAO,KAAK,MAAM;;CAGpB,IAAI,cAAsB;AACxB,SAAO,KAAK,MAAM;;CAGpB,0BACE,iBACA,WACuB;AACvB,SAAO,IAAI,2BAA2B,iBAAiB,MAAM,OAAO;;CAGtE,UAAU,WAKmB;EAC3B,MAAM,SAAS,qBAAqB,OAAO;AAC3C,MAAI,CAAC,qBAAqB,OAAO,MAAM,CACrC,QAAO;AAET,OAAK,MAAM,cAAc,OAAO;AAChC,OAAK,MAAM,cAAc,OAAO;AAChC,SAAO;;CAGT,oBAA2C;AACzC,SAAO,KAAK,MAAM,cAAc;;CAGlC,cAAc,UAA8C;EAC1D,MAAM,UAAU,KAAK,MAAM,aAAa;EACxC,MAAM,gBAAgB,KAAK,oBAAoB,MAAM;AACrD,SAAO,QAAQ,MAAM,CAAC,cAAc,CAAC,SAAS;;CAGhD,uBAAuB,UAAoC;AACzD,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,IAAI,QAAQ,EACjE,QAAO,KAAK,MAAM,MAAM;AAE1B,MAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,GAAG;GACxD,MAAM,SAAS,OAAO,MAAM;AAC5B,OAAI,OAAO,SAAS,OAAO,IAAI,SAAS,EACtC,QAAO,KAAK,MAAM,OAAO;;AAG7B,SAAO;;CAGT,iBAAgC;EAC9B,MAAM,UAAU,KAAK,MAAM,aAAa;EACxC,MAAM,0BAAU,IAAI,KAAqB;EACzC,MAAM,yBAAS,IAAI,KAAqB;EACxC,IAAI,oBAAoB;EACxB,IAAI,wBAAwB;EAC5B,IAAI,cAAc;EAClB,IAAI,oBAAoB;EACxB,IAAI,kBAAkB;EACtB,IAAI,mBAAmB;EACvB,IAAI,yBAAyB;AAE7B,OAAK,MAAM,UAAU,SAAS;AAE5B,OADiB,OAAO,KAAK,OAAO,MAAM,CAAC,SAAS,EAElD,qBAAoB;AAEtB,wBAAqB,OAAO,QAAQ;AACpC,4BAAyB,OAAO,QAAQ;AACxC,kBAAe,OAAO,QAAQ;AAC9B,wBAAqB,OAAO,QAAQ;AACpC,OAAI,OAAO,QAAQ,eAAe,EAChC,2BAA0B;AAE5B,OAAI,OAAO,QAAQ,SACjB,oBAAmB;AAErB,QAAK,YAAY,SAAS,OAAO,OAAO;AACxC,QAAK,YAAY,QAAQ,OAAO,SAAS,UAAU;;AAGrD,SAAO;GACL,cAAc,QAAQ;GACtB;GACA,uBAAuB,QAAQ,SAAS;GACxC;GACA,kBAAkB,QAAQ,IAAI,cAAc;GAC5C,kBAAkB,QAAQ,GAAG,GAAG,EAAE,cAAc;GAChD;GACA;GACA;GACA;GACA;GACA,cAAc,yBAAyB,IAAI,kBAAkB,yBAAyB;GACtF,gBAAgB,oBAAoB,IAAI,oBAAoB,oBAAoB;GAChF,SAAS,KAAK,eAAe,QAAQ;GACrC,QAAQ,KAAK,eAAe,OAAO;GACpC;;CAGH,eAAgC,KAA0B,UAAwB;AAChF,MAAI,IAAI,QAAQ,IAAI,IAAI,MAAM,IAAI,KAAK,EAAE;;CAG3C,kBAAmC,QAAsE;AACvG,SAAO,CAAC,GAAG,IAAI,SAAS,CAAC,CACtB,KAAK,CAAC,OAAO,YAAY;GAAE;GAAO;GAAO,EAAE,CAC3C,MAAM,MAAM,UAAU;AACrB,OAAI,MAAM,UAAU,KAAK,MACvB,QAAO,MAAM,QAAQ,KAAK;AAE5B,UAAO,KAAK,MAAM,cAAc,MAAM,MAAM;IAC5C;;;;;ACvLR,SAAgBE,kBAAgB,OAA+B;AAC7D,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;AAGxC,SAAgBC,WAAS,OAAkD;AACzE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAwF7E,SAAgB,mBAAmB,OAAgB,UAA0B;AAC3E,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,YAAY,KAAK,MAAM,MAAM;AACnC,KAAI,CAAC,OAAO,SAAS,UAAU,CAC7B,QAAO;AAET,QAAO,IAAI,KAAK,UAAU,CAAC,aAAa;;AAG1C,SAAS,kBAAkB,MAAuB;AAChD,KAAI,OAAO,SAAS,SAClB,QAAO;AAET,QAAO,KAAK,UAAU,QAAQ,EAAE,CAAC;;AAGnC,SAAS,uBAAuB,OAAkC;CAChE,MAAM,OAAO,MACV,OAAOC,iBAAe,CACtB,KAAK,SAAS,KAAK,KAAK,CACxB,KAAK,GAAG;AACX,KAAI,KAAK,SAAS,EAChB,QAAO;AAET,KAAI,MAAM,WAAW,EACnB,QAAO;AAET,QAAO,gBAAgB,MAAM;;AAG/B,SAAgB,0BAA0B,SAAyC;AACjF,KAAI,CAAC,QACH,QAAO;AAGT,SAD0B,QAAQ,SAAS,cAAc,2BAA2B,QAAQ,GAAG,SACtE,MACtB,OAAOA,iBAAe,CACtB,KAAK,SAAS,KAAK,KAAK,CACxB,KAAK,GAAG;;AAGb,SAASA,iBAAe,MAAuF;AAC7G,QAAO,KAAK,SAAS,UAAU,KAAK,SAAS;;AA8C/C,SAAgB,uBACd,OACA,UAAqC,EAAE,EAC9B;CACT,MAAM,UAAU,oBAAoB,OAAO,EACzC,YAAY,QAAQ,YACrB,CAAC;AACF,KAAI,YAAY,GACd,QAAO,uBAAuB,MAAM;AAEtC,QAAO;;AA6BT,SAAS,6BAA6B,SAAqB,WAAqC;CAC9F,MAAM,cAAc,0BAA0B,QAAQ;CACtD,MAAM,iBAAiB,QAAQ,MAAM,QAClC,SAAiE,KAAK,SAAS,YACjF;CACD,MAAM,mBAAmB,eAAe,KAAK,SAAS,KAAK,KAAK,CAAC,KAAK,GAAG;CACzE,MAAM,kBAAkB,QAAQ,MAAM,QACnC,SAAwC,KAAK,SAAS,kBACxD;CAED,MAAM,mBAAmC;EACvC,MAAM;EACN,SAAS;EACT;EACA,gBAAgB,QAAQ;EACxB,WAAW,gBAAgB,QAAQ,MAAM;EAC1C;AACD,KAAI,OAAO,QAAQ,UAAU,aAAa,YAAY,QAAQ,SAAS,SAAS,MAAM,CAAC,SAAS,EAC9F,kBAAiB,WAAW,QAAQ,SAAS,SAAS,MAAM;AAE9D,KAAI,eAAe,SAAS,EAC1B,kBAAiB,oBAAoB;AAEvC,KAAI,gBAAgB,SAAS,EAC3B,kBAAiB,aAAa,gBAAgB,KAAK,gBAAgB,WAAW;EAC5E,IAAI,eAAe,cAAc,GAAG,QAAQ,GAAG,QAAQ;EACvD,MAAM;EACN,UAAU;GACR,MAAM,eAAe;GACrB,WAAW,kBAAkB,eAAe,KAAK;GAClD;EACF,EAAE;CAGL,MAAM,WAA6B,CAAC,iBAAiB;AACrD,MAAK,MAAM,kBAAkB,iBAAiB;AAC5C,MAAI,eAAe,UAAU,SAC3B;AAEF,WAAS,KAAK;GACZ,MAAM;GACN,MAAM,eAAe;GACrB,cAAc,eAAe;GAC7B,SACE,OAAO,eAAe,WAAW,WAC7B,eAAe,SACf,KAAK,UAAU,eAAe,UAAU,KAAK;GACnD,GAAI,eAAe,qBACf,EAAE,+BAA+B,gBAAgB,eAAe,mBAAmB,EAAE,GACrF,EAAE;GACN;GACA,gBAAgB,QAAQ;GACzB,CAAC;;AAEJ,QAAO;;AAGT,SAAS,+BACP,SACA,WACA,SACgB;AAEhB,QAAO;EACL,MAFW,QAAQ,SAAS,aAAa,QAAQ,gBAAgB,WAAW,WAAW,QAAQ;EAG/F,SAAS,uBAAuB,QAAQ,OAAO,QAAQ;EACvD;EACA,gBAAgB,QAAQ;EACxB,WAAW,gBAAgB,QAAQ,MAAM;EACzC,GAAI,QAAQ,WAAW,EAAE,cAAc,gBAAgB,QAAQ,SAAS,EAAE,GAAG,EAAE;EAChF;;AAGH,SAAgB,iBACd,UACA,UAAqC,EAAE,EACrB;CAClB,MAAM,iBAAmC,EAAE;AAE3C,MAAK,MAAM,cAAc,UAAU;EACjC,MAAM,UAAU,WAAW,SAAS,cAAc,2BAA2B,WAAW,GAAG;EAC3F,MAAM,YAAY,mBAAmB,QAAQ,4BAAW,IAAI,MAAM,EAAC,aAAa,CAAC;AAEjF,MAAI,QAAQ,SAAS,aAAa;AAChC,kBAAe,KAAK,GAAG,6BAA6B,SAAS,UAAU,CAAC;AACxE;;AAGF,iBAAe,KAAK,+BAA+B,SAAS,WAAW,QAAQ,CAAC;;AAGlF,QAAO;;;;AC9TT,SAAS,eAAe,MAAuF;AAC7G,QAAO,KAAK,SAAS,UAAU,KAAK,SAAS;;AAG/C,SAAS,uBAAuB,OAAmC;AACjE,QAAO,MACJ,KAAK,MAAM,UAAW,eAAe,KAAK,GAAG,QAAQ,GAAI,CACzD,QAAQ,UAAU,SAAS,EAAE;;AAGlC,SAAS,wCACP,OACA,iBACA,eACkB;CAClB,MAAM,YAAY,gBAAgB,MAAM;CACxC,MAAM,iBAAiB,gBAAgB;CACvC,MAAM,gBAAgB,UAAU;AAChC,KAAI,iBAAiB,eAAe,cAAc,CAChD,eAAc,OAAO;AAGvB,QAAO,UAAU,QAAQ,MAAM,UAAU;AACvC,MAAI,CAAC,eAAe,KAAK,CACvB,QAAO;AAET,SAAO,UAAU,kBAAkB,KAAK,KAAK,SAAS;GACtD;;AAGJ,SAAS,gCAAgC,QAKpB;CACnB,MAAM,EAAE,OAAO,QAAQ,QAAQ,oBAAoB;CACnD,MAAM,YAAY,gBAAgB,MAAM;CACxC,MAAM,iBAAiB,gBAAgB;CACvC,MAAM,gBAAgB,gBAAgB,gBAAgB,SAAS;AAE/D,MAAK,MAAM,SAAS,iBAAiB;EACnC,MAAM,OAAO,UAAU;AACvB,MAAI,CAAC,QAAQ,CAAC,eAAe,KAAK,CAChC;AAEF,MAAI,UAAU,eACZ,MAAK,OAAO,GAAG,SAAS,KAAK;AAE/B,MAAI,UAAU,cACZ,MAAK,OAAO,GAAG,KAAK,OAAO;;AAI/B,QAAO;;AAGT,SAAS,2BAA2B,QAIf;CACnB,MAAM,EAAE,eAAe,SAAS,iBAAiB;CACjD,MAAM,QAAQ,SAAS,SAAS,EAAE;AAClC,KAAI,MAAM,WAAW,EACnB,QAAO,cAAc,SAAS,IAAI,CAAC;EAAE,MAAM;EAAQ,MAAM;EAAe,CAAC,GAAG,EAAE;CAGhF,MAAM,kBAAkB,uBAAuB,MAAM;AACrD,KAAI,gBAAgB,WAAW,EAC7B,QAAO,cAAc,SAAS,IAC1B,CAAC;EAAE,MAAM;EAAQ,MAAM;EAAe,EAAE,GAAG,gBAAgB,MAAM,CAAC,GAClE,gBAAgB,MAAM;AAG5B,KAAI,kBAAkB,aACpB,QAAO,gBAAgB,MAAM;CAG/B,MAAM,oBAAoB,cAAc,QAAQ,aAAa;AAC7D,KAAI,aAAa,WAAW,KAAK,oBAAoB,EACnD,QAAO,wCAAwC,OAAO,iBAAiB,cAAc;AAGvF,QAAO,gCAAgC;EACrC;EACA;EACA,QAAQ,cAAc,MAAM,GAAG,kBAAkB;EACjD,QAAQ,cAAc,MAAM,oBAAoB,aAAa,OAAO;EACrE,CAAC;;AAGJ,SAAgB,sBAAsB,OAAiD;AACrF,QACE,MAAM,SACH,OAAO,CACP,SAAS,CACT,MAAM,YAAY,QAAQ,SAAS,OAAO,IAC7C,MAAM,SAAS,MAAM,SAAS,SAAS;;AAI3C,SAAgB,sBAAsB,QASpC;CACA,MAAM,EAAE,YAAY,cAAc,cAAc,UAAU;CAC1D,MAAM,oBAAoB,sBAAsB,MAAM;CACtD,MAAM,eAAe,0BAA0B,kBAAkB;CAUjE,MAAM,eAAe,2BAA2B;EAC9C,SAAS;EACT,eAXoB,aAAa;GACjC,MAAM;GACN,WAAW,IAAI,KACb,mBACE,mBAAmB,4BACnB,IAAI,MAAM,EAAC,aAAa,CACzB,CACF;GACF,CAAC;EAIA;EACD,CAAC;AAEF,QAAO;EACL,aAAa,mBAAmB,SAAS,WAAW,WAAW;EAC/D,oBAAoB,uBAAuB,cAAc,EACvD,YACD,CAAC;EACF,gBAAgB;EACjB;;;;AC7IH,MAAa,sCAAsC;AACnD,MAAa,mCAAmC;AAoBhD,SAAS,qBAAqB,SAAsF;CAClH,MAAM,cAAc,SAAS;AAC7B,KAAI,CAAC,eAAe,OAAO,gBAAgB,YAAY,MAAM,QAAQ,YAAY,CAC/E,QAAO;CAET,MAAM,WAAW;AACjB,KAAI,SAAA,8BAAA,qBACF,QAAO;CAET,MAAM,aACJ,SAAS,cAAc,OAAO,SAAS,eAAe,YAAY,CAAC,MAAM,QAAQ,SAAS,WAAW,GAChG,SAAS,aACV;AACN,KAAI,CAAC,WACH,QAAO;AAET,QAAO;GACJ,sCAAsC;EACvC;EACD;;AAGH,SAAS,qBAAqB,YAAiE;AAC7F,QAAO;EACL,MAAM;EACN,SACE,WAAW,WAAW,gBAClB,cACA;EACN,WAAW,WAAW;EACtB,WAAW,CACT;GACE,MAAM;GACN,MACE,WAAW,WAAW,gBAClB,cACA;GACP,CACF;EACD,cAAc;IACX,sCAAsC;GACvC;GACD;EACF;;AAGH,SAAgB,yCAAyC,QAG1C;CACb,MAAM,EAAE,YAAY,cAAc;CAClC,MAAM,OACJ,WAAW,WAAW,gBAClB,cACA;AACN,QAAO;EACL,IAAI,GAAG,UAAU,8BAA8B,WAAW;EAC1D;EACA,MAAM;EACN,QAAQ;EACR,WAAW,WAAW;EACtB,OAAO,CAAC;GAAE,MAAM;GAAQ;GAAM,CAAC;EAC/B,UAAU;IACP,sCAAsC;GACvC;GACD;EACF;;AAGH,SAAgB,uCAAuC,QAI9C;CACP,MAAM,EAAE,YAAY,yBAAyB,EAAE,EAAE,YAAY;CAC7D,MAAM,cAAc,qBAAqB,WAAW;AACpD,MAAK,IAAI,QAAQ,QAAQ,OAAO,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EAClE,MAAM,QAAQ,QAAQ,OAAO;EAK7B,MAAM,WAAW,qBAHf,OAAO,MAAM,WAAW,OAAO,MAAM,KAAK,YAAY,YAAY,CAAC,MAAM,QAAQ,MAAM,KAAK,QAAQ,GAC/F,MAAM,KAAK,UACZ,KACwC;AAC9C,MAAI,CAAC,SACH;AAEF,QAAM,YAAY,WAAW;AAC7B,QAAM,KAAK,UAAU;AACrB,UAAQ,WAAW,QAAQ,SAAS,KAAK,SAAS;AAEhD,UADqB,qBAAqB,KAAK,EAC1B,WAAW,OAAO,SAAS,WAAW,KAAK,cAAc;IAC9E;AACF,UAAQ,YAAY,IAAI,KAAK,WAAW,UAAU;AAClD;;CAGF,MAAM,QAAsB;EAC1B,KAAK,QAAQ;EACb,MAAM;EACN,WAAW,WAAW;EACtB,MAAM,EACJ,SAAS,aACV;EACF;AACD,SAAQ,WAAW;CACnB,MAAM,eAAe,IAAI,IAAI,uBAAuB;CACpD,MAAM,eAAe,QAAQ,SAAS,WACnC,YAAY,OAAO,QAAQ,mBAAmB,YAAY,aAAa,IAAI,QAAQ,eAAe,CACpG;AACD,KAAI,gBAAgB,EAClB,SAAQ,SAAS,OAAO,cAAc,GAAG,YAAY;KAErD,SAAQ,SAAS,KAAK,YAAY;CAEpC,MAAM,aAAa,QAAQ,OAAO,WAAW,mBAAmB;EAC9D,MAAM,UACJ,gBAAgB,MAAM,WAAW,OAAO,eAAe,KAAK,YAAY,YAAY,CAAC,MAAM,QAAQ,eAAe,KAAK,QAAQ,GAC1H,eAAe,KAAK,UACrB;AACN,SAAO,OAAO,SAAS,mBAAmB,YAAY,aAAa,IAAI,QAAQ,eAAe;GAC9F;AACF,KAAI,cAAc,EAChB,SAAQ,OAAO,OAAO,YAAY,GAAG,MAAM;KAE3C,SAAQ,OAAO,KAAK,MAAM;AAE5B,SAAQ,YAAY,IAAI,KAAK,WAAW,UAAU;;AAGpD,SAAgB,mCAAmC,SAAyF;AAC1I,QAAO,SAAS,WAAW,yCAAyC;;;;ACtJtE,SAAS,sBAAsB,SAAoC;CACjE,MAAM,WAAW,QAAQ;AACzB,KAAI,WAAA,8BAAA,qBACF,QAAO;AAGT,QADmB,0CAA0C,SAAS,WAAW,EAC9D,WAAW;;AAGhC,SAAgB,wCAAwC,QAGvC;CACf,MAAM,EAAE,WAAW,oBAAoB;CACvC,IAAI,kBAAkB;CACtB,IAAI,UAAU;AACd,MAAK,IAAI,QAAQ,gBAAgB,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;EACnE,MAAM,mBAAmB,sBAAsB,gBAAgB,OAAqB;AACpF,MAAI,CAAC,iBACH;AAEF,oBAAkB;AAClB,YAAU;AACV;;AAGF,KAAI,kBAAkB,EACpB,QAAO,gBACJ,QAAQ,YAAY,CAAC,sBAAsB,QAAQ,CAAC,CACpD,KAAK,YAAY,gBAAgB,QAAQ,CAAC;AAG/C,QAAO,CACL;EACE,IAAI,GAAG,UAAU,8BAA8B,gBAAgB,kBAAkB,MAAM;EACvF;EACA,MAAM;EACN,QAAQ;EACR,WAAW,gBAAgB,kBAAkB,8BAAa,IAAI,MAAM,EAAC,aAAa;EAClF,OAAO,CAAC;GAAE,MAAM;GAAQ,MAAM;GAAS,CAAC;EACzC,EACD,GAAG,gBACA,MAAM,kBAAkB,EAAE,CAC1B,QAAQ,YAAY,CAAC,sBAAsB,QAAQ,CAAC,CACpD,KAAK,YAAY,gBAAgB,QAAQ,CAAC,CAC9C;;;;ACMH,MAAM,qBAAqB;AAC3B,MAAM,2BAA2B;AAEjC,SAASC,uBAAqB,UAAkD;AAC9E,QAAOC,kBAAgB,SAAS,SAAS,EAAE,aAAa,IAAIA,kBAAgB,SAAS,QAAQ,EAAE,aAAa,IAAI;;AAGlH,SAAS,yBAAyB,QAIJ;CAC5B,MAAM,EAAE,QAAQ,iBAAiB,kBAAkB;CACnD,MAAM,EAAE,aAAa,OAAO;CAC5B,MAAM,iBAAiB,6BAA6B,OAAO;CAK3D,MAAM,UACJ,0BAA0B,QAJ1BA,kBAAgB,cAAc,EAAE,aAAa,IAC7CD,uBAAqB,gBAAgB,IACrC,eAE0C,IAC1C,0BAA0B,QAAQ,eAAe;AACnD,QAAO;EACL,eAAe,SAAS,iBAAiB,SAAS;EAClD,OAAO,SAAS,SAAS,SAAS;EAClC,uBAAuB,2BAA2B,6BAA6B;GAC7E,eAAe,SAAS,iBAAiB,SAAS;GAClD,iCAAiC,SAAS,yBAAyB,SAAS;GAC7E,CAAC;EACH;;AAGH,SAAS,mBAAmB,QAGX;CACf,MAAM,WAAW,OAAO,gBAAgB,KAAK,YAAY,gBAAgB,QAAQ,CAAC;CAClF,MAAM,OAAO,IAAI,IAAI,SAAS,KAAK,YAAY,QAAQ,GAAG,CAAC;AAC3D,MAAK,MAAM,WAAW,OAAO,eAAe;AAC1C,MAAI,KAAK,IAAI,QAAQ,GAAG,CACtB;AAEF,WAAS,KAAK,gBAAgB,QAAQ,CAAC;;AAEzC,QAAO;;AAGT,SAAS,0BAA0B,UAAsD;CACvF,MAAM,OAAO,KAAK,UAAU,UAAU,MAAM,EAAE;AAC9C,KAAI,KAAK,UAAU,yBACjB,QAAO;AAET,QAAO,GAAG,KAAK,MAAM,GAAG,yBAAyB,CAAC,SAAS,CAAC;;AAG9D,SAAS,qCAAqC,QAIpB;CACxB,MAAM,EAAE,QAAQ,YAAY,uBAAuB;AACnD,QAAO,2BAA2B;EAChC,mBAAmB,OAAO;EAC1B;EACA,yBAAyB,OAAO;EAChC,qBAAqB,OAAO;EAC5B,0BAA0B,OAAO;EACjC,uBAAuB,OAAO;EAC9B,sBAAsB,OAAO;EAC7B;EACA,4BAA4B,aAAa,OAAO,kBAAkB,KAAA;EACnE,CAAC;;AAGJ,SAAS,sCACP,4BACA,QAOuB;CACvB,MAAM,EAAE,YAAY,eAAe,uBAAuB,WAAW,oBAAoB;CACzF,MAAM,yBAAyB,gBAAgB,QAC5C,YAAY,CAAC,mCAAmC,QAAQ,CAC1D;CAOD,MAAM,WAAW,iBANS,aACtB,wCAAwC;EACtC;EACA;EACD,CAAC,GACF,uBACgD;AAMpD,QAAO,qCAAqC;EAC1C,QANa,2BAA2B,SAAS;GACjD;GACA;GACA;GACD,CAAC;EAGA;EACA,oBAAoB;EACrB,CAAC;;AAGJ,IAAa,oCAAb,MAA+C;CAC7C,oBAAqC,IAAI,0BAA0B;CACnE,6BAA8C,IAAI,4BAA4B;CAE9E,YACE,SAIA;AAJiB,OAAA,UAAA;;CAMnB,WAAW,WAMyB;EAClC,MAAM,EACJ,iBACA,WACA,iBACA,eACA,mBACE;EACJ,MAAM,UAAU,yBAAyB;GACvC,QAAQ,KAAK,QAAQ,cAAc,YAAY;GAC/C;GACA;GACD,CAAC;EACF,MAAM,qBAAqB,0CACzB,eAAe,iCAChB;AACD,SAAO,sCAAsC,KAAK,4BAA4B;GAC5E,YAAY;GACZ,eAAe,QAAQ;GACvB,uBAAuB,QAAQ;GAC/B;GACA;GACD,CAAC;;CAGJ,SAAS,WAOoC;EAC3C,MAAM,EACJ,eACA,iBACA,WACA,iBACA,eACA,mBACE;EACJ,MAAM,UAAU,yBAAyB;GACvC,QAAQ,KAAK,QAAQ,cAAc,YAAY;GAC/C;GACA;GACD,CAAC;EACF,MAAM,EAAE,eAAe,0BAA0B;EACjD,MAAM,cAAc,mBAAmB;GACrC;GACA;GACD,CAAC;EACF,MAAM,yBAAyB,YAAY,QACxC,YAAY,CAAC,mCAAmC,QAAQ,CAC1D;EACD,MAAM,qBAAqB,0CACzB,eAAe,iCAChB;EAOD,MAAM,WAAW,iBANS,qBACtB,wCAAwC;GACtC;GACA,iBAAiB;GAClB,CAAC,GACF,uBACgD;EACpD,MAAM,SAAS,KAAK,2BAA2B,SAAS;GACtD;GACA;GACA;GACD,CAAC;EACF,MAAM,OAAO,sBAAsB,CAAC,OAAO,gBACvC,OACA,KAAK,kBAAkB,qBAAqB;GAC1C,UAAU,OAAO;GACjB;GACA,2BAA2B,OAAO;GACnC,CAAC;EACN,MAAM,aAAa,OACf;GACE,GAAG,qCACD,eAAe,iCAChB;GACD,qBAAqB,KAAK,gBAAgB;GAC1C,4BAA4B,KAAK,gBAAgB;GACjD,yBAAyB,KAAK;GAC9B,0BAA0B,OAAO;GAClC,GACD;AAOJ,SAAO;GACL,eANoB,qCAAqC;IACzD;IACA;IACA,oBAAoB;IACrB,CAAC;GAGA,eAAe,QAAQ,aACnB,GAAG,kCAAkC,YAAY,GACjD,EAAE;GACN,iBAAiB;GACjB,iBAAiB,QAAQ,aACrB,yCAAyC;IACvC;IACA;IACD,CAAC,GACF;GACJ,mBAAmB,QAAQ,aACvB;IACE;IACA;IACA,OAAO,QAAQ;IACf;IACA;IACA;IACA,iBAAiB;IAClB,GACD;GACL;;CAGH,SAAS,OACP,YAC8C;EAC9C,MAAM,YAAY,MAAM,KAAK,kBAAkB,6BAA6B;GAC1E,eAAe,QAAQ;GACvB,MAAM,QAAQ;GACd,iBAAiB,OAAO,EAAE,eACxB,MAAM,KAAK,gBAAgB;IACzB;IACA,OAAO,QAAQ;IAChB,CAAC;GACL,CAAC;EACF,MAAM,sBAAsB,UAAU;AACtC,MAAI,CAAC,oBACH,OAAM,IAAI,MAAM,+DAA+D;EAEjF,MAAM,aAAa;GACjB,GAAG;GACH,IAAI,QAAQ,WAAW;GACvB,WAAW,QAAQ,WAAW;GAC9B,QAAQ;GACT;AAWD,SAAO;GACL,eANoB,qCAAqC;IACzD,QANa,KAAK,2BAA2B,SAAS;KACtD,UAAU,UAAU;KACpB,eAAe,QAAQ;KACvB,uBAAuB,QAAQ;KAChC,CAAC;IAGA;IACA,oBAAoB,QAAQ;IAC7B,CAAC;GAGA,eAAe,GACZ,kCAAkC,YACpC;GACD,iBAAiB,QAAQ;GACzB,iBAAiB,yCAAyC;IACxD,WAAW,QAAQ;IACnB;IACD,CAAC;GACH;;CAGH,kBAA0B,OAAO,WAGV;AACrB,MAAI,CAAC,KAAK,QAAQ,gBAChB,OAAM,IAAI,MAAM,oEAAoE;EAEtF,MAAM,EAAE,UAAU,UAAU;EA0B5B,MAAM,WAzBW,MAAM,KAAK,QAAQ,gBAAgB,KAAK;GACvD;GACA,WAAW;GACX,UAAU,CACR;IACE,MAAM;IACN,SAAS;KACP;KACA;KACA;KACA;KACA;KACD,CAAC,KAAK,KAAK;IACb,EACD;IACE,MAAM;IACN,SAAS;KACP;KACA;KACA;KACA,0BAA0B,SAAS;KACpC,CAAC,KAAK,KAAK;IACb,CACF;GACF,CAAC,EACuB,SAAS,MAAM;AACxC,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,sCAAsC;AAExD,SAAO;;;;;AC5WX,IAAa,8BAAb,MAAyC;CACvC;CAEA,YACE,SAGA;AAHiB,OAAA,UAAA;AAIjB,OAAK,mBAAmB,IAAI,kCAAkC,EAC5D,eAAe,QAAQ,eACxB,CAAC;;CAGJ,WAAW,WAMyB;EAClC,MAAM,EACJ,iBACA,WACA,iBACA,eACA,mBACE;AACJ,SAAO,KAAK,iBAAiB,QAAQ;GACnC;GACA;GACA;GACA;GACA;GACD,CAAC;;;AAIN,IAAa,2BAAb,MAAsC;CACpC;CAEA,YACE,SAKA;AALiB,OAAA,UAAA;AAMjB,OAAK,mBAAmB,IAAI,kCAAkC;GAC5D,eAAe,QAAQ;GACvB,iBAAiB,QAAQ;GAC1B,CAAC;;CAGJ,mBAAmB,iBAEjB,QAIiC;EACjC,MAAM,oBAAoB,KAAK,QAAQ;EACvC,MAAM,EAAE,OAAO,YAAY;EAC3B,MAAM,cAAc,KAAK,iBAAiB,MAAM;GAC9C,eAAe,MAAM;GACrB,iBAAiB,MAAM,YAAY,EAAE;GACrC,WAAW,MAAM;GACjB,iBAAiB,QAAQ,aAAa,aAAa,CAAC;GACpD,GAAI,QAAQ,UAAU,EAAE,eAAe,QAAQ,SAAS,GAAG,EAAE;GAC7D,gBAAgB,MAAM,YAAY,EAAE;GACrC,CAAC;AACF,SAAO,KAAK,yBAAyB;GAAE;GAAO,QAAQ;GAAa;GAAS;GAAmB,CAAC;AAChG,MAAI,CAAC,YAAY,kBACf;EAEF,MAAM,eAAe,MAAM,KAAK,iBAAiB,OAAO,YAAY,kBAAkB;AACtF,SAAO,KAAK,yBAAyB;GAAE;GAAO,QAAQ;GAAc;GAAS;GAAmB,CAAC;;CAGnG,2BAAmC,iBAEjC,QAMiC;EACjC,MAAM,EAAE,OAAO,QAAQ,SAAS,sBAAsB;AACtD,MAAI,OAAO,KAAK,OAAO,cAAc,CAAC,SAAS,EAC7C,OAAM,kBAAkB,sBAAsB,QAAQ,WAAW,OAAO,cAAc;EAExF,MAAM,qBAAqB;GACzB,MAAM,aAAa;GACnB,SAAS;IACP,WAAW,MAAM;IACjB,eAAe,OAAO;IACvB;GACF;AACD,QAAM,kBAAkB,mBAAmB,QAAQ,WAAW,mBAAmB;AACjF,QAAM;AACN,MAAI,CAAC,OAAO,gBACV;EAEF,MAAM,YAAY,QAAQ,aAAa,aAAa,CAAC;AACrD,UAAQ,aAAa,QAAQ;GAC3B,WAAW,MAAM;GACjB,UAAU,OAAO;GACjB;GACA,eAAe,OAAO;GACvB,CAAC;EACF,MAAM,gBAAgB;GACpB,MAAM,aAAa;GACnB,SAAS;IACP,WAAW,MAAM;IACjB,SAAS,OAAO;IACjB;GACF;AACD,QAAM,kBAAkB,mBAAmB,QAAQ,WAAW,cAAc;AAC5E,QAAM;;;;;ACjIV,SAAgB,gCAAgC,OAAwC;CACtF,MAAM,UAAU,aAAa,QAAQ,MAAM,UAAU;AACrD,KAAI,CAAC,WAAW,OAAO,YAAY,SACjC,QAAO;AAET,QAAO,eAAe,WAAW,OAAO,QAAQ,cAAc,WAC1D,QAAQ,UAAU,MAAM,IAAI,OAC5B;;AAGN,SAAgB,wBAAwB,OAAkD;AACxF,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAgB,6BAA6B,OAAwC;AACnF,QAAO,KAAK,UAAU,MAAM;;AAG9B,SAAgB,uCAAuC,OAAkC;AACvF,SAAQ,MAAM,MAAd;EACE,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa,sBAChB,QAAO;EACT,QACE,QAAO;;;AAIb,SAAgB,sCAAsC,OAAkC;AACtF,SAAQ,MAAM,MAAd;EACE,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa,SAChB,QAAO;EACT,QACE,QAAO;;;;;ACAb,SAAS,aAAa,MAAwC;AAC5D,KAAIE,WAAS,KAAK,CAChB,QAAO;AAET,KAAI,OAAO,SAAS,SAClB,KAAI;EACF,MAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,SAAOA,WAAS,OAAO,GAAG,SAAS,EAAE;SAC/B;AACN,SAAO,EAAE;;AAGb,QAAO,EAAE;;AAGX,IAAM,qBAAN,MAA4C;CAC1C,YAAY,MAA6B,aAAqF;AAAjG,OAAA,OAAA;AAA6B,OAAA,cAAA;;CAE1D,IAAI,OAAe;AACjB,SAAO,KAAK,KAAK;;CAGnB,IAAI,cAAsB;AACxB,SAAO,KAAK,KAAK;;CAGnB,IAAI,aAAsC;AACxC,SAAO,KAAK,KAAK;;CAGnB,UAAU,OAAO,SAAoC;AACnD,SAAO,KAAK,YAAY,KAAK,KAAK,MAAM,KAAK;;;AAIjD,IAAM,sBAAN,MAAyD;CACvD,WAAmB,IAAI,cAAc;CACrC,wBAAyB,IAAI,KAAsB;CACnD,8BAA4D,EAAE;CAE9D,YACE,cACA,SACA;AAFiB,OAAA,eAAA;AACA,OAAA,UAAA;;CAGnB,iBAAiB,YAAkC;EACjD,MAAM,EACJ,SACA,QACA,QACA,qBACA,WACA,cACE;AACJ,OAAK,8BAA8B;GACjC;GACA,cAAc;GACd,YAAY;GACZ;GACA;GACA,WAAW;GACZ;AAED,OAAK,WAAW,IAAI,cAAc;AAClC,OAAK,MAAM,OAAO;EAElB,MAAM,sBAAsB,KAAK,2BAA2B;AAC5D,OAAK,MAAM,YAAY,KAAK,cAAc,CACxC,UAAS,cAAc,SAAS,oBAAoB;;CAIxD,kBAA0C;AACxC,SAAO,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC,QAAQ,SAAS,KAAK,gBAAgB,KAAK,KAAK,CAAC;;CAGnF,WAAW,SAAsC;AAC/C,MAAI,CAAC,KAAK,gBAAgB,KAAK,CAC7B;AAEF,SAAO,KAAK,MAAM,IAAI,KAAK;;CAG7B,2BAA6D;AAC3D,SAAO,KAAK,WAAW,CAAC,KAAK,UAAU;GACrC,MAAM,KAAK;GACX,aAAa,KAAK;GAClB,YAAY,KAAK;GAClB,EAAE;;CAGL,UAAU,OAAO,YAAoB,UAAkB,SAAoC;AACzF,MAAI,KAAK,SAAS,IAAI,SAAS,CAC7B,QAAO,KAAK,SAAS,WACnB,UACA,aAAa,KAAK,EAClB,KAAK,0BAA0B,WAAW,CAC3C;AAEH,SAAO,KAAK,MAAM,IAAI,SAAS,EAAE,QAAQ,KAAK;;CAGhD,6BAAqC,eAA6C;EAChF,MAAM,YAAY,KAAK,4BAA4B;AACnD,SAAO,2BAA2B;GAChC;GACA,sBAAsB,OAAO,WAAoB;AAC/C,QAAI,CAAC,UACH;AAEF,UAAM,KAAK,QAAQ,qBAAqB;KACtC;KACA;KACA;KACD,CAAC;;GAEL,CAAC;;CAGJ,mCAAoE;EAClE,cAAc,KAAK;EACnB,iBAAiB,KAAK;EACtB,UAAU,SAAS,KAAK,MAAM,IAAI,KAAK;EACvC,kCAAkC,KAAK;EACxC;CAED,gBAAwB,SAAqB;AAC3C,OAAK,SAAS,SAAS,KAAK;AAC5B,OAAK,MAAM,IACT,KAAK,MACL,IAAI,mBAAmB,MAAM,OAAO,UAAU,SAC5C,KAAK,SAAS,QAAQ,UAAU,aAAa,KAAK,CAAC,CACpD,CACF;;CAGH,mBAA2B,SAAwB;AACjD,MAAI,KAAK,MAAM,IAAI,KAAK,KAAK,CAC3B;AAEF,OAAK,MAAM,IAAI,KAAK,MAAM,KAAK;;CAGjC,mBAA2B,SAA0B;EACnD,MAAM,WAAW,KAAK,SAAS,IAAI,KAAK;AACxC,SAAO,WAAW,SAAS,aAAa,GAAG;;;AAI/C,IAAa,cAAb,MAAyB;CACvB,4BAA6B,IAAI,KAA2B;CAE5D,gBAAgB,aAAoD;AAClE,MAAI,KAAK,UAAU,IAAI,SAAS,GAAG,CACjC,OAAM,IAAI,MAAM,wCAAwC,SAAS,KAAK;AAExE,OAAK,UAAU,IAAI,SAAS,IAAI,SAAS;AACzC,SAAO,EACL,eAAe;AACb,OAAI,KAAK,UAAU,IAAI,SAAS,GAAG,KAAK,SACtC,MAAK,UAAU,OAAO,SAAS,GAAG;KAGvC;;CAGH,yBAAyB,YAA6D;AACpF,SAAO,IAAI,0BAA0B,CAAC,GAAG,KAAK,UAAU,QAAQ,CAAC,EAAE,QAAQ;;;AAK/E,SAAgB,yBAAyB,UAA2C;CAClF,MAAM,WAAW,OAAO,SAAS,uBAAuB,EAAE;AAC1D,KAAI,CAAC,OAAO,SAAS,SAAS,IAAI,WAAW,EAC3C,QAAO;AAET,QAAO,KAAK,MAAM,SAAS;;;;ACnO7B,SAAgB,wBAAwB,OAAoC;AAC1E,KAAI,OAAO,UAAU,SACnB;CAEF,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,SAAgB,kBAAkB,UAAkD;CAClF,MAAM,aAAa;EAAC,SAAS;EAAO,SAAS;EAAW,SAAS;EAAa,SAAS;EAAc;AACrG,MAAK,MAAM,aAAa,YAAY;EAClC,MAAM,aAAa,wBAAwB,UAAU;AACrD,MAAI,WACF,QAAO;;AAGX,QAAO;;AAGT,SAAgB,qBAAqB,UAAuE;CAC1G,MAAM,aAAa;EACjB,SAAS;EACT,SAAS;EACT,SAAS;EACT,SAAS;EACT,SAAS;EACV;AACD,MAAK,MAAM,aAAa,YAAY;AAClC,MAAI,OAAO,cAAc,SACvB;EAEF,MAAM,aAAa,UAAU,MAAM,CAAC,aAAa;AACjD,MAAI,CAAC,WACH;AAEF,MAAI,eAAe,WAAW,eAAe,WAAW,eAAe,OACrE,QAAO;EAET,MAAM,QAAQ,mBAAmB,WAAW;AAC5C,MAAI,MACF,QAAO;;AAGX,QAAO;;AAGT,SAAgB,sBAAsB,QAImB;CACvD,MAAM,EAAE,eAAe,oBAAoB;CAC3C,MAAM,WAAW,gBAAgB,OAAO,gBAAgB;AAIxD,KAFE,gBAAgB,gBAAgB,QAChC,gBAAgB,gBAAgB,KAEhC,QAAO,SAAS;CAGlB,MAAM,eAAe,kBAAkB,gBAAgB;AACvD,KAAI,aACF,UAAS,kBAAkB;AAG7B,QAAO;EACL;EACA,OAAO,wBAAwB,SAAS,gBAAgB,IAAI;EAC7D;;AAGH,SAAgB,8BAA8B,QAGlB;CAC1B,MAAM,EAAE,oBAAoB;CAC5B,MAAM,WAAW,gBAAgB,OAAO,gBAAgB;AAIxD,KAFE,gBAAgB,mBAAmB,QACnC,gBAAgB,mBAAmB,KAEnC,QAAO,SAAS;CAGlB,MAAM,kBAAkB,qBAAqB,gBAAgB;AAC7D,KAAI,oBAAoB,aAAa;AACnC,SAAO,SAAS;AAChB,SAAO;;AAET,KAAI,gBACF,UAAS,qBAAqB;AAEhC,QAAO;;AAGT,SAAgB,6BAA6B,QAG8B;CACzE,MAAM,EAAE,oBAAoB;CAC5B,MAAM,WAAW,gBAAgB,OAAO,gBAAgB;CACxD,MAAM,UACJ,wBAAwB,gBAAgB,QAAQ,IAChD,wBAAwB,SAAS,aAAa,IAC9C;CACF,MAAM,SACJ,wBAAwB,gBAAgB,OAAO,IAC/C,wBAAwB,gBAAgB,QAAQ,IAChD,wBAAwB,SAAS,QAAQ,IACzC;AAEF,UAAS,eAAe;AACxB,UAAS,UAAU;AACnB,QAAO;EAAE;EAAS;EAAQ;EAAU;;;;AC1DtC,MAAM,mCAAmC,IAAI,+BAA+B;AAE5E,SAAS,qBAAqB,UAAkD;AAC9E,QAAO,wBAAwB,SAAS,SAAS,EAAE,aAAa,IAC9D,wBAAwB,SAAS,QAAQ,EAAE,aAAa,IACxD;;AAGJ,SAAS,oBAAoB,QAIO;CAClC,MAAM,EAAE,QAAQ,iBAAiB,kBAAkB;CACnD,MAAM,EACJ,QAAQ,EAAE,YACV,QAAQ,cACR,OAAO,EACL,qBACA,MAAM,EAAE,SAAS,2BAEjB;CACJ,MAAM,iBAAiB,6BAA6B,OAAO;CAK3D,MAAM,UACJ,0BAA0B,QAJ1B,wBAAwB,cAAc,EAAE,aAAa,IACrD,qBAAqB,gBAAgB,IACrC,eAEmD,IACnD,0BAA0B,QAAQ,eAAe;AACnD,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,oCAAoC,iBAAiB;CAEvE,MAAM,gBAAgB,QAAQ,iBAAiB,SAAS;AACxD,QAAO;EACL,SAAS,QAAQ;EACjB,WAAW,iBAAiB,QAAQ,aAAa,SAAS,UAAU;EACpE,OAAO,QAAQ,SAAS,SAAS;EACjC;EACA,uBAAuB,2BAA2B,6BAA6B;GAC7E;GACA,iCAAiC,QAAQ,yBAAyB,SAAS;GAC5E,CAAC;EACF;EACA;EACA;EACD;;AAGH,SAAS,0BAA0B,UAA6C;CAC9E,MAAM,WAAW,SAAS,mBAAmB,SAAS;AACtD,KAAI,CAAC,MAAM,QAAQ,SAAS,CAC1B,QAAO,EAAE;AAEX,QAAO,MAAM,KACX,IAAI,IACF,SACG,KAAK,SAAS,wBAAwB,KAAK,CAAC,CAC5C,QAAQ,SAAyB,QAAQ,KAAK,CAAC,CACnD,CACF;;AAGH,SAAS,iBAAiB,QAGE;CAC1B,MAAM,EAAE,iBAAiB,oBAAoB;AAC7C,QAAO;EACL,GAAI,kBAAkB,gBAAgB,gBAAgB,GAAG,EAAE;EAC3D,GAAI,kBAAkB,gBAAgB,gBAAgB,GAAG,EAAE;EAC5D;;AAGH,SAAgB,mCAA2C;AACzD,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAgB,6BACd,QAC+B;CAC/B,MAAM,EACJ,eACA,iBAAiB,sBACjB,WACA,iBAAiB,sBACjB,kBACE;CACJ,MAAM,SAAS,cAAc,YAAY;CACzC,MAAM,kBAAkB,iBAAiB;EACvC,iBAAiB;EACjB,iBAAiB;EAClB,CAAC;CACF,MAAM,UAAU,oBAAoB;EAClC;EACA;EACA;EACD,CAAC;CACF,MAAM,EAAE,UAAU,eAAe,OAAO,mBAAmB,sBAAsB;EAC/E,iBAAiB;EACjB;EACA,eAAe,QAAQ;EACxB,CAAC;CACF,MAAM,qBAAqB,4BAA4B;EACrD,iBAAiB;EACjB,WAAW,QAAQ;EACpB,CAAC;CACF,MAAM,iBAAiB,6BAA6B;EAClD,iBAAiB;EACjB;EACD,CAAC;CACF,MAAM,kBAAkB,eAAe;CACvC,MAAM,kBAAkB,iCAAiC,cAAc,gBAAgB;CACvF,MAAM,kBAAkB,qBAAqB;EAC3C;EACA,SAAS,QAAQ;EACjB,OAAO;EACP,sBAAsB,mBAAmB,gBAAgB,mBAAmB,IAAI;EACjF,CAAC;AAEF,QAAO;EACL,SAAS,eAAe;EACxB,QAAQ,eAAe;EACvB;EACA;EACA;EACA;EACA;EACA;EACA,oBAAoB,0BAA0B,gBAAgB;EAC9D;EACA,YAAY;EACZ;EACA,gBAAgB;GACd;GACA,SAAS,eAAe;GACxB,QAAQ,eAAe;GACvB,SAAS,QAAQ;GACjB;GACA,oBAAoB,QAAQ;GAC5B,cAAc,yBAAyB,gBAAgB;GACvD,UAAU;GACV,qBAAqB,QAAQ;GAC7B,cAAc,QAAQ;GACtB,WAAW;GACZ;EACF;;;;AClKH,MAAM,6BAA6B,CACjC,8HACA,6CACD;AAED,SAASC,WAAS,OAAkD;AAClE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,mBAAmB,OAAkD;CAC5E,MAAM,kBAAkB,MAAM,SAC3B,OAAO,CACP,SAAS,CACT,MAAM,YAAYA,WAAS,QAAQ,SAAS,CAAC,EAAE;AAClD,QAAO;EACL,GAAIA,WAAS,gBAAgB,GAAG,gBAAgB,gBAAgB,GAAG,EAAE;EACrE,GAAIA,WAAS,MAAM,SAAS,GAAG,gBAAgB,MAAM,SAAS,GAAG,EAAE;EACpE;;AAGH,SAAS,qBAAqB,SAA0B;CACtD,MAAM,aAAa,QAAQ,MAAM;AACjC,KAAI,CAAC,WACH,QAAO;AAET,QAAO,2BAA2B,MAAM,YAAY,QAAQ,KAAK,WAAW,CAAC;;AAG/E,SAAS,6BAA6B,MAAoB;CACxD,MAAM,OAAO,KAAK,aAAa;CAC/B,MAAM,QAAQ,OAAO,KAAK,UAAU,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI;CAC1D,MAAM,MAAM,OAAO,KAAK,SAAS,CAAC,CAAC,SAAS,GAAG,IAAI;CACnD,MAAM,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,GAAG,IAAI;CACrD,MAAM,SAAS,OAAO,KAAK,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI;CACzD,MAAM,gBAAgB,CAAC,KAAK,mBAAmB;CAC/C,MAAM,OAAO,iBAAiB,IAAI,MAAM;CACxC,MAAM,aAAa,KAAK,IAAI,cAAc;AAI1C,QAAO,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,OAAO,GAAG,OAHjC,OAAO,KAAK,MAAM,aAAa,GAAG,CAAC,CAAC,SAAS,GAAG,IAAI,CAGD,GAFjD,OAAO,aAAa,GAAG,CAAC,SAAS,GAAG,IAAI,CAEyB,IADrE,KAAK,gBAAgB,CAAC,iBAAiB,CAAC,YAAY,QAC8B;;AAGrG,SAAS,wBAAwB,SAAiB,WAAyB;AACzE,KAAI,CAAC,qBAAqB,QAAQ,CAChC,QAAO;AAGT,QAAO,GAAG,QAAQ,+BAA+B,6BADpC,OAAO,MAAM,UAAU,SAAS,CAAC,mBAAG,IAAI,MAAM,GAAG,UACqB;;AAGrF,SAAS,uBAAuB,SAAiB,yBAA2C;AAC1F,KAAI,wBAAwB,WAAW,EACrC,QAAO;AAET,QAAO,oCAAoC,wBAAwB,KAAK,KAAK,CAAC,OAAO;;AAGvF,SAAS,0BACP,iBACA,oBAC0B;CAC1B,MAAM,QAAQ,gBAAgB,IAAI,wBAAwB;AAC1D,KAAI,MAAM,WAAW,EACnB;AAEF,KAAI,mBAAmB,WAAW,EAChC,QAAO;CAET,MAAM,YAAY,IAAI,IAAI,mBAAmB;CAC7C,MAAM,WAAW,MAAM,QAAQ,SAAS,UAAU,IAAI,KAAK,SAAS,KAAK,CAAC;AAC1E,QAAO,SAAS,SAAS,IAAI,WAAW,KAAA;;AAG1C,IAAa,4BAAb,MAAoE;CAClE,oBAAqC,IAAI,mBAAmB;CAE5D,YACE,SACA;AADiB,OAAA,UAAA;;CAGnB,WAAW,OAAyB,aAAwD;EAC1F,MAAM,aAAa,KAAK,kBAAkB,MAAM;EAChD,MAAM,gBAAgB,KAAK,mBAAmB,OAAO,UAAU,WAAW;AAG1E,SAAO;GACL,UAHa,KAAK,mBAAmB,YAAY,cAAc,CAG9C;GACjB,OAAO,0BAA0B,cAAc,iBAAiB,WAAW,mBAAmB;GAC9F,OAAO,WAAW;GAClB,eAAe,WAAW;GAC3B;;CAGH,qBAA6B,UAAgD;EAC3E,MAAM,kBAAkB,mBAAmB,MAAM;EACjD,MAAM,WAAW,6BAA6B;GAC5C,eAAe,KAAK,QAAQ;GAC5B,WAAW,MAAM;GACjB;GACA,iBAAiB;GACjB,eAAe,KAAK,QAAQ;GAC7B,CAAC;EACF,MAAM,cAAc,sBAAsB;GACxC;GACA,cAAc,SAAS;GACvB,eAAe,EAAE,MAAM,gBACrB,wBACE,uBAAuB,MAAM,SAAS,gBAAgB,UAAU,EAChE,UACD;GACH,YAAY,KAAK,QAAQ;GAC1B,CAAC;AAEF,OAAK,QAAQ,aAAa,cAAc,SAAS,eAAe;AAEhE,SAAO;GACL,GAAG;GACH;GACA,gBAAgB,YAAY;GAC7B;;CAGH,sBACE,OACA,UACA,eAC0B;EAC1B,MAAM,EACJ,SACA,QACA,QACA,aACA,gBACA,oBACA,SACA,iBACA,iBACA,oBACE;EACJ,MAAM,kBAAkB,KAAK,QAAQ,aAAa,oBAAoB;EACtE,MAAM,2BAA2B,CAC/B,kCAAkC,EAClC,kCAAkC,eAAe,CAClD,CAAC,OAAO,QAAQ;EAEjB,MAAM,iBAAiB,IAAI,eACzB,oBACA,OAAO,OAAO,SACd;GACE,eAAe,QAAQ;GACvB,oBAAoB,uBAAuB,gBAAgB;GAC5D,CACF;EACD,MAAM,kBAAkB,wCAAwC;GAC9D,WAAW,MAAM;GACjB,iBAAiB,UAAU,mBAAmB,EAAE;GACjD,CAAC;EACF,MAAM,WAAW,eAAe,cAAc;GAC5C,SAAS,iBAAiB,CAAC,GAAG,gBAAgB,EAAE;IAC9C,YAAY,KAAK,QAAQ;IACzB,aAAa;IACd,CAAC;GACF,gBAAgB;GAChB;GACA;GACA,YAAY,MAAM;GAClB,eAAe;GACf,YAAY,gBAAgB;GAC5B,gBAAgB,wBAAwB,gBAAgB;GACxD;GACD,CAAC;AACF,WAAS,SAAS,SAAS,KAAK;GAC9B,MAAM,YAAY;GAClB,SAAS,YAAY;GACtB;AACD,SAAO;GACL;GACA;GACD;;CAGH,sBACE,YACA,kBACG;AACH,SAAO,KAAK,kBAAkB,MAAM;GAClC,UAAU,cAAc;GACxB,eAAe,WAAW,QAAQ;GAClC,oBAAoB,WAAW,QAAQ;GACvC,qBAAqB;GACtB,CAAC;;;;;ACxON,SAAS,eAAe,OAA0C;AAChE,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;AAGxC,SAAS,uBAAuB,OAAwD;AACtF,QAAO,mBAAmB,MAAM;;AAGlC,SAAS,sBAAsB,OAAmC;AAChE,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;AAGxC,SAAS,gBAAgB,UAA2B,OAAe;AACjE,QAAO;EACL;EACA,IAAI,SAAS;EACb,MAAM;EACN,UAAU;GACR,MAAM,SAAS;GACf,WAAW,KAAK,UAAU,SAAS,aAAa,EAAE,CAAC;GACpD;EACF;;AAGH,SAAS,aACP,UACA,SAKiB;CACjB,MAAM,QAAkE,EAAE;AAC1E,KAAI,QAAQ,eAAe,OAAO,SAAS,YAAY,YAAY,SAAS,QAAQ,SAAS,EAC3F,OAAM,UAAU,SAAS;AAE3B,KACE,QAAQ,oBACR,OAAO,SAAS,qBAAqB,YACrC,SAAS,iBAAiB,SAAS,EAEnC,OAAM,oBAAoB,SAAS;AAErC,KAAI,QAAQ,oBAAoB,SAAS,UAAU,SAAS,EAC1D,OAAM,aAAa,SAAS,UAAU,KAAK,UAAU,UAAU,gBAAgB,UAAU,MAAM,CAAC;AAGlG,QAAO;EACL,SAAS,CACP;GACE;GACA,eAAe,sBAAsB,SAAS,aAAa;GAC5D,CACF;EACD,OAAO,SAAS;EACjB;;AAGH,IAAa,2BAAb,MAA2D;CACzD,YAAY,iBAAsD;AAArC,OAAA,kBAAA;;CAE7B,WAAoB,iBAElB,OACA,SACiC;EACjC,MAAM,QAAQ,eAAe,MAAM,MAAM,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,iBAAiB;EAC7F,MAAM,gBAAgB,uBAAuB,MAAM,cAAc;EACjE,IAAI,eAAe;EACnB,IAAI,oBAAoB;EACxB,IAAI,mBAAmB;AAEvB,aAAW,MAAM,SAAS,KAAK,gBAAgB,WAAW;GACxD,UAAU,MAAM;GAChB,OAAO,MAAM;GACb;GACA,GAAI,gBAAgB,EAAE,eAAe,GAAG,EAAE;GAC1C,WAAW,MAAM;GACjB,QAAQ,SAAS;GAClB,CAAC,EAAE;AACF,OAAI,MAAM,SAAS,SAAS;AAC1B,mBAAe;AACf,UAAM,EACJ,SAAS,CACP,EACE,OAAO,EACL,SAAS,MAAM,OAChB,EACF,CACF,EACF;AACD;;AAGF,OAAI,MAAM,SAAS,mBAAmB;AACpC,wBAAoB;AACpB,UAAM,EACJ,SAAS,CACP,EACE,OAAO,EACL,mBAAmB,MAAM,OAC1B,EACF,CACF,EACF;AACD;;AAGF,OAAI,MAAM,SAAS,mBAAmB;AACpC,uBAAmB;AACnB,UAAM,EACJ,SAAS,CACP,EACE,OAAO,EACL,YAAY,MAAM,WACnB,EACF,CACF,EACF;AACD;;AAGF,SAAM,aAAa,MAAM,UAAU;IACjC,aAAa,CAAC;IACd,kBAAkB,CAAC;IACnB,kBAAkB,CAAC;IACpB,CAAC;;;;;;AClHR,SAASC,WAAS,OAAkD;AAClE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,wCAAwC,QAGN;CACzC,MAAM,eACJ,OAAO,OAAO,OAAO,SAAS,QAAQ,QAAQ,UAC9C,OAAO,OAAO,GAAG,IAAI,SAAS;CAChC,MAAM,kBAAkBA,WAAS,aAAa,GAAG,eAAe,EAAE;AAElE,QACE,oDAAoD,OAAO,gBAAgB,IAC3E,wCAAwC,gBAAgB,uBAAuB,IAC/E,wCAAwC,gBAAgB,wBAAwB,IAChF,wCAAwC,gBAAgB,2BAA2B,IACnF,wCAAwC,gBAAgB,6BAA6B,IACrF;;AAIJ,IAAa,4BAAb,MAAuC;CACrC;CAEA,YAAY,SAA4D;AAA3C,OAAA,UAAA;AAC3B,OAAK,0BAA0B,QAAQ,SAAS,uBAC9C,QAAQ,iBACR,SACD;;CAGH,UAAgC,EAC9B,SACA,cACA,sBAC2C;EAC3C,MAAM,6BAA6B,wCAAwC;GACzE,QAAQ,KAAK,QAAQ,cAAc,YAAY;GAC/C;GACD,CAAC;EAEF,MAAM,eAAe,KAAK,oBAAoB;EAC9C,MAAM,UAAU,IAAI,uBAAuB;GACzC,gBAAgB,IAAI,0BAA0B;IAC5C;IACA;IACA,eAAe,KAAK,QAAQ;IAC5B,YAAY,KAAK,QAAQ;IAC1B,CAAC;GACF,QAAQ,IAAI,yBAAyB,KAAK,wBAAwB;GAClE;GACA;GACA;GACD,CAAC;AACF,SAAO,EACL,KAAK,iBAAiB,OAAO,SAAS;AACpC,UAAO,QAAQ,IAAI,OAAO,QAAQ;KAErC;;CAGH,2BAAmC;AACjC,SAAO,KAAK,QAAQ,YAAY,sBAAsB,EACpD,sBAAsB,KAAK,QAAQ,sBACpC,CAAC;;;;;ACxFN,SAASC,qBAAmB,OAA+B;AACzD,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;AAGxC,SAAS,wBAAwB,OAAmC;CAClE,MAAM,SAASA,qBAAmB,MAAM;AACxC,KAAI,CAAC,OACH,QAAO;AAET,KAAI;AACF,SAAO,OAAO,KAAK,QAAQ,SAAS;SAC9B;AACN,SAAO;;;AAIX,SAAS,eAAe,QAA2B,iBAAyB;AAC1E,QAAO;EACL,KAAK,OAAO;EACZ,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,KAAK,sBAAsB;GACzB,UAAU;GACV,UAAU,OAAO;GAClB,CAAC;EACH;;AAGH,IAAM,eAAN,MAAsC;CACpC,OAAgB;CAChB,cACE;CACF,aAAsB;EACpB,MAAM;EACN,YAAY;GACV,MAAM;IACJ,MAAM;IACN,aAAa;IACd;GACD,aAAa;IACX,MAAM;IACN,aAAa;IACd;GACD,UAAU;IACR,MAAM;IACN,aAAa;IACd;GACD,UAAU;IACR,MAAM;IACN,aAAa;IACd;GACF;EACD,sBAAsB;EACvB;CAED,YACE,YACA,iBACA;AAFiB,OAAA,aAAA;AACA,OAAA,kBAAA;;CAGnB,gBAAgB,SAA4C;EAC1D,MAAM,OAAOA,qBAAmB,KAAK,KAAK;EAC1C,MAAM,cAAcA,qBAAmB,KAAK,YAAY;EACxD,MAAM,WAAWA,qBAAmB,KAAK,SAAS;AAElD,MAAI,QAAQ,YACV,QAAO,CAAC,4DAA4D;AAEtE,MAAI,KACF,QAAO,EAAE;AAEX,MAAI,YACF,QAAO,WAAW,EAAE,GAAG,CAAC,+CAA+C;AAEzE,SAAO,CAAC,kDAAkD;;CAG5D,UAAU,OAAO,SAAoC;EACnD,MAAM,OAAOA,qBAAoB,MAAoC,KAAK;EAC1E,MAAM,WAAWA,qBAAoB,MAAwC,SAAS;EACtF,MAAM,WAAWA,qBAAoB,MAAwC,SAAS;EACtF,MAAM,QAAQ,wBAAyB,MAA2C,YAAY;AAE9F,MAAI,KAMF,QAAO;GACL,IAAI;GACJ,OAAO,eAPM,MAAM,KAAK,WAAW,QAAQ;IAC3C;IACA,UAAU,YAAY,KAAA;IACtB;IACD,CAAC,EAG8B,KAAK,gBAAgB;GACpD;AAGH,MAAI,SAAS,SAMX,QAAO;GACL,IAAI;GACJ,OAAO,eAPM,MAAM,KAAK,WAAW,SAAS;IAC5C;IACA;IACA;IACD,CAAC,EAG8B,KAAK,gBAAgB;GACpD;AAGH,QAAM,IAAI,MAAM,yDAAyD;;;AAI7E,IAAM,kBAAN,MAAyC;CACvC,OAAgB;CAChB,cACE;CACF,aAAsB;EACpB,MAAM;EACN,YAAY;GACV,UAAU;IACR,MAAM;IACN,aAAa;IACd;GACD,YAAY;IACV,MAAM;IACN,aAAa;IACd;GACF;EACD,UAAU,CAAC,YAAY,aAAa;EACpC,sBAAsB;EACvB;CAED,YAAY,YAA8C;AAA7B,OAAA,aAAA;;CAE7B,UAAU,OAAO,SAAoC;EACnD,MAAM,WAAWA,qBAAoB,MAAwC,SAAS;EACtF,MAAM,aAAaA,qBAAoB,MAA0C,WAAW;AAC5F,MAAI,CAAC,YAAY,CAAC,WAChB,OAAM,IAAI,MAAM,iDAAiD;AAGnE,SAAO;GACL,IAAI;GACJ;GACA,cAJmB,MAAM,KAAK,WAAW,OAAO,EAAE,KAAK,UAAU,EAAE,QAAQ,WAAW,CAAC;GAKxF;;;AAIL,IAAM,gBAAN,MAAuC;CACrC,OAAgB;CAChB,cAAuB;CACvB,aAAsB;EACpB,MAAM;EACN,YAAY,EACV,UAAU;GACR,MAAM;GACN,aAAa;GACd,EACF;EACD,UAAU,CAAC,WAAW;EACtB,sBAAsB;EACvB;CAED,YACE,YACA,iBACA;AAFiB,OAAA,aAAA;AACA,OAAA,kBAAA;;CAGnB,UAAU,OAAO,SAAoC;EACnD,MAAM,WAAWA,qBAAoB,MAAwC,SAAS;AACtF,MAAI,CAAC,SACH,OAAM,IAAI,MAAM,gCAAgC;EAElD,MAAM,SAAS,MAAM,KAAK,WAAW,WAAW,SAAS;AACzD,MAAI,CAAC,OACH,QAAO;GACL,IAAI;GACJ,OAAO;IACL,MAAM;IACN,SAAS,oBAAoB;IAC9B;GACF;AAEH,SAAO;GACL,IAAI;GACJ,OAAO,eAAe,QAAQ,KAAK,gBAAgB;GACpD;;;AAIL,SAAgB,iBAAiB,QAGnB;CACZ,MAAM,EAAE,eAAe;CACvB,MAAM,kBAAkB,OAAO,mBAAmB;AAClD,QAAO;EACL,IAAI,aAAa,YAAY,gBAAgB;EAC7C,IAAI,gBAAgB,WAAW;EAC/B,IAAI,cAAc,YAAY,gBAAgB;EAC/C;;;;AC/KH,IAAa,yBAAb,MAAoC;CAClC;CACA,WAA+D,EAAE;CACjE;CACA;CACA;CACA,WAAmB;CACnB,UAAkB;CAElB,YAAY,SAKT;EACD,MAAM,EACJ,0BACA,SACA,mBACA,sBACE;AACJ,OAAK,2BAA2B;AAChC,OAAK,UAAU;AACf,OAAK,oBAAoB;AACzB,OAAK,oBAAoB;;CAG3B,cAAoB;AAClB,OAAK,mBAAmB;AACxB,MAAI,KAAK,QACP;AAEF,OAAK,UAAU;AACf,OAAK,SAAS,KACZ,KAAK,QAAQ,WAAW,YAAY,SAAS,MAAM,KAAK,kBAAkB,EAC1E,KAAK,QAAQ,WAAW,YAAY,SAAS,OAAO,KAAK,mBAAmB,EAC5E,KAAK,QAAQ,WAAW,YAAY,SAAS,uBAAuB,KAAK,4BAA4B,CACtG;;CAGH,UAAU,YAA2B;AACnC,MAAI,KAAK,SACP;AAEF,OAAK,WAAW;AAChB,SAAO,KAAK,SAAS,SAAS,EAC5B,OAAM,KAAK,SAAS,KAAK,IAAI;AAE/B,OAAK,UAAU;;CAGjB,OACE,UACA,YACoC,KAAK,WAAW,KAAK,uBAAuB,SAAS,EAAE,QAAQ;CAErG,oBAAqC,OACnC,aAC0B;AAC1B,MAAI,CAAC,SAAS,QACZ,OAAM,IAAI,MAAM,kCAAkC;EAEpD,MAAM,kBAAkB,MAAM,KAAK,wBAAwB,SAAS,QAAQ;AAC5E,SAAO,MAAM,iBACX,KAAK,WAAW,gBAAgB,EAChC;GACE,WAAW,gBAAgB;GAC3B,eAAe,gBAAgB,QAAQ;GACvC,oBAAoB;GACpB,OAAO,gBAAgB;GACvB,GAAI,gBAAgB,gBAAgB,EAAE,eAAe,gBAAgB,eAAe,GAAG,EAAE;GAC1F,CACF;;CAGH,qBAAsC,OACpC,aACkB;EAClB,MAAM,UAAU,SAAS;AACzB,MAAI,CAAC,SAAS,UACZ,OAAM,IAAI,MAAM,mCAAmC;EAErD,MAAM,YAAY,KAAK,kBAAkB,oBAAoB,QAAQ,UAAU;AAC/E,MAAI,CAAC,aAAa,UAAU,OAC1B;AAEF,YAAU,eAAe;AACzB,YAAU,WAAW,OAAO;AAC5B,OAAK,kBAAkB,oBAAoB,QAAQ,WAAW,UAAU;AACxE,QAAM,KAAK,kBAAkB,mBAAmB,QAAQ,WAAW;GACjE,MAAM,aAAa;GACnB,SAAS;IACP,WAAW,QAAQ;IACnB,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,WAAW,GAAG,EAAE;IAC9D;GACF,CAAC;AACF,OAAK,kBAAkB,uBAAuB,QAAQ,WAAW,UAAU,MAAM;;CAGnF,aAA8B,iBAE5B,UACA,SACiC;EACjC,MAAM,WAAW,MAAM,KAAK,0BAA0B,SAAS,WAAW,SAAS,SAAS;EAC5F,MAAM,UAAU,MAAM,KAAK,kBAAkB,uBAAuB,SAAS,WAAW,SAAS;EACjG,MAAM,aAAa,IAAI,iBAAiB;AACxC,WAAS,QAAQ,iBAAiB,eAAe,WAAW,OAAO,EAAE,EAAE,MAAM,MAAM,CAAC;EACpF,MAAM,YAAkC;GACtC,OAAO,SAAS;GAChB;GACA,iBAAiB,gBAAgB,SAAS;GAC1C,cAAc;GACd,QAAQ;GACT;AACD,OAAK,kBAAkB,oBAAoB,QAAQ,WAAW,UAAU;EACxE,IAAI,uBAAuB;AAE3B,MAAI;AACF,OAAI,CAAC,mBAAmB,SAAS,QAAQ,EAAE;IACzC,MAAM,mBAAqC;KACzC,MAAM,aAAa;KACnB,SAAS;MACP,WAAW,SAAS;MACpB,SAAS,gBAAgB,SAAS,QAAQ;MAC1C,GAAI,SAAS,gBAAgB,EAAE,eAAe,SAAS,eAAe,GAAG,EAAE;MAC3E;MACD;KACF;AACD,UAAM,KAAK,kBAAkB,mBAAmB,QAAQ,WAAW,kBAAkB,EACnF,wBAAwB,OACzB,CAAC;AACF,UAAM;;GAGR,MAAM,eAAe;IACnB,WAAW,SAAS;IACpB,OAAO,SAAS;IAChB,UAAU,CAAC,SAAS,QAAQ;IAC5B,eAAe,SAAS;IACxB;IACD;AACD,UAAO,KAAK,yBAAyB,iBAAiB;IACpD,OAAO;IACP;IACD,CAAC;AACF,cAAW,MAAM,SAAS,QAAQ,QAAQ,IAAI,cAAc,EAC1D,QAAQ,UAAU,WAAW,QAC9B,CAAC,EAAE;IACF,MAAM,kBAAkB,sBAAsB;KAC5C;KACA,OAAO,kBAAkB,OAAO,SAAS;KACzC;KACD,CAAC;AACF,2BAAuB,gBAAgB;AACvC,SAAK,MAAM,kBAAkB,gBAAgB,iBAAiB;AAC5D,WAAM,KAAK,kBAAkB,mBAAmB,QAAQ,WAAW,gBAAgB,EACjF,wBAAwB,OACzB,CAAC;AACF,WAAM;;;AAIV,OAAI,UAAU,WAAW,OAAO,WAAW,CAAC,UAAU,cAAc;IAClE,MAAM,aAA+B;KACnC,MAAM,aAAa;KACnB,SAAS,EAAE,WAAW,QAAQ,WAAW;KAC1C;AACD,UAAM,KAAK,kBAAkB,mBAAmB,QAAQ,WAAW,WAAW;AAC9E,UAAM;;WAED,OAAO;AACd,OAAI,CAAC,UAAU,WAAW,OAAO,SAAS;IACxC,MAAM,gBAAkC;KACtC,MAAM,aAAa;KACnB,SAAS;MACP,WAAW,SAAS;MACpB,OAAO,SAAS;MAChB,GAAI,SAAS,gBAAgB,EAAE,eAAe,SAAS,eAAe,GAAG,EAAE;MAC3E,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;MAC9D;KACF;AACD,UAAM,KAAK,kBAAkB,mBAAmB,QAAQ,WAAW,cAAc;AACjF,UAAM;;YAEA;AACR,QAAK,kBAAkB,uBAAuB,QAAQ,WAAW,UAAU,MAAM;;;CAIrF,0BAA2C,OACzC,aACyC;EACzC,MAAM,eAAe,KAAK,kBAAkB,SAAS;EACrD,MAAM,oBAAoBC,aAAW,aAAa,UAAU,IAAIA,aAAW,aAAa,QAAQ,UAAU;AAC1G,MAAI,kBACF,QAAO,KAAK,uBAAuB,YAAY,cAAc,kBAAkB,CAAC;EAGlF,MAAM,WAAW,aAAa,YAAY,EAAE;EAC5C,MAAM,iBAAiB,MAAM,KAAK,kBAAkB,cAAc;GAChE,MAAM,gBAAgB,aAAa,QAAQ;GAC3C,OAAO,mBAAmB,UAAU,SAAS,QAAQ;GACrD,uBAAuB,EAAE;GACzB,mBAAmB;GACnB,SAAS,mBAAmB,UAAU,YAAY,UAAU;GAC5D,OAAO,mBAAmB,UAAU,mBAAmB,QAAQ;GAC/D,SAAS,mBAAmB,UAAU,WAAW,eAAe;GAChE,aAAa,mBAAmB,UAAU,gBAAgB,UAAU;GACpE,eAAe,mBAAmB,UAAU,sBAAsB,WAAW;GAC7E,aAAa,mBAAmB,UAAU,eAAe;GAC1D,CAAC;AACF,SAAO,KAAK,uBAAuB,YAAY,cAAc,eAAe,UAAU,CAAC;;CAGzF,qBACE,aACyB;AACzB,MAAI,MAAM,QAAQ,SAAS,QAAQ,EAAE;GACnC,MAAM,EAAE,SAAS,GAAG,YAAY;AAChC,UAAO;IACL,GAAG;IACH,SAAS;KACP,IAAI,gBAAgB,YAAY;KAChC,MAAM;KACN,QAAQ;KACR,4BAAW,IAAI,MAAM,EAAC,aAAa;KACnC,OAAO,gBAAgB,QAAQ;KAChC;IACF;;AAEH,MAAI,aAAa,YAAY,SAAS,QACpC,QAAO;AAET,QAAM,IAAI,MAAM,kCAAkC;;CAGpD,0BAA2C,cAA+D;EACxG,GAAG;EACH,OAAO,WAAW,YAAY;EAC/B;CAED,4BAA6C,OAC3C,WACA,kBAA2C,EAAE,KACR;EAMrC,IAAI,eAAe,sBAAsB;GACvC,iBALsB;IACtB,IAFoB,MAAM,KAAK,kBAAkB,iBAAiB,UAAU,GAEzD,YAAY,EAAE;IACjC,GAAG,gBAAgB,gBAAgB;IACpC;GAGC;GACA,eAAe;GAChB,CAAC,CAAC;AACH,iBAAe,8BAA8B;GAC3C,iBAAiB;GACjB;GACD,CAAC;AACF,iBAAe,6BAA6B;GAC1C,iBAAiB;GACjB;GACD,CAAC,CAAC;AACH,QAAM,KAAK,kBAAkB,sBAAsB,WAAW,aAAa;AAC3E,SAAO;;CAGT,8BAA+C,OAC7C,aACkB;EAClB,MAAM,UAAU,SAAS;AACzB,MAAI,CAAC,SAAS,aAAa,CAAC,QAAQ,aAAa,CAAC,QAAQ,QACxD,OAAM,IAAI,MAAM,6CAA6C;EAE/D,IAAI,oBAAoB;AACxB,aAAW,MAAM,SAAS,KAAK,IAAI;GACjC,WAAW,QAAQ;GACnB,SAAS,QAAQ;GACjB,eAAe,QAAQ;GACxB,CAAC,CACA,uBAAsB,mBAAmB,MAAM;AAEjD,MAAI,CAAC,kBACH,OAAM,IAAI,MAAM,mDAAmD;;CAIvE,0BAAiD;AAC/C,MAAI,KAAK,SACP,OAAM,IAAI,MAAM,uDAAuD;;;;;ACzU7E,MAAa,iCAAiC;;;AC+D9C,SAAS,oBAAoB,OAA+B;AAC1D,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,aAAa,MAAM,MAAM,CAAC,aAAa;AAC7C,QAAO,WAAW,SAAS,IAAI,aAAa;;AAG9C,SAAS,kBAAkB,OAA6C;AACtE,QAAO;EACL,IAAI,MAAM;EACV,OAAO,MAAM;EACb,GAAI,MAAM,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,GAAG,EAAE;EACjD,MAAM,MAAM;EACZ,SAAS,MAAM,YAAY;EAC3B,QAAQ,MAAM,SAAS,EAAE,GAAG,MAAM,QAAQ,GAAG,EAAE;EAChD;;AAGH,SAAgB,qCACd,OACoC;AACpC,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,MAAM,MAAM,MAAM;AACxB,SAAO,MAAM;GAAE,MAAM;GAAS;GAAK,GAAG;;AAExC,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;CAET,MAAM,aAAa;CACnB,MAAM,MAAM,OAAO,WAAW,QAAQ,WAAW,WAAW,IAAI,MAAM,GAAG;AACzE,KAAI,CAAC,IACH,QAAO;CAET,MAAM,MACJ,OAAO,WAAW,QAAQ,YAAY,WAAW,IAAI,MAAM,CAAC,SAAS,IACjE,WAAW,IAAI,MAAM,GACrB;AACN,QAAO;EACL,MAAM;EACN;EACA,GAAI,MAAM,EAAE,KAAK,GAAG,EAAE;EACvB;;AA0BH,MAAM,+BAA+B,EACnC,QAAQ;CACN,OAAO;CACP,MAAM;EACJ,MAAM;EACN,KAAK;EACL,KAAK;EACN;CACF,EACF;AAID,SAASC,aAAW,OAAoC;AACtD,KAAI,OAAO,UAAU,SACnB;AAGF,QADgB,MAAM,MAAM,IACV,KAAA;;AAGpB,SAASC,aAAW,OAAqD;AACvE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D;AAEF,QAAO;;AAGT,SAAS,kCACP,OAC8D;CAC9D,MAAM,aAAaD,aAAW,MAAM,EAAE,aAAa;AACnD,KAAI,CAAC,WACH,QAAO;AAET,KAAI,EAAE,cAAc,8BAClB,QAAO;AAET,QAAO,6BAA6B,eAAgD;;AAGtF,SAAS,wBAAwB,QAAuD;CACtF,MAAM,sBAAsBC,aAAW,OAAO,IAAI,KAAK,UAAU,OAAO,IAAI,EAAE;AAC9E,QAAO;EACL,IAAI;EACJ,OAAO;EACP,MAAM;EACN,SAAS,oBAAoB,YAAY;EACzC,QAAQ;EACT;;AAGH,SAAgB,2BAA2B,QAKzC;CACA,MAAM,0BAAU,IAAI,KAAgC;AAEpD,SAAQ,IAAI,gCAAgC,wBAAwB,OAAO,OAAO,CAAC;AAEnF,MAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,OAAO,OAAO,OAAO,SAAS,WAAW,EAAE,CAAC,EAAE;EAC3F,MAAM,KAAK,MAAM,MAAM,CAAC,aAAa;EACrC,MAAM,OAAOD,aAAW,SAAS,KAAK,EAAE,aAAa;AACrD,MAAI,CAAC,MAAM,CAAC,KACV;EAEF,MAAM,eAAe,qCAAqC,SAAS,KAAK;EACxE,MAAM,sBACJ,kCAAkC,GAAG,IACrC,kCAAkC,KAAK;AACzC,UAAQ,IAAI,IAAI;GACd;GACA,OAAOA,aAAW,SAAS,MAAM,IAAI,qBAAqB,SAAS;GACnE,GAAI,gBAAgB,qBAAqB,OACrC,EAAE,MAAM,gBAAgB,qBAAqB,MAAM,GACnD,EAAE;GACN;GACA,SAAS,SAAS,YAAY;GAC9B,QAAQ,SAAS,SAAS,EAAE,GAAG,SAAS,QAAQ,GAAG,EAAE;GACtD,CAAC;;AAMJ,QAAO;EACL,gBAJqB,QAAQ,IAAA,SAAmC,GAC9D,iCACA,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC,MAAA;EAGtB,SAAS,CAAC,GAAG,QAAQ,QAAQ,CAAC;EAC/B;;AAGH,SAAS,4BAA4B,iBAAyD;AAC5F,QACE,oBAAoB,gBAAgB,QAAQ,IAC5C,oBAAoB,gBAAgB,aAAa,IACjD,oBAAoB,gBAAgB,YAAY,IAChD;;AAIJ,IAAa,uBAAb,MAAkC;CAChC,4BAA6B,IAAI,KAA+C;CAChF,0BAAkB,IAAI,KAAgC;CACtD,iBAAyB;CAEzB,YAAY,iBAA+D;EACzE,MAAM,iBAAiB,oBAAoB,aAAa,KAAK;AAC7D,MAAI,CAAC,eACH,OAAM,IAAI,MAAM,gDAAgD;EAGlE,MAAM,QAAQ,OAAO,eAAe;AACpC,OAAK,UAAU,IAAI,gBAAgB;GACjC,GAAG;GACH,MAAM;GACN;GACD,CAAC;AAEF,SAAO,mBAAmB;GACxB,MAAM,UAAU,KAAK,UAAU,IAAI,eAAe;AAClD,OAAI,CAAC,WAAW,QAAQ,UAAU,MAChC;AAEF,QAAK,UAAU,OAAO,eAAe;IACrC;;CAGJ,gBAAgB,WAGJ;EACV,MAAM,8BAAc,IAAI,KAAgC;AACxD,OAAK,MAAM,YAAY,OAAO,SAAS;GACrC,MAAM,KAAK,oBAAoB,SAAS,GAAG;GAC3C,MAAM,OAAO,oBAAoB,SAAS,KAAK;GAC/C,MAAM,QAAQ,SAAS,OAAO,MAAM,IAAI;AACxC,OAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MACnB;AAEF,eAAY,IAAI,IAAI,kBAAkB;IACpC,GAAG;IACH;IACA;IACA;IACD,CAAC,CAAC;;AAEL,OAAK,UAAU;AACf,OAAK,iBACH,oBAAoB,OAAO,eAAe,KACzC,YAAY,IAAA,SAAmC,GAAA,WAE5C,CAAC,GAAG,YAAY,MAAM,CAAC,CAAC,MAAA;;CAGhC,0BAA0B,oBAAsE;EAC9F,MAAM,EAAE,UAAU,KAAK,oBAAoB,gBAAgB;AAC3D,SAAO;GACL,GAAG;GACH,SAAS,MAAM;GACf,cAAc,MAAM;GACpB,cAAc,MAAM;GACrB;;CAGH,iBAAiB,WAAkD;EACjE,MAAM,sBAAsB,KAAK,uBAAuB,OAAO,gBAAgB;EAC/E,MAAM,EAAE,OAAO,aAAa,KAAK,oBAAoB,oBAAoB;AACzE,MAAI,SAAS,sBACX,QAAO,SAAS,sBAAsB;GACpC,OAAO,kBAAkB,MAAM;GAC/B,eAAe;IACb,GAAG;IACH,iBAAiB;IAClB;GACF,CAAC;AAEJ,SAAO,SAAS,cAAc;GAC5B,GAAG;GACH,iBAAiB;GAClB,CAAC;;CAGJ,uBAA+B,oBAA6C;EAC1E,MAAM,mBACJ,4BAA4B,gBAAgB,IAAI,KAAK;EACvD,MAAM,QAAQ,KAAK,QAAQ,IAAI,iBAAiB;AAChD,MAAI,CAAC,SAAS,MAAM,YAAY,MAC9B,OAAM,IAAI,MAAM,4BAA4B,mBAAmB;EAGjE,MAAM,WAAW,KAAK,UAAU,IAAI,MAAM,KAAK;AAC/C,MAAI,CAAC,SACH,OAAM,IAAI,MAAM,qCAAqC,MAAM,OAAO;AAEpE,SAAO;GAAE;GAAO;GAAU;;CAG5B,mBAAmB,OAAO,WAGpB;EACJ,MAAM,UAAU,MAAM,QAAQ,IAC5B,CAAC,GAAG,KAAK,QAAQ,QAAQ,CAAC,CACvB,QAAQ,UAAU,MAAM,YAAY,MAAM,CAC1C,IAAI,OAAO,UAAU;GACpB,MAAM,WAAW,KAAK,UAAU,IAAI,MAAM,KAAK;AAC/C,OAAI,CAAC,SACH,QAAO;IACL,OAAO,MAAM;IACb,OAAO,MAAM;IACb,MAAM,MAAM,QAAQ;IACpB,OAAO;IACP,QAAQ;IACR,eAAe,0CAA0C,MAAM,KAAK;IACpE,kBAAkB;IAClB,KAAK;KACH,MAAM;KACN,OAAO;KACR;IACF;GAGH,MAAM,aAAa,SAAS,8BACxB,MAAM,SAAS,4BAA4B;IACzC,OAAO,kBAAkB,MAAM;IAC/B,gBAAgB;IACjB,CAAC,GACF,MAAM,SAAS,sBAAsB,OAAO;AAChD,UAAO;IACL,OAAO,MAAM;IACb,OAAO,MAAM;IACb,MAAM,YAAY,QAAQ,MAAM,QAAQ;IACxC,OAAO,YAAY,SAAS;IAC5B,QAAQ,YAAY,UAAU;IAC9B,eAAe,YAAY,iBAAiB;IAC5C,kBAAkB,YAAY,oBAAoB;IAClD,KAAK,YAAY,OAAO;IACxB,GAAI,YAAY,kBAAkB,EAAE,iBAAiB,WAAW,iBAAiB,GAAG,EAAE;IACvF;IACD,CACL;AAED,SAAO;GACL,aAAa,KAAK;GAClB,SAAS,QAAQ,MAAM,MAAM,UAAU;AACrC,QAAI,KAAK,UAAU,KAAK,eACtB,QAAO;AAET,QAAI,MAAM,UAAU,KAAK,eACvB,QAAO;AAET,WAAO,KAAK,MAAM,cAAc,MAAM,MAAM;KAC5C;GACH;;;;;AC/WL,IAAa,sBAAb,MAAiC;CAC/B,kBAAmC,IAAI,sBAAsB;CAC7D,wCAAyD;AACvD,OAAK,gBAAgB,aACnB,2BAA2B,EACzB,QAAQ,KAAK,OAAO,cAAc,YAAY,EAC/C,CAAC,CACH;;CAGH,WAAmB;CAEnB,YAAY,QAAqD;AAApC,OAAA,SAAA;;CAE7B,2BAA2B,iBAA+D;AACxF,OAAK,mBAAmB;EACxB,MAAM,aAAa,KAAK,gBAAgB,SAAS,aAAa;AAC9D,OAAK,iCAAiC;AACtC,SAAO;;CAGT,iBAAiB,kBAAwC;AACvD,OAAK,mBAAmB;AACxB,OAAK,iCAAiC;AACtC,SAAO,KAAK,gBAAgB,cAAc;GACxC,GAAG;GACH,0BAA0B,aAAa,KAAK,OAAO,WAAW,mBAAmB,SAAS;GAC3F,CAAC;;CAGJ,0BAA0B,oBAAsE;AAC9F,OAAK,mBAAmB;AACxB,OAAK,iCAAiC;AACtC,SAAO,KAAK,gBAAgB,uBAAuB,gBAAgB;;CAGrE,oBAAoB,mBAA2D;AAC7E,OAAK,iCAAiC;AACtC,SAAO,KAAK,gBAAgB,iBAAiB,eAAe;;CAG9D,UAAU,YAA2B;AACnC,MAAI,KAAK,SACP;AAEF,OAAK,WAAW;;CAGlB,0BAAiD;AAC/C,MAAI,KAAK,SACP,OAAM,IAAI,MAAM,2CAA2C;;;;;AC/DjE,IAAa,oBAAb,cAAuC,YAAY;CACjD,YAAY,SAAmC;AAC7C,QAAM,QAAQ,UAAU;;;;;AC+B5B,MAAM,WAAW,QAAwB,WAAW,SAAS,CAAC,OAAO,IAAI,CAAC,OAAO,MAAM;AAEvF,MAAM,aAAa,MAA+B,UAA4D;CAC5G,MAAM,OAAgC,EAAE,GAAG,MAAM;AACjD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE;AAChD,MAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,EAAE;GAC/D,MAAM,UAAU,KAAK;AACrB,QAAK,OAAO,WAAW,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,QAAQ,GACzE,UAAU,SAAoC,MAAiC,GAC/E,UAAU,EAAE,EAAE,MAAiC;AACnD;;AAEF,OAAK,OAAO;;AAEd,QAAO;;AAGT,IAAa,gBAAb,MAA2B;CACzB;CACA;CACA,QAA2C,EAAE;CAC7C,aAA2C;CAC3C,qBAAmD;CACnD,cAA4D;CAC5D,gBAAwB;CACxB,gBAAwB;CAExB,YAAY,SAAgD;AAA/B,OAAA,UAAA;AAC3B,OAAK,aAAa,QAAQ,cAAc,eAAe;AACvD,OAAK,gBAAgB,KAAK,YAAY;AACtC,OAAK,QAAQ,gBAAgB,KAAK,KAAK,cAAc;AACrD,OAAK,QAAQ,SAAS,KAAK;GACzB,eAAe,KAAK,qBAAqB,KAAK,cAAc;GAC5D,mBAAmB,KAAK,0BAA0B;GACnD,CAAC;;CAGJ,IAAI,SAAiB;AACnB,SAAO,KAAK;;CAGd,mBACE,qBAAqB,WAAW,KAAK,WAAW,EAAE,EAAE,YAAY,KAAK,YAAY,CAAC;CAEpF,wBACE,KAAK,YAAY,CAAC,OAAO,SAAS;CAEpC,qBAAqB,UAAsC;EACzD,MAAM,QAAQ,KAAK,YAAY,CAAC,OAAO,SAAS,OAAO,QAAQ,QAAQ;AACvE,SAAO,OAAO,UAAU,WAAW,KAAK,MAAM,MAAM,GAAG,KAAA;;CAGzD,uBAAuB,UAA2C;AAChE,OAAK,QAAQ;GAAE,GAAG,KAAK;GAAO,GAAG;GAAO;;CAG1C,wBAAwB,YAA2B;AACjD,QAAM,KAAK,gBAAgB,KAAK,YAAY,CAAC;;CAG/C,kBAAkB,OAAO,eAAsC;EAC7D,MAAM,eAAe,gBAAgB,KAAK,eAAe,WAAW;AACpE,MAAI,CAAC,aAAa,OAChB;AAEF,OAAK,gBAAgB;EACrB,MAAM,OAAO,gBAAgB,aAAa;AAE1C,MAAI,KAAK,WAAW;AAClB,SAAM,KAAK,UAAU;IACnB,QAAQ;IACR;IACD,CAAC;AACF,WAAQ,IAAI,uCAAuC;;AAErD,MAAI,KAAK,iBAAiB;AACxB,SAAM,KAAK,gBAAgB;IACzB,QAAQ;IACR;IACD,CAAC;AACF,WAAQ,IAAI,4CAA4C;;AAE1D,MAAI,KAAK,iBAAiB;AACxB,SAAM,KAAK,gBAAgB,YAAY,EAAE,OAAO,MAAM,CAAC;AACvD,WAAQ,IAAI,qCAAqC;;AAEnD,MAAI,KAAK,iBAAiB;AACxB,SAAM,KAAK,eAAe,WAAW;AACrC,WAAQ,IAAI,4CAA4C;;AAE1D,MAAI,KAAK,aAAa;AACpB,QAAK,MAAM,0BAA0B,WAAW;AAChD,WAAQ,IAAI,yCAAyC;;AAEvD,MAAI,KAAK,gBAAgB,SAAS,EAChC,MAAK,MAAM,oBAAoB,KAAK,gBAAgB;;CAIxD,qBAAqB,SAA+B,EAAE,KAA8B;EAClF,MAAM,EAAE,MAAM,KAAK,UAAU,UAAU,KAAK,mBAAmB,OAAO;AACtE,SAAO;GACL;GACA;GACA,MAAM,KAAK;GACX,QAAQ;GACR,QAAQ;GACR,UAAU;GACV;GACD;;CAGH,mBAAmB,SAA+B,EAAE,KAA8B,kBAAkB,EAAE,SAAS,OAAO,SAAS,CAAC;CAEhI,iBAAiB,OAAO,WACtB,KAAK,gBAAgB,SAAS,WAAW,WAAW,OAAO;CAE7D,iBAAiB,OAAO,WACtB,KAAK,gBAAgB,SAAS,UAAU,UAAU,UAAU,SAAS,QAAmC,MAAM,CAAC;CAEjH,kBAAkB,WAAyB;AACzC,MAAI,KAAK,YACP,cAAa,KAAK,YAAY;AAEhC,OAAK,cAAc,iBAAiB;AAC7B,QAAK,UAAU,OAAO;KAC1B,IAAI;;CAGT,YAAY,OAAO,WAAkC;AACnD,MAAI,KAAK,eAAe;AACtB,QAAK,gBAAgB;AACrB;;AAEF,OAAK,gBAAgB;AACrB,MAAI,KAAK,aAAa;AACpB,gBAAa,KAAK,YAAY;AAC9B,QAAK,cAAc;;AAErB,MAAI;AACF,SAAM,KAAK,uBAAuB;WAC3B,OAAO;AACd,WAAQ,MAAM,yBAAyB,OAAO,KAAK,OAAO,MAAM,GAAG;YAC3D;AACR,QAAK,gBAAgB;AACrB,OAAI,KAAK,eAAe;AACtB,SAAK,gBAAgB;AACrB,SAAK,eAAe,UAAU;;;;CAKpC,eAAe,OAAO,WAAqC;AACzD,QAAM,KAAK,UAAU,UAAU,eAAe;AAC9C,SAAO;;CAGT,kBAAkB,OAAO,YAAoB,UAA+B,EAAE,KAAoB;AAChG,MAAI,KAAK,YAAY;AACnB,SAAM,KAAK;AACX;;AAEF,OAAK,cAAc,YAAY;AAC7B,SAAM,KAAK,QAAQ,SAAS,OAAO;IACjC,eAAe,KAAK,qBAAqB,WAAW;IACpD,mBAAmB,KAAK,0BAA0B;IAClD,OAAO,QAAQ,SAAS;IACzB,CAAC;MACA;AACJ,MAAI;AACF,SAAM,KAAK;YACH;AACR,QAAK,aAAa;;;CAItB,wBAAgC,WAC9B,KAAK,MAAM,uBAAuB,OAAO,IAAI;CAE/C,iCACE,KAAK,MAAM,wBAAwB,IAAI,EAAE;CAE3C,iBAAyB,OAAO,eAAsC;AACpE,MAAI,KAAK,oBAAoB;AAC3B,SAAM,KAAK;AACX;;AAEF,OAAK,sBAAsB,YAAY;AACrC,QAAK,QAAQ,gBAAgB,KAAK,WAAW;MAC3C;AACJ,MAAI;AACF,SAAM,KAAK;YACH;AACR,QAAK,qBAAqB;;;CAI9B,YAAoB,OAAO,WAGN;AACnB,QAAM,KAAK,MAAM,YAAY,OAAO;;CAGtC,kBAA0B,OAAO,WAGZ;AACnB,QAAM,KAAK,MAAM,kBAAkB,OAAO;;CAG5C,sBAA8B,SAA+B,EAAE,KAAqB;EAClF,IAAI,MAAM;EACV,IAAI,SAAkC,EAAE;AACxC,MAAI,WAAW,KAAK,WAAW,EAAE;AAC/B,SAAM,aAAa,KAAK,YAAY,QAAQ;AAC5C,OAAI;AACF,aAAS,KAAK,MAAM,IAAI;WAClB;AACN,aAAS,EAAE;;;EAIf,IAAI;EACJ,IAAI,QAAQ;AACZ,MAAI;AACF,YAAS,aAAa,MAAM,0BAA0B,OAAO,CAAC;UACxD;AACN,YAAS,aAAa,MAAM,EAAE,CAAC;AAC/B,WAAQ;;AAEV,MAAI,CAAC,IACH,OAAM,KAAK,UAAU,QAAQ,MAAM,EAAE;EAEvC,MAAM,OAAO,QAAQ,IAAI;AACzB,SAAO;GACL,KAAK,QAAQ,KAAK,UAAU,KAAK,aAAa,QAAQ,OAAO,EAAE,MAAM,EAAE,GAAG;GAC1E,MAAM,QAAQ,OAAO;GACrB;GACA,UAAU,KAAK,aAAa,QAAQ,OAAO;GAC3C;GACD;;CAGH,gBAAwB,QAAgB,SAA+B,EAAE,KAA8B;AAErG,SAAO,mBAAmB,QADX,kBAAkB,EAAE,SAAS,OAAO,SAAS,CAAC,CACpB,QAAQ;;CAGnD,oBAA4B,UAA8B,aAA0D;AAClH,MAAI,CAAC,SACH,QAAO;GAAE,IAAI;GAAO,OAAO;GAA0D;AAEvF,MAAI,CAAC,SAAS,SAAS,CAAC,SAAS,KAC/B,QAAO;GAAE,IAAI;GAAO,OAAO;GAA6D;AAE1F,MAAI,aAAa,SAAS,KACxB,QAAO;GAAE,IAAI;GAAO,OAAO;GAA+D;AAE5F,SAAO;;CAGT,uBAA+B,UAAgG;AAC7H,MAAI;AACF,UAAO;IAAE,IAAI;IAAM,QAAQ,aAAa,MAAM,0BAA0B,MAAM,CAAC;IAAE;WAC1E,OAAO;AACd,UAAO;IAAE,IAAI;IAAO,OAAO,mBAAmB,OAAO,MAAM;IAAI;;;CAInE,kBAA0B,OACxB,QACA,iBACkC;EAClC,MAAM,EAAE,UAAU,MAAM,KAAK,YAAY;EACzC,MAAM,WAAW,KAAK,mBAAmB,EAAE,SAAS,CAAC;EACrD,MAAM,qBAAqB,KAAK,iBAAiB,UAAU,SAAS;AACpE,MAAI,mBACF,QAAO;EAGT,IAAI;AACJ,MAAI;AACF,YAAS,KAAK,MAAM,IAAI;UAClB;AACN,UAAO;IAAE,IAAI;IAAO,OAAO;IAA8B;;EAG3D,MAAM,YAAY,KAAK,oBAAoB,aAAa,UAAU,OAAO,CAAC;AAC1E,SAAO,UAAU,KACb,KAAK,kBAAkB;GAAE,YAAY,UAAU;GAAQ;GAAM;GAAS,CAAC,GACvE;;CAGN,oBAA4B,OAAO,WAIE;EACnC,MAAM,EAAE,YAAY,MAAM,YAAY;EACtC,MAAM,eAAe,gBAAgB,KAAK,mBAAmB,EAAE,SAAS,CAAC,CAAC,QAAQ,WAAW;AAE7F,MAAI,aAAa,WAAW,EAC1B,QAAO,KAAK,2BAA2B;GACrC;GACA,QAAQ;GACR;GACA;GACD,CAAC;AAGJ,aAAW,YAAY,KAAK,WAAW;AACvC,QAAM,KAAK,gBAAgB,WAAW;AACtC,SAAO,KAAK,2BAA2B;GACrC;GACA,QAAQ;GACR;GACA;GACD,CAAC;;CAGJ,8BAAsC,WAKV;EAC1B,MAAM,EAAE,cAAc,QAAQ,MAAM,YAAY;EAChD,MAAM,OAAO,gBAAgB,aAAa;EAC1C,MAAM,iBACJ,KAAK,gBAAgB,SAAS,IAC1B;GACE,UAAU;GACV,WAAW;GACX,cAAc,CAAC,GAAG,KAAK,gBAAgB;GACvC,SAAS,4CAA4C,KAAK,gBAAgB,KAAK,KAAK,CAAC;GACtF,GACD;EACN,MAAM,UACJ,aAAa,WAAW,IACpB,gDACA,iBACE,aAAa,SAAS,KAAK,gBAAgB,SACzC,kGACA,qDACF;AAER,SAAO;GACL,IAAI;GACJ,MAAM,QAAQ;GACd,MAAM,KAAK;GACX,QAAQ,KAAK,aAAa,QAAQ,EAAE,SAAS,CAAC;GAC9C,cAAc,CAAC,GAAG,aAAa;GAC/B;GACA;GACD;;;;;ACpYL,SAAS,6BAA6B,OAA+C;AACnF,KAAI,CAAC,OAAO,MAAM,CAChB;CAEF,MAAM,SAAS,MAAM,MAAM,MAAM,CAAC,OAAO,QAAQ;CACjD,MAAM,YAAsB,EAAE;AAC9B,MAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;EACrD,MAAM,QAAQ,OAAO;AACrB,MAAI,UAAU,8BAA8B,UAAU,iBACpD;AAEF,OAAK,UAAU,kBAAkB,UAAU,SAAS,OAAO,QAAQ,OAAO,eAAe;AACvF,YAAS;AACT;;AAEF,YAAU,KAAK,MAAM;;AAEvB,QAAO,UAAU,SAAS,IAAI,UAAU,KAAK,IAAI,GAAG,KAAA;;AAGtD,IAAa,4BAAb,MAAuC;CACrC,4BAA6B,IAAI,KAAsC;CAEvE,YAAY,WAAgC,WAGX;EAC/B,MAAM,UAAqC,EAAE;AAC7C,OAAK,MAAM,YAAY,UACrB,KAAI;AACF,WAAQ,KAAK,KAAK,MAAM,UAAU,OAAO,CAAC;WACnC,OAAO;AACd,WAAQ,KAAK,aAAa,SAAS,GAAG,oBAAoB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAAG;;AAGvH,SAAO;;CAGT,UAAU,YAA2B;EACnC,MAAM,YAAY,CAAC,GAAG,KAAK,UAAU,QAAQ,CAAC;AAC9C,OAAK,UAAU,OAAO;AACtB,QAAM,QAAQ,IAAI,UAAU,IAAI,OAAO,EAAE,cAAc;AACrD,OAAI,QAAQ,aAAa,QAAQ,QAAQ,eAAe,KACtD;AAEF,WAAQ,MAAM;AACd,SAAM,IAAI,SAAe,mBAAmB;AAC1C,YAAQ,KAAK,cAAc,gBAAgB,CAAC;AAC5C,YAAQ,KAAK,eAAe,gBAAgB,CAAC;AAC7C,eAAW,gBAAgB,IAAK,CAAC,OAAO;KACxC;IACF,CAAC;;CAGL,SACE,UACA,WAI4B;EAC5B,MAAM,WAAW,KAAK,UAAU,IAAI,SAAS,GAAG;AAChD,MAAI,SACF,QAAO;EAKT,MAAM,QAAQ,MAHE,SAAS,OAAO,YAAY,UAAU,SAAS,OAAO,YAAY,aAC9E,QAAQ,WACR,SAAS,OAAO,SACS,SAAS,OAAO,QAAQ,EAAE,EAAE;GACvD,KAAK,SAAS;GACd,KAAK;IACH,GAAG,QAAQ;IACX,cAAc,6BAA6B,QAAQ,IAAI,aAAa;IACpE,GAAG,SAAS,OAAO;IACnB,uBAAuB,SAAS;IAChC,6BAA6B,OAAO;IACpC,0BAA0B,OAAO;IAClC;GACD,OAAO;IAAC;IAAU;IAAU;IAAU;GACtC,aAAa;GACd,CAAC;EACF,MAAM,UAAU;GAAE;GAAU,SAAS;GAAO;AAC5C,OAAK,UAAU,IAAI,SAAS,IAAI,QAAQ;AACxC,QAAM,KAAK,cAAc;AACvB,OAAI,KAAK,UAAU,IAAI,SAAS,GAAG,EAAE,YAAY,MAC/C,MAAK,UAAU,OAAO,SAAS,GAAG;AAEpC,WAAQ,KAAK,aAAa,SAAS,GAAG,UAAU;IAChD;AACF,QAAM,KAAK,UAAU,UAAU;AAC7B,WAAQ,KAAK,aAAa,SAAS,GAAG,WAAW,MAAM,UAAU;IACjE;AACF,SAAO;;;;;AC1FX,MAAM,0BAA0B;AAChC,MAAM,6BAA6B;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AACD,MAAM,iBAAiB,cAAc,OAAO,KAAK,IAAI;AAErD,SAASE,aAAW,OAAoC;AACtD,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,KAAA;;AAGpE,SAAS,gBAAgB,OAAsC;AAC7D,QAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,OAAO,SAAS,OAAO,SAAS,SAAS,GAAG,QAAQ,KAAA;;AAG3F,SAAS,iBAAiB,OAAoD;AAC5E,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D;CAEF,MAAM,UAAU,OAAO,QAAQ,MAAM;AACrC,QAAO,QAAQ,OAAO,GAAG,UAAU,OAAO,SAAS,SAAS,GACxD,OAAO,YAAY,QAAQ,GAC3B,KAAA;;AAGN,SAASC,aAAW,OAAyC;AAC3D,QAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,GAC9D,QACA,EAAE;;AAGR,SAAS,YAAY,OAA2B;CAC9C,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,aAAa,QAAQ,KAAK;AAChC,MAAI,CAAC,KAAK,IAAI,WAAW,EAAE;AACzB,QAAK,IAAI,WAAW;AACpB,UAAO,KAAK,WAAW;;;AAG3B,QAAO;;AAGT,SAAS,0BAA0B,WAAuC;CACxE,IAAI,UAAU,QAAQ,UAAU;AAChC,QAAO,MAAM;AACX,MAAI,WAAW,KAAK,SAAS,wBAAwB,CAAC,CACpD,QAAO;EAET,MAAM,SAAS,QAAQ,QAAQ;AAC/B,MAAI,WAAW,QACb;AAEF,YAAU;;;AAId,SAAS,iCACP,cAAc,QAAQ,IAAI,wCAC1B,YAAY,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EAC/B;CACpB,MAAM,aAAa,aAAa,MAAM;AACtC,KAAI,WACF,QAAO;AAQT,QANmB;EACjB,QAAQ,WAAW,mBAAmB;EACtC,QAAQ,WAAW,sBAAsB;EACzC,QAAQ,WAAW,yBAAyB;EAC5C,QAAQ,WAAW,4BAA4B;EAChD,CACiB,MAAM,cAAc,WAAW,UAAU,CAAC;;AAG9D,SAAS,WAAW,OAAgB,SAAoC;AACtE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,OAAM,IAAI,MAAM,uCAAuC;CAEzD,MAAM,SAAS;CACf,MAAM,SAASA,aAAW,OAAO,OAAO;CACxC,MAAM,KAAKD,aAAW,OAAO,GAAG;CAChC,MAAM,UAAUA,aAAW,OAAO,QAAQ;AAC1C,KAAI,CAAC,GACH,OAAM,IAAI,MAAM,oCAAoC;AAEtD,KAAI,OAAO,SAAS,QAClB,OAAM,IAAI,MAAM,sCAAsC;AAExD,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,uCAAuC;AAEzD,QAAO;EACL;EACA;EACA,GAAIA,aAAW,OAAO,KAAK,GAAG,EAAE,MAAMA,aAAW,OAAO,KAAK,EAAE,GAAG,EAAE;EACpE,GAAIA,aAAW,OAAO,QAAQ,GAAG,EAAE,SAASA,aAAW,OAAO,QAAQ,EAAE,GAAG,EAAE;EAC7E,QAAQ;GACN,MAAM;GACN;GACA,GAAI,gBAAgB,OAAO,KAAK,GAAG,EAAE,MAAM,gBAAgB,OAAO,KAAK,EAAE,GAAG,EAAE;GAC9E,GAAI,iBAAiB,OAAO,IAAI,GAAG,EAAE,KAAK,iBAAiB,OAAO,IAAI,EAAE,GAAG,EAAE;GAC9E;EACD,GAAI,OAAO,eAAe,OAAO,OAAO,gBAAgB,YAAY,CAAC,MAAM,QAAQ,OAAO,YAAY,GAClG,EAAE,aAAa,OAAO,aAAiD,GACvE,EAAE;EACP;;AAGH,SAAgB,uCAAiD;AAC/D,KAAI,QAAQ,IAAI,wCAAwC,IACtD,QAAO,EAAE;CAEX,MAAM,QAAkB,EAAE;AAC1B,MAAK,MAAM,eAAe,2BACxB,KAAI;EAEF,MAAM,OAAO,0BAA0B,QADrB,eAAe,QAAQ,YAAY,CACI,CAAC;AAC1D,MAAI,KACF,OAAM,KAAK,KAAK;SAEZ;AAIV,QAAO,YAAY,MAAM;;AAG3B,SAAgB,8BAA8B,QAGjC;CACX,MAAM,mBAAmB,kCAAkC;AAC3D,QAAO,YAAY;EACjB,KAAK,aAAa,EAAE,aAAa;EACjC,KAAK,OAAO,WAAW,aAAa,aAAa;EACjD,GAAI,mBAAmB,CAAC,iBAAiB,GAAG,EAAE;EAC9C,GAAG,sCAAsC;EAC1C,CAAC;;AAGJ,IAAa,oCAAb,MAA+C;CAC7C,WAAW,OAAO,UAAkD;EAClE,MAAM,YAAiC,EAAE;AACzC,OAAK,MAAM,QAAQ,MACjB,WAAU,KAAK,GAAI,MAAM,KAAK,aAAa,KAAK,CAAE;AAEpD,SAAO,KAAK,WAAW,UAAU;;CAGnC,gBAAgB,UAAyC;EACvD,MAAM,YAAiC,EAAE;AACzC,OAAK,MAAM,QAAQ,MACjB,WAAU,KAAK,GAAG,KAAK,iBAAiB,KAAK,CAAC;AAEhD,SAAO,KAAK,WAAW,UAAU;;CAGnC,cAAsB,cAAwD;EAC5E,MAAM,uBAAO,IAAI,KAAa;EAC9B,MAAM,SAA8B,EAAE;AACtC,OAAK,MAAM,YAAY,WAAW;AAChC,OAAI,KAAK,IAAI,SAAS,GAAG,CACvB;AAEF,QAAK,IAAI,SAAS,GAAG;AACrB,UAAO,KAAK,SAAS;;AAEvB,SAAO;;CAGT,eAAuB,OAAO,SAA+C;EAC3E,MAAM,iBAAiB,MAAM,KAAK,qBAAqB,KAAK,MAAM,wBAAwB,CAAC;AAC3F,MAAI,eACF,QAAO,CAAC,eAAe;EAEzB,MAAM,UAAU,MAAM,QAAQ,MAAM,EAAE,eAAe,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC;AAM5E,UALkB,MAAM,QAAQ,IAC9B,QACG,QAAQ,UAAU,MAAM,aAAa,CAAC,CACtC,KAAK,UAAU,KAAK,qBAAqB,KAAK,MAAM,MAAM,MAAM,wBAAwB,CAAC,CAAC,CAC9F,EACgB,QAAQ,aAA4C,QAAQ,SAAS,CAAC;;CAGzF,oBAA4B,SAAsC;EAChE,MAAM,iBAAiB,KAAK,yBAAyB,KAAK,MAAM,wBAAwB,CAAC;AACzF,MAAI,eACF,QAAO,CAAC,eAAe;AAEzB,SAAO,KAAK,oBAAoB,KAAK,CAClC,KAAK,UAAU,KAAK,yBAAyB,KAAK,MAAM,OAAO,wBAAwB,CAAC,CAAC,CACzF,QAAQ,aAA4C,QAAQ,SAAS,CAAC;;CAG3E,uBAA+B,OAAO,SAAoD;AACxF,MAAI;AACF,UAAO,WAAW,KAAK,MAAM,MAAM,SAAS,MAAM,QAAQ,CAAC,EAAE,QAAQ,KAAK,CAAC;WACpE,OAAO;AACd,OAAK,MAAgC,SAAS,SAC5C,QAAO;AAET,SAAM;;;CAIV,4BAAoC,SAA2C;AAC7E,MAAI;AACF,UAAO,WAAW,KAAK,MAAM,aAAa,MAAM,QAAQ,CAAC,EAAE,QAAQ,KAAK,CAAC;WAClE,OAAO;AACd,OAAK,MAAgC,SAAS,SAC5C,QAAO;AAET,SAAM;;;CAIV,uBAA+B,SAA2B;AACxD,MAAI;AACF,UAAO,YAAY,MAAM,EAAE,eAAe,MAAM,CAAC,CAC9C,QAAQ,UAAU,MAAM,aAAa,CAAC,CACtC,KAAK,UAAU,MAAM,KAAK;UACvB;AACN,UAAO,EAAE;;;;;;ACzOf,SAAgB,wBAAwB,QAG3B;CAEX,MAAM,YADY,IAAI,mCAAmC,CAC7B,aAAa,8BAA8B,OAAO,CAAC;CAC/E,MAAM,aAAuB,EAAE;AAC/B,MAAK,MAAM,YAAY,UACrB,MAAK,MAAM,WAAW,SAAS,aAAa,YAAY,EAAE,EAAE;EAC1D,MAAM,YAAY,OAAO,QAAQ,OAAO,WAAW,QAAQ,GAAG,MAAM,GAAG;AACvE,MAAI,aAAa,CAAC,WAAW,SAAS,UAAU,CAC9C,YAAW,KAAK,UAAU;;AAIhC,QAAO;;;;ACcT,MAAM,+BAA+B;AACrC,MAAM,+BAA+B;AAKrC,SAASE,aAAW,OAAoC;AACtD,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,KAAA;;AAGpE,SAASC,aAAW,OAAyC;AAC3D,QAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,GAC9D,QACA,EAAE;;AAGR,SAASC,qBAAmB,OAAgB,MAAsB;CAChE,MAAM,UAAUF,aAAW,MAAM;AACjC,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,GAAG,KAAK,cAAc;AAExC,QAAO;;AAGT,SAAS,gBAAgB,OAAwB;CAC/C,MAAM,UAAUC,aAAW,MAAM;AACjC,KAAI,QAAQ,SAAS,UAAU,OAAO,QAAQ,SAAS,SACrD,OAAM,IAAI,MAAM,uEAAuE;AAEzF,QAAO,QAAQ;;AAGjB,SAAS,mBAAmB,OAAoC;AAC9D,QAAO,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,GAAG,QAAQ,KAAA;;AAGvE,SAAS,uBAAuB,OAAqC;AACnE,KAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,QAAO,EAAE;AAEX,QAAO,MACJ,QAAQ,UACP,QAAQ,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,CAAC,CACrE,CACA,KAAK,WAAW;EACf,GAAID,aAAW,MAAM,GAAG,GAAG,EAAE,IAAIA,aAAW,MAAM,GAAG,EAAE,GAAG,EAAE;EAC5D,GAAIA,aAAW,MAAM,KAAK,GAAG,EAAE,MAAMA,aAAW,MAAM,KAAK,EAAE,GAAG,EAAE;EAClE,GAAIA,aAAW,MAAM,KAAK,GAAG,EAAE,MAAMA,aAAW,MAAM,KAAK,EAAE,GAAG,EAAE;EAClE,GAAIA,aAAW,MAAM,IAAI,GAAG,EAAE,KAAKA,aAAW,MAAM,IAAI,EAAE,GAAG,EAAE;EAC/D,GAAIA,aAAW,MAAM,SAAS,GAAG,EAAE,UAAUA,aAAW,MAAM,SAAS,EAAE,GAAG,EAAE;EAC9E,GAAIA,aAAW,MAAM,SAAS,GAAG,EAAE,UAAUA,aAAW,MAAM,SAAS,EAAE,GAAG,EAAE;EAC9E,GAAI,mBAAmB,MAAM,KAAK,KAAK,KAAA,IAAY,EAAE,MAAM,mBAAmB,MAAM,KAAK,EAAE,GAAG,EAAE;EAChG,GAAIA,aAAW,MAAM,OAAO,GAAG,EAAE,QAAQA,aAAW,MAAM,OAAO,EAAE,GAAG,EAAE;EACxE,GAAI,MAAM,WAAW,WAAW,MAAM,WAAW,gBAAgB,EAAE,QAAQ,MAAM,QAAQ,GAAG,EAAE;EAC9F,GAAIA,aAAW,MAAM,UAAU,GAAG,EAAE,WAAWA,aAAW,MAAM,UAAU,EAAoC,GAAG,EAAE;EACpH,EAAE;;AAGP,SAAS,iBAAiB,OAAgC;CACxD,MAAM,UAAUC,aAAW,MAAM;AACjC,QAAO;EACL,SAASC,qBAAmB,QAAQ,WAAW,YAAY;EAC3D,QAAQA,qBAAmB,QAAQ,gBAAgB,iBAAiB;EACpE,UAAUA,qBAAmB,QAAQ,UAAU,WAAW;EAC1D,SAAS,gBAAgB,QAAQ,QAAQ;EACzC,2BAAW,IAAI,MAAM;EACrB,aAAa,uBAAuB,QAAQ,YAAY;EACxD,UAAUD,aAAW,QAAQ,SAAS;EACvC;;AAGH,SAAS,6BAA6B,OAAyC;AAE7E,QAAOA,aADQA,aAAW,MAAM,CACP,cAAc;;AAGzC,SAAS,yBAAyB,OAAiD;CACjF,MAAM,SAASA,aAAW,MAAM;AAChC,QAAO;EACL,eAAe,6BAA6B,OAAO;EACnD,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;EACrE,OAAO,MAAM,QAAQ,OAAO,MAAM,GAAG,OAAO,MAAM,QAAQ,SAAyB,OAAO,SAAS,SAAS,GAAG,EAAE;EAClH;;AAGH,SAAS,wBAAwB,OAAuD;AACtF,KAAI,CAAC,MACH,QAAO;CAET,MAAM,SAASA,aAAW,MAAM;AAChC,QAAO;EACL,SAASC,qBAAmB,OAAO,SAAS,UAAU;EACtD,QAAQ,OAAO;EACf,SAASF,aAAW,OAAO,QAAQ;EACnC,YAAY,mBAAmB,OAAO,WAAW;EACjD,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;EACrE,OAAO,MAAM,QAAQ,OAAO,MAAM,GAAG,OAAO,MAAM,QAAQ,SAAyB,OAAO,SAAS,SAAS,GAAG,EAAE;EACjH,eAAe,6BAA6B,OAAO;EACpD;;AAGH,IAAM,yBAAN,MAA6F;CAC3F,YACE,QAKA;AALiB,OAAA,SAAA;;CAOnB,QAAsD,OAAO,EAAE,WAAW,SAAS,cACjF,yBAAyB,MAAM,KAAK,OAAO,QAAQ;EACjD,aAAa,KAAK,OAAO;EACzB,MAAM;EACN,SAAS;GACP,WAAW,KAAK,OAAO;GACvB;GACA;GACA;GACD;EACF,CAAC,CAAC;CAEL,QAAsD,OAAO,WAC3D,MAAM,KAAK,OAAO,QAAyC;EACzD,aAAa,KAAK,OAAO;EACzB,MAAM;EACN,SAAS;GACP,WAAW,KAAK,OAAO;GACvB,WAAW,OAAO;GAClB,SAAS,OAAO;GAChB,QAAS,OAAsC;GAChD;EACF,CAAC;CAEJ,UAA0D,OAAO,WAC/D,wBAAwB,MAAM,KAAK,OAAO,QAA2C;EACnF,aAAa,KAAK,OAAO;EACzB,MAAM;EACN,SAAS;GACP,WAAW,KAAK,OAAO;GACvB,WAAW,OAAO;GAClB,QAAQ,OAAO;GACf,QAAQ,OAAO;GAChB;EACF,CAAC,CAAC;CAEL,OAAoD,OAAO,EAAE,gBAC3D,wBAAwB,MAAM,KAAK,OAAO,QAAQ;EAChD,aAAa,KAAK,OAAO;EACzB,MAAM;EACN,SAAS;GACP,WAAW,KAAK,OAAO;GACvB;GACD;EACF,CAAC,CAAC;CAEL,WAA0D,OAAO,EAAE,IAAI,MAAM,WAAW,SAAS,OAAO,eACtG,MAAM,KAAK,OAAO,QAAQ;EACxB,aAAa,KAAK,OAAO;EACzB,MAAM;EACN,SAAS;GACP,WAAW,KAAK,OAAO;GACvB;GACA;GACA;GACA;GACA;GACA;GACD;EACF,CAAC;;AAGN,IAAa,0BAAb,MAAqC;CACnC,QAAiB,YAAY;CAC7B,YAA6B,IAAI,2BAA2B;CAC5D,kCAAmC,IAAI,KAAsC;CAC7E,YAAyC,EAAE;CAE3C,YAAY,SAA0D;AAAzC,OAAA,UAAA;;CAE7B,gCAA+C;AAC7C,OAAK,QAAQ,QAAQ,WACnB,YAAY,UAAU,kBACtB,KAAK,uBACN;AACD,OAAK,QAAQ,QAAQ,WACnB,YAAY,UAAU,sBACtB,KAAK,2BACN;AACD,OAAK,QAAQ,QAAQ,WACnB,YAAY,UAAU,oBACtB,KAAK,yBACN;AACD,OAAK,QAAQ,QAAQ,WACnB,YAAY,UAAU,uBACtB,KAAK,4BACN;AACD,OAAK,QAAQ,QAAQ,WACnB,YAAY,UAAU,UACtB,KAAK,wBACN;;CAGH,2BAAoC,OAAO,WAGG;AAC5C,OAAK,YAAY,MAAM,KAAK,kBAAkB,OAAO;AACrD,SAAO,KAAK,gBAAgB,KAAK,UAAU;;CAG7C,QAAiB,OAAO,WAAuD;EAC7E,MAAM,WAAW,OAAO,UAAU,MAAM;AACxC,MAAI,CAAC,SACH;EAEF,MAAM,YAAY,KAAK,UAAU,SAAS,IACtC,KAAK,YACL,MAAM,KAAK,kBAAkB;GAC3B,QAAQ,KAAK,QAAQ,WAAW;GAChC,WAAW,KAAK,QAAQ,cAAc;GACvC,CAAC;EACN,MAAM,UAAU,KAAK,UAAU,SAAS,WAAW;GACjD;GACA,OAAO,KAAK;GACb,CAAC;AACF,MAAI,QAAQ,SAAS,EACnB,SAAQ,IAAI,yBAAyB,QAAQ,KAAK,UAAU,MAAM,SAAS,GAAG,CAAC,KAAK,KAAK,GAAG;;CAIhG,OAAgB,YAA2B;AACzC,QAAM,KAAK,UAAU,SAAS;AAC9B,OAAK,MAAM,CAAC,WAAW,YAAY,KAAK,iBAAiB;AACvD,gBAAa,QAAQ,QAAQ;AAC7B,WAAQ,uBAAO,IAAI,MAAM,gCAAgC,YAAY,CAAC;;AAExE,OAAK,gBAAgB,OAAO;;CAG9B,oBAAqC,OAAO,WAGR;AAElC,SAAO,MADW,IAAI,mCAAmC,CAClC,SAAS,8BAA8B,OAAO,CAAC;;CAGxE,mBAAoC,cAAkE;EACpG,MAAM,kBAA6C,EAAE;EACrD,MAAM,aAAoC,EAAE;AAC5C,OAAK,MAAM,YAAY,UACrB,MAAK,MAAM,WAAW,SAAS,aAAa,YAAY,EAAE,EAAE;GAC1D,MAAM,YAAYA,aAAW,QAAQ,GAAG;AACxC,OAAI,CAAC,UACH;GAEF,MAAM,gBAAgB,KAAK,kBAAkB,QAAQ,cAAc;AACnE,mBAAgB,KAAK;IACnB,aAAa,SAAS;IACtB;IACA,SAAS;KACP,IAAI;KACJ,MAAM;MACJ,OAAO,QAAQ,QAAQ;MACvB,gBAAgB,QAAQ,QAAQ;MAChC,GAAI,QAAQ,cAAc,EAAE,OAAO,QAAQ,aAAa,GAAG,EAAE;MAC7D,GAAI,QAAQ,QAAQ,EAAE;MACvB;KACD,GAAI,QAAQ,eAAe,EACzB,cAAc;MACZ,QAAQ,QAAQ;MAChB,GAAI,gBAAgB,EAAE,SAAS,eAAe,GAAG,EAAE;MACpD,EACF,GAAG,EAAE;KACN,GAAI,QAAQ,OAAO,EAAE,MAAM,KAAK,kBAAkB,SAAS,IAAI,UAAU,EAAE,GAAG,EAAE;KAChF,UAAU,KAAK,sBAAsB,SAAS,IAAI,UAAU;KAC7D;IACF,CAAC;AACF,cAAW,KAAK;IACd,IAAI,SAAS;IACb,cAAc,QAAQ;IACtB,GAAI,gBAAgB,EAAE,eAAe,GAAG,EAAE;IAC3C,CAAC;;AAGN,SAAO;GAAE;GAAiB;GAAY;;CAGxC,0BACE,UACA,YACG;AACH,OAAK,iBAAiB,QAAQ;EAE9B,MAAM,YAAYE,qBADFD,aAAW,SAAS,QAAQ,CACC,WAAW,YAAY;AACpE,SAAO,EACL,QAAS,KAAK,QAAQ,WAAW,CAAC,SAAqC,cAAc,EAAE,EACxF;;CAGH,6BAA8C,OAC5C,UACA,YACG;AACH,OAAK,iBAAiB,QAAQ;AAC9B,QAAM,KAAK,QAAQ,WAAW,eAAe,iBAAiB,SAAS,QAAQ,CAAC;AAChF,SAAO,EAAE,UAAU,MAAM;;CAG3B,4BACE,WACA,YACG;AACH,OAAK,iBAAiB,QAAQ;AAE9B,SAAO,EACL,UAFe,IAAI,gBAAgB,KAAK,QAAQ,WAAW,EAAE,KAAK,QAAQ,eAAe,CAEtE,mBAAmB,EACvC;;CAGH,8BAA+C,OAC7C,UACA,YACG;AACH,OAAK,iBAAiB,QAAQ;EAC9B,MAAM,UAAUA,aAAW,SAAS,QAAQ;EAC5C,MAAM,UAAUC,qBAAmB,QAAQ,WAAW,YAAY;EAClE,MAAM,SAASA,qBAAmB,QAAQ,gBAAgB,iBAAiB;EAC3E,MAAM,WAAWA,qBAAmB,QAAQ,UAAU,WAAW;EACjE,MAAM,WAAWD,aAAW,QAAQ,SAAS;EAC7C,MAAM,SAAS,KAAK,QAAQ,WAAW;EACvC,MAAM,WAAW,IAAI,gBAAgB,QAAQ,KAAK,QAAQ,eAAe;EACzE,MAAM,QAAQ,IAAI,mBAAmB,OAAO,CAAC,eAAe;GAC1D,SAAS;IACP;IACA;IACA;IACA,SAASD,aAAW,QAAQ,QAAQ,IAAIA,aAAW,QAAQ,YAAY,IAAI;IAC3E,2BAAW,IAAI,MAAM;IACrB,aAAa,EAAE;IACf;IACD;GACD,eAAeA,aAAW,SAAS,gBAAgB;GACnD,oBAAoBA,aAAW,SAAS,qBAAqB;GAC9D,CAAC;EACF,MAAM,UAAUA,aAAW,QAAQ,QAAQ;AAC3C,MAAI,QAOF,QANe,MAAM,SAAS,YAAY,SAAS;GACjD;GACA;GACA;GACA,YAAY,MAAM;GACnB,CAAC,IACe;GACf,SAAS;GACT,WAAW;GACZ;AAEH,SAAO,MAAM,SAAS,QACpBE,qBAAmB,QAAQ,aAAa,cAAc,EACtDD,aAAW,QAAQ,KAAK,EACxB;GACE;GACA;GACA;GACA,YAAY,MAAM;GACnB,CACF;;CAGH,2BACE,UACA,YACG;AACH,OAAK,iBAAiB,QAAQ;EAC9B,MAAM,UAAUA,aAAW,SAAS,QAAQ;EAC5C,MAAM,YAAYC,qBAAmB,QAAQ,WAAW,YAAY;EACpE,MAAM,UAAU,KAAK,gBAAgB,IAAI,UAAU;AACnD,MAAI,CAAC,QACH,QAAO,EAAE,UAAU,OAAO;AAE5B,OAAK,gBAAgB,OAAO,UAAU;AACtC,eAAa,QAAQ,QAAQ;AAC7B,MAAI,QAAQ,OAAO,OAAO;GAExB,MAAM,UAAUF,aADFC,aAAW,QAAQ,MAAM,CACN,QAAQ,IAAI;AAC7C,WAAQ,OAAO,IAAI,MAAM,QAAQ,CAAC;AAClC,UAAO,EAAE,UAAU,MAAM;;AAE3B,UAAQ,QAAQ,QAAQ,KAAK;AAC7B,SAAO,EAAE,UAAU,MAAM;;CAG3B,qBACE,UACqD;AACrD,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,GAC9D,QACA,KAAA;;CAGN,qBACE,aACA,cAEA,IAAI,uBAAuB;EACzB;EACA;EACA,SAAS,KAAK;EACf,CAAC;CAEJ,yBACE,aACA,cAEA,IAAI,uBAAuB;EACzB;EACA;EACA,SAAS,KAAK;EACf,CAAC;CAEJ,mBAAoC,OAAU,WAI5B;EAChB,MAAM,YAAY,YAAY;EAC9B,MAAM,SAAS,IAAI,SAAY,gBAAgB,kBAAkB;GAC/D,MAAM,UAAU,iBAAiB;AAC/B,SAAK,gBAAgB,OAAO,UAAU;AACtC,kCAAc,IAAI,MAAM,gCAAgC,OAAO,OAAO,CAAC;MACtE,6BAA6B;AAChC,QAAK,gBAAgB,IAAI,WAAW;IAClC,UAAU,UAAU,eAAe,MAAW;IAC9C,QAAQ;IACR;IACD,CAAC;IACF;AACF,OAAK,QAAQ,SAAS,aAAa;GACjC,MAAM;GACN,SAAS;IACP;IACA,aAAa,OAAO;IACpB,MAAM,OAAO;IACb,SAAS,OAAO;IACjB;GACD,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,QAAQ;GACT,CAAC;AACF,SAAO,MAAM;;CAGf,oBAAqC,YAAkC;AACrE,MAAI,QAAQ,UAAU,KAAK,MACzB,OAAM,IAAI,MAAM,6BAA6B;;;;;ACxbnD,SAAS,+BAAkD;AACzD,QAAO;EACL,OAAO,EAAE;EACT,UAAU,EAAE;EACZ,aAAa,EAAE;EAChB;;AAGH,SAAS,6BAA6B,UAAuE;AAC3G,QAAO,SAAS,KAAK,YAAY,GAAG,QAAQ,YAAY,GAAG,QAAQ,YAAqB,CAAC,MAAM;;AAGjG,SAAS,+BAA+B,UAAsE;AAC5G,QAAO,SACJ,KAAK,iBAAiB,aAAa,QAAQ,GAAG,CAC9C,QAAQ,OAAqB,OAAO,OAAO,YAAY,GAAG,MAAM,CAAC,SAAS,EAAE,CAC5E,MAAM;;AAGX,SAAS,0BAA0B,MAAyB,OAAmC;AAC7F,QAAO,KAAK,WAAW,MAAM,UAAU,KAAK,OAAO,OAAO,UAAU,UAAU,MAAM,OAAO;;AAG7F,SAAS,sBAAsB,MAAc,QAA+B;AAC1E,KAAI,CAAC,KAAK,WAAW,OAAO,CAC1B,QAAO;CAET,MAAM,CAAC,WAAW,KAAK,MAAM,OAAO,OAAO,CAAC,MAAM,IAAI;AACtD,QAAO,SAAS,MAAM,GAAG,QAAQ,MAAM,GAAG;;AAG5C,SAAS,cAAc,QAGD;AACpB,QAAO;EACL,mBAAmB;GACjB,GAAG,8BAA8B;GACjC,UAAU,OAAO,gBAAgB,KAAK,aAAa;IACjD,aAAa,QAAQ;IACrB,SAAS,QAAQ;IACjB,QAAQ;IACT,EAAE;GACJ;EACD,iBAAiB,OAAO;EACxB,YAAY,OAAO;EACpB;;AAGH,SAAS,wCAAwC,QAIrC;CACV,MAAM,EAAE,cAAc,iBAAiB,iBAAiB;AAGxD,KAAI,CAAC,0BAF4B,6BAA6B,gBAAgB,gBAAgB,EAChE,6BAA6B,aAAa,gBAAgB,CACT,CAC7E,QAAO;AAKT,KAAI,CAAC,0BAF8B,+BAA+B,gBAAgB,kBAAkB,SAAS,EAC7E,+BAA+B,aAAa,kBAAkB,SAAS,CACpB,CACjF,QAAO;CAGT,MAAM,6BAAa,IAAI,KAAa;AACpC,MAAK,MAAM,WAAW,CAAC,GAAG,gBAAgB,iBAAiB,GAAG,aAAa,gBAAgB,CACzF,YAAW,IAAI,QAAQ,UAAU;AAGnC,MAAK,MAAM,QAAQ,cAAc;EAC/B,MAAM,YAAY,sBAAsB,MAAM,YAAY;AAC1D,MAAI,aAAa,WAAW,IAAI,UAAU,CACxC,QAAO;AAET,MAAI,KAAK,WAAW,cAAc,CAChC,QAAO;;AAIX,QAAO;;AAGT,SAAS,kBAAkB,UAA8C,UAAkD;AACzH,QAAO,IAAI,IAAI,CACb,GAAG,SAAS,KAAK,YAAY,QAAQ,YAAY,EACjD,GAAG,SAAS,KAAK,SAAS,KAAK,GAAG,CACnC,CAAC,CAAC;;AAGL,IAAa,mBAAb,MAA8B;CAC5B,WAAsC,cAAc;EAClD,iBAAiB,EAAE;EACnB,YAAY,EAAE;EACf,CAAC;CACF;CAEA,YAAY,SAAmD;AAAlC,OAAA,UAAA;AAC3B,OAAK,UAAU,IAAI,wBAAwB;GACzC,UAAU,QAAQ;GAClB,WAAW,QAAQ,cAAc;GACjC,cAAc,KAAK;GACnB,SAAS,QAAQ;GACjB,YAAY,QAAQ;GACpB,gBAAgB,QAAQ;GACzB,CAAC;;CAGJ,OAAO,OAAO,SAA8B,EAAE,KAAmC;EAC/E,MAAM,EAAE,eAAe,EAAE,EAAE,aAAa,yBAAyB;EACjE,MAAM,SAAS,OAAO,UAAU,KAAK,QAAQ,cAAc,YAAY;EACvE,MAAM,YAAY,iBAAiB,OAAO,OAAO,SAAS,UAAU;EACpE,MAAM,gBAAgB,MAAM,KAAK,QAAQ,yBAAyB;GAChE;GACA;GACD,CAAC;EACF,MAAM,sBAAsB,kBAAkB,cAAc,iBAAiB,cAAc,WAAW;AACtG,gBAAc,EAAE,qBAAqB,CAAC;AACtC,OAAK,MAAM,CAAC,OAAO,YAAY,cAAc,gBAAgB,SAAS,CACpE,wBAAuB;GACrB,aAAa,QAAQ;GACrB,sBAAsB,QAAQ;GAC9B;GACD,CAAC;EAEJ,MAAM,kBAAkB,KAAK;EAC7B,MAAM,eAAe,cAAc,cAAc;AACjD,OAAK,WAAW;AAChB,SAAO;GACL,aAAa,EAAE;GACf;GACA,sBAAsB;GACtB,uBAAuB,wCAAwC;IAC7D;IACA;IACA;IACD,CAAC;GACH;;CAGH,wBAAwB,OAAO,WAEK,MAAM,KAAK,KAAK,OAAO;CAE3D,gCAAsC;AACpC,OAAK,QAAQ,yBAAyB;;CAGxC,QAAQ,OAAO,WAAuD;AACpE,QAAM,KAAK,QAAQ,MAAM,OAAO;;CAGlC,OAAO,YAA2B;AAChC,QAAM,KAAK,QAAQ,MAAM;;CAG3B,6BAAgD,KAAK,SAAS;CAE9D,2BAAsD,KAAK,SAAS;CAEpE,sBAA6C,KAAK,SAAS;CAE3D,gBAAgB,WACd,sBAAsB,OAAO;CAE/B,mBAAmB,SAAiB,mBAClC,yBAAyB,SAAS,eAAe;CAEnD,qBACE,iBAAiB,KAAK,QAAQ,cAAc,YAAY,CAAC,OAAO,SAAS,UAAU;;;;AC7NvF,MAAM,qBAAqB;AAE3B,SAASE,WAAS,OAAkD;AAClE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,mBAAmB,OAAyB;AACnD,KAAI,CAACA,WAAS,MAAM,CAClB,QAAO;CAET,MAAM,OAAO,MAAM;AACnB,QAAO,SAAS,eAAe,SAAS;;AAG1C,SAAS,8BAA8B,SAA2B;AAChE,KAAI,CAAC,MAAM,QAAQ,QAAQ,CACzB,QAAO;CAGT,IAAI,WAAW;CACf,MAAM,QAAQ,QAAQ,KAAK,SAAS;AAClC,MAAI,CAAC,mBAAmB,KAAK,CAC3B,QAAO;AAET,aAAW;AACX,SAAO;GAAE,MAAM;GAAQ,MAAM;GAAoB;GACjD;AAEF,KAAI,CAAC,SACH,QAAO;CAGT,MAAM,YAAY,MACf,QAAQ,SACPA,WAAS,KAAK,IAAI,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,SAC/D,CACD,KAAK,SAAS,KAAK,KAAK,MAAM,CAAC,CAC/B,OAAO,QAAQ;AAClB,KAAI,UAAU,WAAW,MAAM,OAC7B,QAAO,UAAU,KAAK,OAAO;AAE/B,QAAO;;AAGT,SAAgB,uCAAuC,QAGpB;AACjC,KAAI,OAAO,eACT,QAAO,OAAO;AAEhB,QAAO,OAAO,SAAS,KAAK,YAAY;AACtC,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,SAAS,UAAU,CAC3D,QAAO;EAET,MAAM,UAAU,8BAA8B,QAAQ,QAAQ;AAC9D,SAAO,YAAY,QAAQ,UAAU,UAAU;GAAE,GAAG;GAAS;GAAS;GACtE;;;;ACTJ,MAAM,mBAAmB,UAAoD;AAC3E,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;AAGxC,MAAM,sBAAsB,YAA+D;AACzF,KAAI,CAAC,QACH,QAAO;CAET,MAAM,gBAAgB,OAAO,QAAQ,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,KAAK,cAAc,MAAM,CAAC;AAClG,QAAO,KAAK,UAAU,cAAc;;AAGtC,IAAM,wBAAN,cAAoC,YAAY;CAC9C,YAAY,cAA8B;AACxC,QAAM,MAAM,KAAK;AADC,OAAA,eAAA;;CAIpB,mBAAmB,UAAwB;AACzC,OAAK,eAAe;;CAGtB,wBAAgC;AAC9B,SAAO,KAAK;;CAGd,OAAgB,OAAO,YAAgD;AACrE,QAAM,IAAI,MAAM,6EAA6E;;;AAIjG,IAAa,qBAAb,MAAgC;CAC9B;CACA,+BAAgC,IAAI,KAA0B;CAC9D,kBAAmC,IAAI,sBAAsB,SAAS;CACtE,SAAgC;CAEhC,cAAc;AACZ,OAAK,mBAAmB,IAAI,iBAAiB,yBAAyB;;CAGxE,QAAQ,WAAyB;AAC/B,OAAK,SAAS;AACd,OAAK,aAAa,OAAO;AACzB,OAAK,gBAAgB,gBAAgB,OAAO,OAAO,SAAS,MAAM;;CAGpE,OAAO,UAAuC;EAC5C,MAAM,QAAQ,KAAK,aAAa,MAAM;AACtC,MAAI,CAAC,MACH,QAAO,KAAK;AAEd,SAAO,KAAK,oBAAoB,MAAM;;CAGxC,OAAgB,OAAO,WAAqD;EAC1E,MAAM,QAAQ,KAAK,aAAa,OAAO,SAAS,KAAK;AAErD,UADiB,QAAQ,KAAK,oBAAoB,MAAM,GAAG,KAAK,iBAChD,KAAK;GACnB,GAAG;GACH,UAAU,KAAK,2BAA2B,OAAO,OAAO,SAAS;GAClE,CAAC;;CAGJ,aAAsB,iBAEpB,QACgC;EAChC,MAAM,QAAQ,KAAK,aAAa,OAAO,SAAS,KAAK;EACrD,MAAM,WAAW,QAAQ,KAAK,oBAAoB,MAAM,GAAG,KAAK;AAChE,aAAW,MAAM,SAAS,SAAS,WAAW;GAC5C,GAAG;GACH,UAAU,KAAK,2BAA2B,OAAO,OAAO,SAAS;GAClE,CAAC,CACA,OAAM;;CAIV,iBAA0B,OAAO,UAAsD;AAgBrF,QAfiB,KAAK,eAAe;GACnC,cAAc,MAAM;GACpB,UAAU;IACR,SAAS;IACT,aAAa;IACb,QAAQ,MAAM,UAAU;IACxB,SAAS,MAAM,WAAW;IAC1B,cAAc,MAAM,gBAAgB;IACpC,SAAS,MAAM,WAAW;IAC1B,QAAQ,EAAE;IACV,aAAa,EAAE;IAChB;GACD,SAAS,MAAM,WAAW;GAC1B,OAAO,MAAM;GACd,CAAC,CACa,KAAK;GAClB,UAAU,MAAM;GAChB,OAAO,MAAM;GACb,WAAW,MAAM;GACjB,QAAQ,MAAM;GACf,CAAC;;CAGJ,gBAAwB,UAAgD;AACtE,MAAI,CAAC,KAAK,OACR,QAAO;EAGT,MAAM,iBAAiB,gBAAgB,MAAM,IAAI,KAAK,OAAO,OAAO,SAAS;EAC7E,MAAM,EAAE,UAAU,SAAS,KAAK,gBAAgB,eAAe;EAC/D,MAAM,eAAe,OAAO,KAAK,iBAAiB,mBAAmB,KAAK,GAAG,KAAA;AAC7E,SAAO;GACL,OAAO;GACP,cAAc;GACd;GACA,SAAS,UAAU,WAAW,cAAc,kBAAkB;GAC/D;;CAGH,mBAA2B,UAGtB;EACH,MAAM,YAAY,KAAK,QAAQ;AAC/B,MAAI,CAAC,UACH,QAAO;GAAE,UAAU;GAAM,MAAM;GAAM;EAGvC,MAAM,QAAQ,KAAK,iBAAiB,mBAAmB;EACvD,MAAM,aAAa,MAAM,aAAa;EACtC,MAAM,cAAc,WAAW,SAAS,IAAI,GACxC,WAAW,MAAM,GAAG,WAAW,QAAQ,IAAI,CAAC,GAC5C;AAEJ,MAAI,aAAa;GACf,MAAM,WAAW,KAAK,sBAAsB,WAAW,YAAY;AACnE,OAAI,SACF,QAAO;;EAIX,MAAM,iBAAiB,MACpB,KAAK,UAAU;GAAE,MAAM,KAAK;GAAM,UAAU,UAAU,KAAK;GAAO;GAAM,EAAE,CAC1E,QAAQ,UAAU,MAAM,UAAU,YAAY,SAAS,QAAQ,MAAM,UAAU,OAAO,CAAC,CACvF,QAAQ,UAAU,MAAM,KAAK,SAAS,MAAM,YAAY,WAAW,SAAS,QAAQ,CAAC,CAAC;AACzF,MAAI,eAAe,WAAW,GAAG;GAC/B,MAAM,QAAQ,eAAe;AAC7B,UAAO;IAAE,UAAU,MAAM,YAAY;IAAM,MAAM,MAAM;IAAM;;AAE/D,MAAI,eAAe,SAAS,EAC1B,QAAO;GAAE,UAAU;GAAM,MAAM;GAAM;EAGvC,MAAM,eAAe,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,KAAK,CAAC;EAC5D,MAAM,mBAAmB,OAAO,QAAQ,UAAU,CAC/C,QAAQ,GAAG,cAAc,SAAS,YAAY,SAAS,QAAQ,SAAS,OAAO,CAAC;EACnF,MAAM,iBAAiB,iBAAiB,QAAQ,CAAC,UAAU,aAAa,IAAI,KAAK,CAAC;AAClF,MAAI,eAAe,WAAW,GAAG;GAC/B,MAAM,CAAC,MAAM,YAAY,eAAe;AACxC,UAAO;IAAE;IAAU;IAAM;;EAE3B,MAAM,gBAAgB,iBAAiB,QAAQ,CAAC,UAAU,CAAC,aAAa,IAAI,KAAK,CAAC;AAClF,MAAI,cAAc,WAAW,GAAG;GAC9B,MAAM,CAAC,MAAM,YAAY,cAAc;AACvC,UAAO;IAAE;IAAU;IAAM;;AAE3B,SAAO;GAAE,UAAU;GAAM,MAAM;GAAM;;CAGvC,yBACE,WACA,gBACoE;AACpE,OAAK,MAAM,QAAQ,KAAK,iBAAiB,mBAAmB,EAAE;GAC5D,MAAM,WAAW,UAAU,KAAK;GAChC,MAAM,UAAU,CAAC,KAAK,MAAM,KAAK,eAAe,GAAG,CAChD,KAAK,UAAU,MAAM,MAAM,CAAC,aAAa,CAAC,CAC1C,OAAO,QAAQ;AAClB,OAAI,YAAY,QAAQ,SAAS,YAAY,CAC3C,QAAO,SAAS,YAAY,QACxB;IAAE;IAAU,MAAM,KAAK;IAAM,GAC7B;IAAE,UAAU;IAAM,MAAM;IAAM;;EAGtC,MAAM,iBAAiB,OAAO,QAAQ,UAAU,CAC7C,MAAM,CAAC,UAAU,KAAK,aAAa,KAAK,YAAY;AACvD,MAAI,CAAC,eACH,QAAO;EAET,MAAM,CAAC,MAAM,YAAY;AACzB,SAAO,SAAS,YAAY,QAAQ;GAAE;GAAU;GAAM,GAAG;GAAE,UAAU;GAAM,MAAM;GAAM;;CAGzF,uBAA+B,UAAsC;AACnE,MAAI,CAAC,MAAM,UAAU,UAAU,CAAC,MAAM,MAAM,WAAW,WAAW,CAChE,QAAO,KAAK;EAGd,MAAM,WAAW,KAAK,cAAc,MAAM;EAC1C,MAAM,SAAS,KAAK,aAAa,IAAI,SAAS;AAC9C,MAAI,OACF,QAAO;EAGT,MAAM,UAAU,KAAK,eAAe,MAAM;AAC1C,OAAK,aAAa,IAAI,UAAU,QAAQ;AACxC,SAAO;;CAGT,kBAA0B,UAAsC;AAC9D,SAAO,IAAI,gBAAgB;GACzB,QAAQ,MAAM,UAAU,UAAU;GAClC,SAAS,MAAM;GACf,cAAc,MAAM;GACpB,cAAc,MAAM,UAAU,gBAAgB;GAC9C,cAAc,MAAM;GACpB,kBAAkB,KAAK;GACvB,SAAS,MAAM,UAAU,WAAW;GACrC,CAAC;;CAGJ,8BACE,OACA,aACmC;AACnC,SAAO,uCAAuC;GAC5C;GACA,gBAAgB,oBAAoB;IAClC,OAAO,OAAO;IACd,cAAc,OAAO;IACrB,aAAa,OAAO,UAAU;IAC/B,CAAC;GACH,CAAC;;CAGJ,iBAAyB,UAAiC;EACxD,MAAM,gBAAgB,MAAM;AAC5B,SAAO;GACL,MAAM,gBAAgB;GACtB,eAAe,UAAU;GACzB,MAAM,WAAW;GACjB,eAAe,WAAW;GAC1B,mBAAmB,eAAe,gBAAgB,KAAK;GACxD,CAAC,KAAK,KAAK;;;;;AChShB,IAAa,aAAb,MAAwB;CACtB;CACA;CACA;CACA;CACA,gBAA8C;CAE9C,YAAY,WAAyB;AACnC,OAAK,mBAAmB,WAAW;AACnC,OAAK,sBAAsB,IAAI,0BAA0B,EACvD,iBAAiB,KAAK,kBACvB,CAAC;AACF,OAAK,qBAAqB,IAAI,mBAAmB;GAC/C,iBAAiB,KAAK;GACtB,kBAAkB,KAAK;GACxB,CAAC;AACF,OAAK,sBAAsB,IAAI,0BAA0B,KAAK,mBAAmB;;CAGnF,mBAAmB,WACjB,KAAK,oBAAoB,gBAAgB,OAAO;CAElD,cAAoB;AAClB,OAAK,kBAAkB,KAAK,6BAA6B;;CAG3D,cAAc,OAAO,WAAkC;EACrD,MAAM,iBAAiB,KAAK;AAC5B,OAAK,mBAAmB;EACxB,MAAM,kBAAkB,MAAM,KAAK,mBAAmB,gBAAgB;GACpE,YAAY;GACZ,YAAY;GACb,CAAC;AAEF,OAAK,MAAM,cAAc,gBAAgB,OACvC,KAAI,CAAC,WAAW,GACd,SAAQ,KAAK,wBAAwB,WAAW,KAAK,IAAI,WAAW,QAAQ;;CAKlF,UAAU,YAA2B;AACnC,QAAM,KAAK,eAAe,YAAY,KAAA,EAAU;AAChD,QAAM,KAAK,mBAAmB,OAAO;;CAGvC,8BAAsC,YAA2B;EAC/D,MAAM,UAAU,MAAM,KAAK,mBAAmB,uBAAuB;AACrE,OAAK,MAAM,UAAU,QACnB,KAAI,CAAC,OAAO,GACV,SAAQ,KAAK,wBAAwB,OAAO,KAAK,IAAI,OAAO,QAAQ;;;AC1C5E,MAAa,uCAAuC;AAEpD,MAAM,gCAAgC;AAUtC,MAAa,gDAAgD;AAC7D,MAAa,0CAA0C;AACvD,MAAa,2CAA2C;AACxD,MAAa,wCAAwC;AA6CrD,SAAgB,sBAAsB,WAA2B;AAC/D,QAAO,UAAU,MAAM;;AAGzB,SAAgB,uBAAuB,OAAuB;AAC5D,QAAO,MAAM,QAAQ,oBAAoB,IAAI;;AAG/C,SAAgB,oBAAoB,SAAiD;AACnF,QAAO,SAAS,MAAM,CAAC,aAAa,IAAI,KAAA;;AAG1C,SAAgBC,WAAS,OAAkD;AACzE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAgB,YAAY,OAAgB,UAA0B;CACpE,MAAM,SAAS,OAAO,UAAU,WAAW,KAAK,MAAM,MAAM,GAAG;AAC/D,QAAO,OAAO,SAAS,OAAO,GAAG,IAAI,KAAK,OAAO,CAAC,aAAa,GAAG;;AAGpE,SAAgB,6BAA6B,QAA+C;CAC1F,MAAM,WAAW,gBAAgB,OAAO,YAAY,EAAE,CAAC;CACvD,MAAM,QAAQ,iBAAiB,SAAS,MAAM,IAAI,wBAAwB,OAAO,SAAS;AAC1F,KAAI,MACF,UAAS,QAAQ;CAEnB,MAAM,gBAAgB,qBAAqB,OAAO,SAAS,GAAG,GAAG,CAAC;AAClE,QAAO;EACL,WAAW,OAAO;EAClB,GAAI,oBAAoB,OAAO,QAAQ,GAAG,EAAE,SAAS,oBAAoB,OAAO,QAAQ,EAAE,GAAG,EAAE;EAC/F,cAAc,OAAO,SAAS;EAC9B,GAAI,OAAO,YAAY,EAAE,WAAW,OAAO,WAAW,GAAG,EAAE;EAC3D,WAAW,OAAO;EAClB,GAAI,gBAAgB,EAAE,eAAe,GAAG,EAAE;EAC1C,QAAQ;EACR,GAAI,OAAO,KAAK,SAAS,CAAC,SAAS,IAAI,EAAE,UAAU,GAAG,EAAE;EACzD;;AAGH,SAAgB,0CACd,QACqC;AACrC,QAAO;EACL,OAAO;EACP,SAAA;EACA,YAAY,OAAO,aAAa,OAAO;EACvC,GAAI,oBAAoB,OAAO,QAAQ,GAAG,EAAE,UAAU,oBAAoB,OAAO,QAAQ,EAAE,GAAG,EAAE;EAChG,UAAU,gBAAgB,OAAO,YAAY,EAAE,CAAC;EACjD;;AAGH,SAAgB,kCAAkC,QAK5B;CACpB,MAAM,EAAE,SAAS,OAAO,WAAW,cAAc;CACjD,MAAM,eAAe,4BAA4B,MAAM;CACvD,MAAM,eAAe,UACjB,QAAQ,gBAAgB,eAAe,IAAI,KAC3C,eACE,IACA;CACN,MAAM,gBAAgB,qBAAqB,aAAa,IAAI,SAAS;AACrE,QAAO;EACL;EACA,GAAI,oBAAoB,SAAS,QAAQ,GAAG,EAAE,SAAS,oBAAoB,SAAS,QAAQ,EAAE,GAAG,EAAE;EACnG;EACA,WAAW,SAAS,aAAa;EACjC;EACA,GAAI,gBAAgB,EAAE,eAAe,GAAG,EAAE;EAC1C,QAAQ;EACT;;AAGH,eAAsB,4BACpB,QACuB;CACvB,MAAM,eAAe,IAAI,yCAAyC;AAClE,MAAK,MAAM,SAAS,QAAQ;AAC1B,MAAI,mBAAmB,MAAM,CAC3B;AAEF,QAAM,aAAa,SAAS,kBAAkB,MAAM,CAAC;;CAEvD,MAAM,WAAW,aAAa,aAAa;AAC3C,QAAO,CACL,GAAG,SAAS,SAAS,KAAK,YAAY,gBAAgB,QAAQ,CAAC,EAC/D,GAAI,SAAS,mBAAmB,CAAC,gBAAgB,SAAS,iBAAiB,CAAC,GAAG,EAAE,CAClF;;AAGH,SAAS,kBAAkB,OAAyD;CAClF,MAAM,cAAc,gBAAgB,MAAM;CAC1C,MAAM,gBAAgB,4BAA4B,YAAY;AAC9D,KACE,eAAe,SAAS,gBACvB,cAAc,WAAW,aAAa,cAAc,WAAW,aAEhE,eAAc,SAAS;AAEzB,KACE,YAAY,SAAA,8BACZ,YAAY,SAAS,aAAa,iBAElC,QAAO;EAAE,MAAM,aAAa;EAAa,SAAS,YAAY;EAAS;AAEzE,QAAO;;AAGT,SAAS,mBAAmB,OAAkF;AAC5G,QACE,MAAM,SAAA,8BACN,MAAM,SAAA,+BACN,MAAM,SAAA;;AAIV,SAAgB,gCAAgC,SAAoC;AAClF,QAAO,QAAQ,iBAAiB,QAAQ,aAAa,QAAQ;;AAG/D,SAAS,qBAAqB,SAAqD;AACjF,QAAO,YAAY,SAAS,WAAW,GAAG,IAAI,KAAA;;AAGhD,SAAS,cAAc,OAAuB;CAC5C,MAAM,QAAQ,MAAM,KAAK,MAAM;AAC/B,QAAO,MAAM,UAAU,gCACnB,QACA,GAAG,MAAM,MAAM,GAAG,8BAA8B,CAAC,KAAK,GAAG,CAAC;;AAGhE,SAAS,iBAAiB,OAA+B;AAEvD,SADgB,OAAO,UAAU,WAAW,MAAM,MAAM,GAAG,OACzC;;AAGpB,SAAS,wBAAwB,UAAgD;AAC/E,MAAK,MAAM,WAAW,UAAU;AAC9B,MAAI,QAAQ,SAAS,OACnB;AAEF,OAAK,MAAM,QAAQ,QAAQ,MACzB,KAAI,KAAK,SAAS,UAAU,KAAK,SAAS,aAAa;GACrD,MAAM,OAAO,iBAAiB,KAAK,KAAK;AACxC,OAAI,KACF,QAAO,cAAc,KAAK;;;AAKlC,QAAO;;AAGT,SAAS,4BAA4B,OAAkE;AACrG,SAAQ,MAAM,MAAd;EACE,KAAK,aAAa,YAChB,QAAO,MAAM,QAAQ;EACvB,KAAK,aAAa,iBAChB,QAAO,MAAM,QAAQ;EACvB,KAAK,8CACH,QAAO,MAAM,QAAQ;EACvB,QACE;;;;;ACjNN,MAAM,uBAAuB;AAC7B,MAAM,oBAAoB;AAC1B,MAAM,6BAA6B;AACnC,MAAM,oCAAoC;AAC1C,MAAM,qCAAqC;AAC3C,MAAM,uCAAuC;AAS7C,SAAS,mBAAmB,WAA2B;AACrD,QAAO,UAAU,MAAM;;AAGzB,SAAS,WAAc,OAAY,OAAqB;AACtD,KAAI,CAAC,OAAO,SAAS,MAAM,IAAI,OAAO,UAAU,YAAY,SAAS,EACnE,QAAO;AAET,QAAO,MAAM,MAAM,GAAG,KAAK,MAAM,MAAM,CAAC;;AAG1C,SAASC,qBAAmB,OAA+B;AACzD,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;AAGxC,SAAS,cAAc,MAAsB;CAC3C,MAAM,aAAa,KAAK,MAAM,CAAC,QAAQ,QAAQ,IAAI;AACnD,KAAI,CAAC,WACH,QAAO;AAET,QAAO,WAAW,UAAU,KAAK,aAAa,GAAG,WAAW,MAAM,GAAG,GAAG,CAAC;;AAG3E,SAAS,iBAAyB;AAChC,QAAO,OAAO,KAAK,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,YAAY,CAAC,QAAQ,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE;;AAGrF,SAAS,uBAAuB,gBAAkE;CAChG,MAAM,eAAwC,EAAE;AAYhD,MAAK,MAAM,OAXW;EACpB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAEC,KAAI,OAAO,UAAU,eAAe,KAAK,gBAAgB,IAAI,CAC3D,cAAa,OAAO,gBAAgB,eAAe,KAAK;AAG5D,QAAO;;AAGT,SAAS,uBACP,UACA,WACyB;AACzB,QAAO,aAAa,OAAO,KAAK,UAAU,CAAC,SAAS,IAChD;EAAE,GAAG;EAAU,GAAG,gBAAgB,UAAU;EAAE,GAC9C;;AAGN,SAAS,mBAAmB,QAIjB;CACT,MAAM,EAAE,UAAU,SAAS,gBAAgB;AAC3C,QACEA,qBAAmB,QAAQ,IAC3BA,qBAAmB,SAAS,QAAQ,IACpCA,qBAAmB,YAAY,IAC/BA,qBAAmB,SAAS,aAAa,IACzC;;AAIJ,SAAS,sBAAsB,QAUtB;CACP,MAAM,EACJ,WACA,UACA,OACA,iBACA,aACA,WACA,aACA,eACA,UACE;AACJ,UAAS,eAAe;AACxB,UAAS,UAAU;AACnB,UAAS,8BAA8B;AACvC,UAAS,wCAAwC;AACjD,KAAI,gBACF,UAAS,qCAAqC;AAEhD,KAAI,UACF,UAAS,sCAAsC;AAEjD,KAAIA,qBAAmB,MAAM,EAAE;AAC7B,WAAS,QAAQ,OAAO,MAAM;AAC9B,WAAS,kBAAkB,OAAO,MAAM;;AAE1C,KAAIA,qBAAmB,cAAc,EAAE;AACrC,WAAS,WAAW,eAAe,MAAM;AACzC,WAAS,qBAAqB,eAAe,MAAM;;AAErD,KAAIA,qBAAmB,YAAY,CACjC,UAAS,eAAe,aAAa,MAAM;;AAI/C,SAAS,6BAA6B,OAAmD;AACvF,SAAQ,MAAM,MAAd;EACE,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,KAAK,aAAa,SAChB,QAAO;EACT,QACE,QAAO;;;AAIb,IAAa,oBAAb,MAAwD;CACtD;CACA,oCAAqC,IAAI,KAAa;CACtD;CAEA,YAAY,SAAoD;AAAnC,OAAA,UAAA;AAC3B,OAAK,uBAAuB,IAAI,4BAA4B,EAC1D,eAAe,QAAQ,eACxB,CAAC;AACF,OAAK,8BAA8B,QAAQ,SAAS,GAClD,UAAU,kBACV,KAAK,uBACN;;CAGH,gBAAsB;AACpB,OAAK,6BAA6B;AAClC,OAAK,kBAAkB,OAAO;;CAGhC,gBAAgB,OAAO,WAA2D;EAChF,MAAM,EACJ,SAAS,kBACT,mBACA,OACA,iBAAiB,oBACjB,aACA,WAAW,cACX,SACA,WAAW,oBACX,aAAa,sBACb,iBACA,uBACA,MACA,eACA,OAAO,mBACL;EACJ,MAAM,eAAe,kBACjB,MAAM,KAAK,iBAAiB,gBAAgB,GAC5C;EACJ,MAAM,WAAW,uBAAuB,sBAAsB;EAC9D,MAAM,QAAQA,qBAAmB,eAAe,IAAI,cAAc,KAAK;EACvE,MAAM,kBAAkBA,qBAAmB,mBAAmB;EAC9D,MAAM,YAAYA,qBAAmB,aAAa;EAClD,MAAM,cAAc,mBAAmB;GACrC;GACA,aAAa;GACb;GACD,CAAC;AACF,wBAAsB;GACpB,WAAW;GACX;GACA;GACA,iBAAiB,mBAAmB,KAAA;GACpC;GACA,WAAW,aAAa,KAAA;GACxB;GACA;GACA;GACD,CAAC;EACF,MAAM,uBAAM,IAAI,MAAM,EAAC,aAAa;EACpC,MAAM,eAAe,uBAAuB,UAAU,kBAAkB;EACxE,MAAM,UACJA,qBAAmB,iBAAiB,IACpCA,qBAAmB,cAAc,QAAQ,IACzC;EACF,MAAM,YAAYA,qBAAmB,mBAAmB,IAAI,gBAAgB;EAC5E,MAAM,SAA6B;GACjC;GACA,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;GAC9B,UAAU,EAAE;GACZ,WAAW;GACX,WAAW;GACX,UAAU;GACX;AACD,QAAM,KAAK,QAAQ,aAAa,sBAAsB,OAAO;AAC7D,QAAM,KAAK,qBAAqB,UAAU;AAC1C,SAAO;GACL;GACA;GACA;GACA,eAAe,gBAAgB,uBAAuB,WAAW;GACjE,GAAI,kBAAkB,EAAE,iBAAiB,GAAG,EAAE;GAC9C,GAAI,YAAY,EAAE,oBAAoB,WAAW,GAAG,EAAE;GACtD,WAAW;GACX;GACA,UAAU;GACV,WAAW;GACX,WAAW;GACZ;;CAGH,qBAAqB,OAAO,WAGP;EACnB,MAAM,EAAE,UAAU;EAClB,MAAM,YAAY,mBAAmB,OAAO,UAAU;AACtD,MAAI,CAAC,UACH;AAEF,QAAM,KAAK,QAAQ,aAAa,mBAAmB;GACjD;GACA;GACD,CAAC;AACF,MAAI,6BAA6B,MAAM,CACrC,OAAM,KAAK,qBAAqB,UAAU;;CAI9C,qBAAqB,OACnB,WACA,aACqB;EACrB,MAAM,sBAAsB,mBAAmB,UAAU;AACzD,MAAI,CAAC,oBACH,QAAO;AAMT,MAAI,CAJY,MAAM,KAAK,QAAQ,aAAa,mBAAmB;GACjE,WAAW;GACX,UAAU,gBAAgB,SAAS;GACpC,CAAC,CAEA,QAAO;AAET,OAAK,8BAA8B,qBAAqB,UAAU,MAAM;AACxE,QAAM,KAAK,qBAAqB,oBAAoB;AACpD,SAAO;;CAGT,wBAAwB,OACtB,WACA,aACqB;EACrB,MAAM,sBAAsB,mBAAmB,UAAU;AACzD,MAAI,CAAC,oBACH,QAAO;AAMT,MAAI,CAJY,MAAM,KAAK,QAAQ,aAAa,sBAAsB;GACpE,WAAW;GACX,UAAU,gBAAgB,SAAS;GACpC,CAAC,CAEA,QAAO;AAET,OAAK,8BAA8B,qBAAqB,UAAU,SAAS;AAC3E,QAAM,KAAK,qBAAqB,oBAAoB;AACpD,SAAO;;CAGT,gBAAgB,OACd,WACA,UACsC;AACtC,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,WAAW,CAC1D,QAAO,MAAM,KAAK,WAAW,UAAU;AAKzC,UAHgB,MAAM,aAAa,OAC/B,MAAM,KAAK,mBAAmB,WAAW,EAAE,CAAC,GAC5C,MAAM,KAAK,sBAAsB,WAAW,MAAM,YAAY,EAAE,CAAC,IACpD,MAAM,KAAK,WAAW,UAAU,GAAG;;CAGtD,gBAAgB,OAAO,cAAqC;EAC1D,MAAM,sBAAsB,mBAAmB,UAAU;AACzD,MAAI,CAAC,oBACH;AAEF,QAAM,KAAK,QAAQ,aAAa,cAAc,oBAAoB;AAClE,QAAM,KAAK,qBAAqB,oBAAoB;;CAGtD,mBAAmB,OAAO,cAA0D;EAClF,MAAM,sBAAsB,mBAAmB,UAAU;AACzD,MAAI,CAAC,oBACH,QAAO;AAET,SAAO,MAAM,KAAK,QAAQ,aAAa,WAAW,oBAAoB;;CAGxE,eAAe,OAAO,YAAgE;AAEpF,SAAO,WADW,MAAM,KAAK,QAAQ,aAAa,sBAAsB,EAC3C,SAAS,MAAM,CAAC,IAAI,KAAK,sBAAsB;;CAG9E,sBAAsB,OACpB,WACA,YAC0B;EAC1B,MAAM,sBAAsB,mBAAmB,UAAU;AACzD,MAAI,CAAC,oBACH,QAAO,EAAE;AAGX,SAAO,WADU,MAAM,KAAK,QAAQ,aAAa,oBAAoB,oBAAoB,EAC7D,SAAS,MAAM;;CAG7C,aAAa,OAAO,cAAyD;EAC3E,MAAM,SAAS,MAAM,KAAK,iBAAiB,UAAU;AACrD,SAAO,SAAS,KAAK,sBAAsB,KAAK,wBAAwB,QAAQ,KAAK,CAAC,GAAG;;CAG3F,mBAAmB,OACjB,WACA,eAC4C;AAI5C,UAHgB,aACZ,KAAK,sBAAsB,KAAK,wBAAwB,YAAY,KAAK,CAAC,GAC1E,MAAM,KAAK,WAAW,UAAU,GACpB,iBAAiB;;CAGnC,uBAAuB,OAAO,eAAsC;EAClE,MAAM,uBAAuB,mBAAmB,WAAW;AAC3D,MAAI,CAAC,qBACH;AAEF,OAAK,QAAQ,SAAS,KAAK,UAAU,gBAAgB,EAAE,YAAY,sBAAsB,EAAE;GACzF,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,QAAQ;GACT,CAAC;AACF,QAAM,KAAK,QAAQ,cAAc,qBAAqB,qBAAqB;EAC3E,MAAM,UAAU,MAAM,KAAK,WAAW,qBAAqB;AAC3D,MAAI,SAAS;AACX,QAAK,QAAQ,SAAS,KAAK,UAAU,sBAAsB,EAAE,SAAS,CAAC;AACvE;;AAEF,OAAK,QAAQ,SAAS,KAAK,UAAU,sBAAsB,EACzD,YAAY,sBACb,CAAC;;CAGJ,2BACE,QACA,uBAAuB,UACD;EACtB,MAAM,UAAU,6BAA6B,OAAO;EACpD,MAAM,gBAAgB,uBAClB,KAAK,qBAAqB,QAAQ;GAClC,iBAAiB,OAAO,YAAY,EAAE;GACtC,WAAW,OAAO;GAClB,iBAAiB,OAAO;GACxB,eAAe,OAAO;GACtB,gBAAgB,OAAO,YAAY,EAAE;GACtC,CAAC,GACA,KAAA;AACJ,SAAO,gBAAgB;GAAE,GAAG;GAAS;GAAe,GAAG;;CAGzD,yBAAiC,YAC/B,KAAK,kBAAkB,IAAI,QAAQ,UAAU,GACzC;EAAE,GAAG;EAAS,QAAQ;EAAW,GACjC;CAEN,0BAAkC,YAGtB;EACV,MAAM,YAAY,mBAAmB,QAAQ,WAAW;AACxD,MAAI,CAAC,UACH;AAEF,MAAI,QAAQ,WAAW,UAAW,MAAK,kBAAkB,IAAI,UAAU;MAClE,MAAK,kBAAkB,OAAO,UAAU;;CAG/C,iCACE,YACA,UACA,SACS;AACT,OAAK,QAAQ,SAAS,KACpB,UAAU,wBACV;GAAE;GAAY;GAAM,UAAU,gBAAgB,SAAS;GAAE,EACzD;GAAE,4BAAW,IAAI,MAAM,EAAC,aAAa;GAAE,QAAQ;GAAe,CAC/D;;;;;ACvbL,SAAgB,sBAAsB,KAA+B;CACnE,MAAM,cAAc,sBAAsB,IAAI;AAC9C,KAAI,CAAC,YACH,QAAO,EAAE;CAGX,MAAM,SAAS,qBAAqB,YAAY;CAChD,MAAM,cAAc,qBAAqB,QAAQ,eAAe,eAAe;CAC/E,MAAM,kBAAkB,qBAAqB,QAAQ,mBAAmB,mBAAmB;AAE3F,QAAO;EACL,MAAMC,aAAW,QAAQ,OAAO;EAChC,SAASA,aAAW,QAAQ,UAAU;EACtC,aAAa,sBAAsB,aAAa,EAAE,IAAIA,aAAW,QAAQ,aAAa,aAAa,EAAE,CAAC;EACtG,aAAaA,aAAW,QAAQ,cAAc;EAC9C,iBAAiB,sBAAsB,iBAAiB,EACtD,IAAIA,aAAW,QAAQ,iBAAiB,iBAAiB,EAC1D,CAAC;EACF,QAAQA,aAAW,QAAQ,SAAS;EACpC,MAAM,SAAS,OAAO;EACvB;;AAGH,SAAgB,sBAAsB,KAAqB;CACzD,MAAM,aAAa,IAAI,QAAQ,SAAS,KAAK;CAC7C,MAAM,QAAQ,WAAW,MAAM,yBAAyB;AACxD,QAAO,QAAQ,WAAW,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,WAAW,MAAM;;AAG7E,SAAgB,sBACd,aACA,GAAG,MACe;AAClB,QAAO;EACL,GAAI,sBAAsB,GAAG,KAAK,IAAI,EAAE;EACxC,IAAI;EACL;;AAGH,SAAS,sBAAsB,KAA4B;AAEzD,QADc,IAAI,QAAQ,SAAS,KAAK,CAAC,MAAM,wBAAwB,GACxD,MAAM;;AAGvB,SAAS,qBAAqB,KAAsC;AAClE,KAAI;EACF,MAAM,SAASC,MAAU,IAAI;AAC7B,SAAOC,WAAS,OAAO,GAAG,SAAS,EAAE;UAC9B,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAM,IAAI,MAAM,iCAAiC,UAAU;;;AAI/D,SAASF,aAAW,QAAiC,GAAG,OAAqC;CAC3F,MAAM,QAAQ,UAAU,QAAQ,MAAM;AACtC,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,KAAA;;AAGpE,SAAS,qBAAqB,QAAiC,GAAG,OAA+C;CAC/G,MAAM,QAAQ,UAAU,QAAQ,MAAM;AACtC,KAAI,CAACE,WAAS,MAAM,CAClB;CAGF,MAAM,YAAY,OAAO,YACvB,OAAO,QAAQ,MAAM,CAClB,QAAQ,UAAqC,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CACxG,KAAK,CAAC,QAAQ,UAAU,CAAC,mBAAmB,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC,CACtE;AACD,QAAO,OAAO,KAAK,UAAU,CAAC,SAAS,IAAI,YAAY,KAAA;;AAGzD,SAAS,SAAS,QAAuD;CACvE,MAAM,QAAQ,UAAU,QAAQ,CAAC,OAAO,CAAC;CAEzC,MAAM,cADO,MAAM,QAAQ,MAAM,GAAG,QAAQ,OAAO,UAAU,WAAW,MAAM,MAAM,IAAI,GAAG,EAAE,EAE1F,QAAQ,UAA2B,OAAO,UAAU,SAAS,CAC7D,KAAK,UAAU,MAAM,MAAM,CAAC,CAC5B,OAAO,QAAQ;AAClB,QAAO,WAAW,SAAS,IAAI,aAAa,KAAA;;AAG9C,SAAS,sBACP,GAAG,MAC2B;CAC9B,MAAM,YAAY,OAAO,YACvB,KAAK,SAAS,QACZ,OAAO,QAAQ,OAAO,EAAE,CAAC,CACtB,QAAQ,UAAqC,OAAO,MAAM,OAAO,YAAY,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CACxG,KAAK,CAAC,QAAQ,UAAU,CAAC,mBAAmB,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC,CACtE,CACF;AACD,QAAO,OAAO,KAAK,UAAU,CAAC,SAAS,IAAI,YAAY,KAAA;;AAGzD,SAAS,UAAU,QAAiC,OAA0B;CAC5E,MAAM,kBAAkB,MAAM,IAAI,wBAAwB;CAC1D,MAAM,cAAc,OAAO,KAAK,OAAO,CAAC,MAAM,cAC5C,gBAAgB,SAAS,wBAAwB,UAAU,CAAC,CAC7D;AACD,QAAO,cAAc,OAAO,eAAe,KAAA;;AAG7C,SAAS,wBAAwB,KAAqB;AACpD,QAAO,IAAI,QAAQ,SAAS,GAAG,CAAC,aAAa;;AAG/C,SAAS,mBAAmB,KAAqB;AAC/C,QAAO,IAAI,MAAM,CAAC,aAAa;;AAGjC,SAASA,WAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;AClF7E,IAAa,eAAb,MAA0B;CACxB;CACA;CAEA,YAAY,QAAyB;AACnC,OAAK,YAAY,QAAQ,OAAO,UAAU;AAC1C,OAAK,SAAS,IAAI,aAAa,KAAK,UAAU;;CAGhD,cAAc,SAA0C,EAAE,KAAsB;AAC9E,SAAO,KAAK,OAAO,WAAW,OAAO,kBAAkB;;CAGzD,gBAAgB,aAA2C;AACzD,SAAO,KAAK,OAAO,aAAa,SAAS;;CAG3C,oBAAoB,aAAoE;AACtF,SAAO,KAAK,OAAO,iBAAiB,SAAS;;CAG/C,oBAAoB,aAAoC;AACtD,SAAO,KAAK,OAAO,UAAU,SAAS;;CAGxC,uBAAuB,SAGnB,EAAE,KAA0B;EAC9B,MAAM,QAAQ,KAAK,wBAAwB,OAAO,MAAM;EACxD,MAAM,kBAAkB,KAAK,wBAAwB,OAAO,MAAM,EAAE,aAAa,IAAI;EAErF,MAAM,SAAS,KACZ,WAAW,EAAE,mBAAmB,OAAO,CAAC,CACxC,KAAK,UAAU,KAAK,2BAA2B,MAAM,CAAC,CACtD,QAAQ,UAAU,UAAU,SAAS,MAAM,UAAU,MAAM,CAC3D,QAAQ,UAAU,KAAK,2BAA2B,OAAO,gBAAgB,CAAC;AAE7E,SAAO;GACL,WAAW,KAAK;GAChB,OAAO,OAAO;GACd;GACD;;CAGH,2BAA2B,aAAkD;EAC3E,MAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,MAAI,CAAC,MACH,QAAO;EAGT,MAAM,UAAU,KAAK,2BAA2B,MAAM;EACtD,MAAM,MAAM,aAAa,MAAM,MAAM,OAAO;AAC5C,SAAO;GACL,GAAG;GACH,UAAU,KAAK,iBAAiB,MAAM;GACtC;GACA,SAAS,sBAAsB,IAAI;GACpC;;CAGH,oBAAoB,SAAuC;AACzD,SAAO,KACJ,WAAW,EAAE,mBAAmB,OAAO,CAAC,CACxC,MAAM,UAAU,MAAM,SAAS,QAAQ,MAAM,WAAW,UAAU,IAAI;;CAG3E,0BAA0B,SAAgC;EACxD,MAAM,QAAQ,KAAK,iBAAiB,KAAK;AACzC,SAAO,QAAQ,QAAQ,MAAM,KAAK,GAAG;;CAGvC,8BAAsC,UAAgD;EACpF,MAAM,MAAM,aAAa,MAAM,MAAM,OAAO;EAC5C,MAAM,WAAW,KAAK,iBAAiB,MAAM;EAC7C,MAAM,cAAc,sBAAsB,IAAI;AAE9C,SAAO;GACL,KAAK,MAAM;GACX,MAAM,MAAM;GACZ,MAAM,MAAM;GACZ,cAAc,KAAK,kBAAkB,MAAM,KAAK;GAChD,OAAO,MAAM;GACb,QAAQ,MAAM;GACd,SAAS,YAAY,WAAW;GAChC,aAAa,YAAY,eAAe;GACxC,aAAa,YAAY,eAAe,UAAU,eAAe;GACjE,iBAAiB,YAAY,mBAAmB;GAChD,QAAQ,YAAY,UAAU;GAC9B,MAAM,YAAY,QAAQ,EAAE;GAC5B,QAAQ,KAAK,eAAe,SAAS;GACtC;;CAGH,8BACE,OACA,UACY;AACZ,MAAI,CAAC,MACH,QAAO;AAkBT,SAfkB;GAChB,MAAM;GACN,MAAM;GACN,MAAM;GACN,MAAM,gBAAgB;GACtB,MAAM;GACN,MAAM;GACN,MAAM,WAAW;GACjB,MAAM,eAAe;GACrB,MAAM,UAAU;GAChB,GAAG,MAAM;GACT,GAAG,OAAO,OAAO,MAAM,eAAe,EAAE,CAAC;GACzC,GAAG,OAAO,OAAO,MAAM,mBAAmB,EAAE,CAAC;GAC9C,CAEgB,MAAM,UAAU,MAAM,aAAa,CAAC,SAAS,MAAM,CAAC;;CAGvE,kBAA0B,aAAqD;AAC7E,MAAI,UAAU,WAAW,OACvB,QAAO;EAGT,MAAM,MAAM,UAAU;AACtB,MAAI,CAAC,IACH,QAAO;AAGT,MAAI;AAMF,UALe,KAAK,MAAM,IAAI,CAKhB,UAAU,WAAW;UAC7B;AACN,UAAO;;;CAIX,qBAA6B,iBAAwC;EACnE,MAAM,eAAe,SAAS,KAAK,WAAW,aAAa,CAAC,QAAQ,OAAO,IAAI;AAC/E,SAAO,aAAa,WAAW,KAAK,GAAG,OAAO;;CAGhD,2BAAmC,UAAyD;EAC1F,MAAM,aAAa,KAAK,wBAAwB,MAAM;AACtD,MAAI,CAAC,cAAc,eAAe,MAChC,QAAO;AAET,MAAI,eAAe,aAAa,eAAe,aAAa,eAAe,YACzE,QAAO;AAET,QAAM,IAAI,MAAM,wBAAwB,MAAM,iDAAiD;;CAGjG,2BAAmC,UAA6C;AAC9E,MAAI,OAAO,UAAU,SACnB,QAAO;EAET,MAAM,UAAU,MAAM,MAAM;AAC5B,SAAO,QAAQ,SAAS,IAAI,UAAU;;;;;ACzL1C,MAAM,wBAAwB;CAAC;CAAW;CAAgB;CAAe;AAEzE,SAASC,wBAAsB,OAAkC;AAC/D,QAAO,MAAM,SAAS,aAAa;;AAGrC,SAAS,yBACP,SACA,MACyB;CACzB,MAAM,QAAiC,EAAE;AACzC,MAAK,MAAM,OAAO,uBAAuB;EACvC,MAAM,QAAQ,KAAK;AACnB,MAAI,CAAC,OAAO,GAAG,QAAQ,MAAM,MAAM,CACjC,OAAM,OAAO,gBAAgB,MAAM;;AAGvC,QAAO;;AAGT,IAAa,oBAAb,MAA+B;CAC7B;CACA;CACA;CACA,+BAAgC,IAAI,KAA0B;CAC9D,WAAuC,EAAE;CACzC,WAAmB;CAEnB,YAAY,SAIT;EACD,MAAM,EACJ,qBACA,UACA,sBACE;AACJ,OAAK,sBAAsB;AAC3B,OAAK,oBAAoB;AACzB,OAAK,WAAW;;CAGlB,UAAU,YAA2B;AACnC,MAAI,KAAK,SACP;AAEF,OAAK,WAAW;AAChB,SAAO,KAAK,SAAS,SAAS,EAC5B,OAAM,KAAK,SAAS,KAAK,IAAI;;CAIjC,aAAa,cAA+B,QAAQ,KAAK,aAAa,IAAI,UAAU,EAAE,gBAAgB;CAEtG,yBAAyB,OACvB,WACA,kBAA2C,EAAE,KACpB,KAAK,kBAAkB,WAAW,gBAAgB;CAE7E,uBAAuB,cACrB,KAAK,aAAa,IAAI,UAAU,EAAE,mBAAmB;CAEvD,wBAAwB,cAAsB;EAC5C,MAAM,UAAU,KAAK,aAAa,IAAI,UAAU,MAAM,CAAC;AACvD,SAAO,UAAU,mBAAmB,0BAAS,IAAI,MAAM,EAAC,aAAa,CAAC,GAAG;;CAG3E,uBACE,WACA,cACS;EACT,MAAM,UAAU,KAAK,mBAAmB,UAAU;EAClD,MAAM,UAAU,QAAQ;AACxB,MAAI,WAAW,YAAY,aAAa,CAAC,QAAQ,OAC/C,OAAM,IAAI,MAAM,WAAW,QAAQ,UAAU,mCAAmC;AAElF,UAAQ,kBAAkB;AAC1B,MAAI,YAAY,UACd,MAAK,wBAAwB;GAAE,YAAY,QAAQ;GAAW,QAAQ;GAAW,CAAC;;CAItF,0BACE,WACA,UACS;EACT,MAAM,UAAU,KAAK,mBAAmB,UAAU;EAClD,MAAM,UAAU,QAAQ;AACxB,MAAI,CAAC,WAAW,QAAQ,UAAU,MAChC;AAEF,UAAQ,SAAS;AACjB,UAAQ,kBAAkB;AAC1B,OAAK,wBAAwB;GAAE,YAAY,QAAQ;GAAW,QAAQ;GAAQ,CAAC;;CAGjF,uBAA6C,OAAO,EAClD,QACA,WACA,iBACmB;AACnB,OAAK,mBAAmB;EACxB,MAAM,sBAAsB,UAAU,MAAM;EAC5C,MAAM,uBAAuB,WAAW,MAAM;AAC9C,MAAI,CAAC,uBAAuB,CAAC,qBAC3B;EAEF,MAAM,UAAU,MAAM,KAAK,kBAAkB,oBAAoB;AACjE,QAAM,KAAK,oBAAoB,SAAS;GACtC,MAAM,aAAa;GACnB,SAAS;IACP,WAAW;IACX,YAAY;IACZ,SAAS;IACV;GACF,CAAC;;CAGJ,wBAAwB,OACtB,WACA,aACqB;AACrB,OAAK,mBAAmB;EACxB,MAAM,sBAAsB,UAAU,MAAM;AAC5C,MAAI,CAAC,oBAAqB,QAAO;EACjC,MAAM,cAAc,KAAK,aAAa,IAAI,oBAAoB;EAC9D,MAAM,gBAAgB,cAAc,OAAO,MAAM,KAAK,kBAAkB,iBAAiB,oBAAoB;AAC7G,MAAI,CAAC,eAAe,CAAC,cAAe,QAAO;AAC3C,SAAO,MAAM,KAAK,kBAAkB,sBAAsB,qBAAqB,SAAS;;CAG1F,qBAAqB,OACnB,WACA,OACA,UAAsC,EAAE,KACtB;AAClB,QAAM,KAAK,oBAAoB,KAAK,mBAAmB,UAAU,EAAE,OAAO,QAAQ;;CAGpF,oBAAqC,OACnC,WACA,kBAA2C,EAAE,KACpB;EACzB,MAAM,WAAW,KAAK,aAAa,IAAI,UAAU;AACjD,MAAI,SACF,QAAO;EAGT,MAAM,gBAAgB,MAAM,KAAK,kBAAkB,iBAAiB,UAAU;EAC9E,MAAM,eAAe,IAAI,yCAAyC;AAClE,eAAa,QAAQ;GACnB;GACA,UAAU,eAAe,SAAS,KAAK,YAAY,gBAAgB,QAAQ,CAAC,IAAI,EAAE;GACnF,CAAC;EACF,MAAM,WAAW;GACf,GAAI,eAAe,WAAW,gBAAgB,cAAc,SAAS,GAAG,EAAE;GAC1E,GAAG,gBAAgB,gBAAgB;GACpC;EACD,MAAM,kBAAkB,KAAK,oBAAoB,uBAAuB,SAAS;EACjF,MAAM,uBAAuB,yBAAyB,UAAU,gBAAgB;AAChF,MAAI,OAAO,KAAK,qBAAqB,CAAC,SAAS,EAC7C,OAAM,KAAK,kBAAkB,sBAAsB,WAAW,qBAAqB;EAErF,MAAM,UAAuB;GAC3B;GACA,GAAIC,aAAW,eAAe,QAAQ,IAAI,YAAY,SAAS,GAC3D,EAAE,SAASA,aAAW,eAAe,QAAQ,IAAI,YAAY,SAAS,EAAE,GACxE,EAAE;GACN;GACA,SAAS;GACT,iBAAiB;GAClB;AACD,UAAQ,UAAU,KAAK,oBAAoB,cAAc;GACvD;GACA,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;GACvD;GACA,iBAAiB;GAClB,CAAC;AACF,OAAK,aAAa,IAAI,WAAW,QAAQ;AACzC,OAAK,SAAS,KAAK,YAAY;AAC7B,WAAQ,iBAAiB,WAAW,OAAO;AAC3C,SAAM,eAAe,QAAQ,QAAQ;AACrC,QAAK,aAAa,OAAO,UAAU;IACnC;AACF,SAAO;;CAGT,sBAAuC,cAAmC;EACxE,MAAM,UAAU,KAAK,aAAa,IAAI,UAAU;AAChD,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,WAAW,UAAU,eAAe;AAEtD,SAAO;;CAGT,sBAAuC,OACrC,SACA,OACA,UAAsC,EAAE,KACtB;AAClB,MAAI,QAAQ,2BAA2B,MACrC,OAAM,QAAQ,aAAa,SAAS,MAAM;AAE5C,MAAI,QAAQ,mBAAmB,MAC7B,OAAM,KAAK,wBAAwB,SAAS,MAAM;AAEpD,OAAK,SAAS,KAAK,UAAU,UAAU,OAAO;GAC5C,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,QAAQ;GACT,CAAC;;CAGJ,0BAA2C,OAAO,SAAsB,UAA2C;AACjH,MAAI,CAACD,wBAAsB,MAAM,CAC/B;AAEF,QAAM,KAAK,kBAAkB,mBAAmB;GAC9C,WAAW,QAAQ;GACnB;GACD,CAAC;;CAGJ,0BAAiD;AAC/C,MAAI,KAAK,SACP,OAAM,IAAI,MAAM,iDAAiD;;CAIrE,2BAAmC,YAAsE;AACvG,OAAK,SAAS,KAAK,UAAU,kBAAkB,SAAS;GACtD,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,QAAQ;GACT,CAAC;;;;;AC7ON,IAAa,+BAAb,MAA0C;CACxC,YAAY,YAAqC;AAApB,OAAA,aAAA;;CAE7B,QAAQ,OAAO,WAAmD;AAChE,QAAM,MAAM,KAAK,YAAY,EAAE,WAAW,MAAM,CAAC;EACjD,MAAM,aAAa,KAAK,aAAa,OAAO,UAAU;EACtD,MAAM,WAAW,GAAG,WAAW,GAAG,QAAQ,IAAI,GAAG,YAAY,CAAC;AAC9D,MAAI;AACF,SAAM,UAAU,UAAU,GAAG,KAAK,UAAU,0CAA0C,OAAO,CAAC,CAAC,KAAK,QAAQ;AAC5G,SAAM,OAAO,UAAU,WAAW;WAC3B,OAAO;AACd,SAAM,GAAG,UAAU,EAAE,OAAO,MAAM,CAAC;AACnC,SAAM;;;CAIV,OAAO,OACL,WACA,qBAC6C;AAC7C,MAAI;GACF,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,aAAa,UAAU,EAAE,QAAQ,CAAC;AAChF,OAAI,CAACE,WAAS,OAAO,IAAI,OAAO,UAAU,cAAc,CAACA,WAAS,OAAO,SAAS,CAChF,OAAM,IAAI,MAAM,+CAA+C,YAAY;GAE7E,MAAM,YAAY,YAAY,OAAO,YAAY,iBAAiB,UAAU;GAC5E,MAAM,UAAU,oBAAoB,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW,KAAA,EAAU;AACtG,UAAO;IACL,UAAU,gBAAgB,OAAO,SAAS;IAC1C,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;IAC9B;IACA,WAAW,iBAAiB;IAC7B;WACM,OAAO;AAEd,QADa,SAAS,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,OAAO,KAAA,OACrE,SACX,QAAO;AAET,SAAM;;;CAIV,SAAS,OAAO,cAAqC;AACnD,QAAM,GAAG,KAAK,aAAa,UAAU,EAAE,EAAE,OAAO,MAAM,CAAC;;CAGzD,gBAAwB,cAA8B;AACpD,SAAO,KAAK,KAAK,YAAY,GAAG,uBAAuB,UAAU,QAAQ,MAAM,IAAI,CAAC,CAAC,gBAAgB;;;;;ACpDzG,SAAS,qBAAqB,SAA+C;CAC3E,MAAM,EAAE,UAAU,WAAW,GAAG,gBAAgB;AAEhD,QAAO;;AAGT,IAAa,mCAAb,MAA8C;CAC5C,eAA8D;CAE9D,YACE,YACA,aACA;AAFiB,OAAA,aAAA;AACA,OAAA,cAAA;;CAGnB,MAAM,OAAO,eAAyC,MAAM,KAAK,MAAM,EAAE,IAAI,UAAU;CAEvF,OAAO,YAA0C;AAE/C,SAAO,CAAC,IADM,MAAM,KAAK,MAAM,EACd,QAAQ,CAAC,CACvB,KAAK,YAAY,gBAAgB,QAAQ,CAAC,CAC1C,MAAM,MAAM,UAAU,gCAAgC,MAAM,CAAC,cAAc,gCAAgC,KAAK,CAAC,CAAC;;CAGvH,SAAS,OAAO,YAA8C;AAE5D,GADc,MAAM,KAAK,MAAM,EACzB,IAAI,QAAQ,WAAW,qBAAqB,gBAAgB,QAAQ,CAAC,CAAC;AAC5E,QAAM,KAAK,SAAS;;CAGtB,iBAAiB,OAAO,WAIH;EACnB,MAAM,EAAE,OAAO,WAAW,cAAc;EACxC,MAAM,QAAQ,MAAM,KAAK,MAAM;EAC/B,MAAM,UAAU,kCAAkC;GAChD,SAAS,MAAM,IAAI,UAAU;GAC7B;GACA;GACA;GACD,CAAC;AACF,QAAM,IAAI,QAAQ,WAAW,qBAAqB,QAAQ,CAAC;AAC3D,QAAM,KAAK,SAAS;;CAGtB,SAAS,OAAO,cAAqC;AAEnD,GADc,MAAM,KAAK,MAAM,EACzB,OAAO,UAAU;AACvB,QAAM,KAAK,SAAS;;CAGtB,OAAe,YAAqD;AAClE,MAAI,KAAK,aACP,QAAO,KAAK;AAEd,MAAI;GACF,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,WAAW,EAAE,QAAQ,CAAC;AACpE,OAAI,OAAO,YAAA,KAAuD,MAAM,QAAQ,OAAO,QAAQ,EAAE;AAC/F,SAAK,eAAe,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,CACzD,OAAO,WACP,qBAAqB,gBAAgB,OAAO,CAAC,CAC9C,CAAC,CAAC;AACH,WAAO,KAAK;;UAER;AAGR,OAAK,eAAe,MAAM,KAAK,SAAS;AACxC,QAAM,KAAK,SAAS;AACpB,SAAO,KAAK;;CAGd,UAAkB,YAAqD;EACrE,MAAM,0BAAU,IAAI,KAAgC;EACpD,IAAI,UAAoB,EAAE;AAC1B,MAAI;AACF,aAAU,MAAM,QAAQ,KAAK,WAAW;UAClC;AACN,UAAO;;AAET,OAAK,MAAM,SAAS,SAAS;AAC3B,OAAI,CAAC,MAAM,SAAS,SAAS,CAC3B;GAEF,MAAM,YAAY,MAAM,QAAQ,YAAY,GAAG,CAAC,QAAQ,MAAM,IAAI;GAClE,MAAM,SAAS,MAAM,KAAK,YAAY,UAAU;AAChD,OAAI,OACF,SAAQ,IAAI,WAAW,qBAAqB,6BAA6B,OAAO,OAAO,CAAC,CAAC;;AAG7F,SAAO;;CAGT,UAAkB,YAA2B;EAC3C,MAAM,UAAU,CAAC,GAAI,KAAK,cAAc,QAAQ,IAAI,EAAE,CAAE,CACrD,KAAK,YAAY,qBAAqB,gBAAgB,QAAQ,CAAC,CAAC,CAChE,MAAM,MAAM,UAAU,gCAAgC,MAAM,CAAC,cAAc,gCAAgC,KAAK,CAAC,CAAC;AACrH,QAAM,MAAM,KAAK,YAAY,EAAE,WAAW,MAAM,CAAC;AACjD,QAAM,UACJ,KAAK,WAAW,EAChB,GAAG,KAAK,UAAU;GAAE,SAAA;GAAkD;GAAS,CAAC,CAAC,KACjF,QACD;;CAGH,kBAAkC,QAAQ,KAAK,YAAY,qCAAqC;;;;AC1FlG,SAAS,sBAAsB,OAAiD;CAC9E,MAAM,aAAa,KAAK,UAAU,MAAM;AACxC,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,sEAAsE;AAGxF,KAAI,CAACC,WADU,KAAK,MAAM,WAAW,CAChB,CACnB,OAAM,IAAI,MAAM,4EAA4E;AAE9F,QAAO;;AAGT,IAAa,8BAAb,MAAyC;CACvC,2BAA4B,IAAI,KAA2C;CAC3E,mCAAoC,IAAI,KAAqB;CAC7D,8BAA+B,IAAI,KAA4B;CAC/D;CACA;CAEA,YAAY,YAAqC;AAApB,OAAA,aAAA;AAC3B,OAAK,gBAAgB,IAAI,6BAA6B,WAAW;AACjE,OAAK,oBAAoB,IAAI,iCAC3B,YACA,OAAO,cAAc,KAAK,YAAY,UAAU,CACjD;;CAGH,qBAAqB,OAAO,WAGP;EACnB,MAAM,YAAY,sBAAsB,OAAO,UAAU;AACzD,MAAI,CAAC,UACH;EAGF,MAAM,QADW,KAAK,YAAY,IAAI,UAAU,IAAI,QAAQ,SAAS,EAC/C,WAAW,KAAK,sBAAsB;GAC1D,GAAG;GACH;GACD,CAAC,CAAC;AACH,OAAK,YAAY,IAAI,WAAW,KAAK,YAAY,KAAA,EAAU,CAAC;AAC5D,QAAM;;CAGR,aAAa,OAAO,cAA0D;EAC5E,MAAM,sBAAsB,sBAAsB,UAAU;AAC5D,MAAI,CAAC,oBACH,QAAO;EAET,MAAM,SAAS,KAAK,SAAS,IAAI,oBAAoB;AACrD,MAAI,OACF,QAAO,gBAAgB,OAAO,OAAO;EAEvC,MAAM,SAAS,MAAM,KAAK,YAAY,oBAAoB;AAC1D,MAAI,CAAC,OACH,QAAO;AAET,OAAK,SAAS,IAAI,qBAAqB,OAAO;AAC9C,SAAO,gBAAgB,OAAO,OAAO;;CAGvC,uBAAuB,YAA0C;EAC/D,MAAM,YAAY,MAAM,KAAK,kBAAkB,MAAM;AACrD,SAAO,MAAM,QAAQ,IAAI,UAAU,IAAI,KAAK,aAAa,CAAC;;CAG5D,sBAAsB,OAAO,cAA6C;EACxE,MAAM,UAAU,MAAM,KAAK,WAAW,UAAU;AAChD,SAAO,UAAU,QAAQ,SAAS,KAAK,YAAY,gBAAgB,QAAQ,CAAC,GAAG,EAAE;;CAGnF,qBAAqB,OAAO,WAGJ;EACtB,MAAM,YAAY,sBAAsB,OAAO,UAAU;AACzD,MAAI,CAAC,UACH,QAAO;EAGT,MAAM,QADW,KAAK,YAAY,IAAI,UAAU,IAAI,QAAQ,SAAS,EAC/C,WAAW,KAAK,sBAAsB;GAC1D,GAAG;GACH;GACD,CAAC,CAAC;AACH,OAAK,YAAY,IAAI,WAAW,KAAK,WAAW,KAAA,SAAiB,KAAA,EAAU,CAAC;AAC5E,SAAO,MAAM;;CAGf,wBAAwB,OAAO,WAGP;EACtB,MAAM,YAAY,sBAAsB,OAAO,UAAU;AACzD,MAAI,CAAC,UACH,QAAO;EAGT,MAAM,QADW,KAAK,YAAY,IAAI,UAAU,IAAI,QAAQ,SAAS,EAC/C,WAAW,KAAK,yBAAyB;GAC7D,GAAG;GACH;GACD,CAAC,CAAC;AACH,OAAK,YAAY,IAAI,WAAW,KAAK,WAAW,KAAA,SAAiB,KAAA,EAAU,CAAC;AAC5E,SAAO,MAAM;;CAGf,wBAAgC,OAAO,WAGf;EACtB,MAAM,EAAE,UAAU,cAAc;EAChC,MAAM,SAAS,KAAK,SAAS,IAAI,UAAU,IAAI,MAAM,KAAK,YAAY,UAAU;AAChF,MAAI,CAAC,OACH,QAAO;EAET,MAAM,aAAiC;GACrC,GAAG,OAAO;GACV,UAAU,gBAAgB,SAAS;GACpC;AACD,QAAM,KAAK,cAAc,MAAM,WAAW;AAC1C,OAAK,SAAS,IAAI,WAAW;GAC3B,QAAQ;GACR,SAAS,OAAO;GACjB,CAAC;AACF,OAAK,iBAAiB,IAAI,WAAW,OAAO,QAAQ;AACpD,QAAM,KAAK,kBAAkB,OAAO,6BAA6B,WAAW,CAAC;AAC7E,SAAO;;CAGT,2BAAmC,OAAO,WAGlB;EACtB,MAAM,SAAS,KAAK,SAAS,IAAI,OAAO,UAAU,IAAI,MAAM,KAAK,YAAY,OAAO,UAAU;AAC9F,MAAI,CAAC,OACH,QAAO;AAET,SAAO,MAAM,KAAK,sBAAsB;GACtC,GAAG;GACH,UAAU;IACR,GAAI,OAAO,OAAO,WAAW,gBAAgB,OAAO,OAAO,SAAS,GAAG,EAAE;IACzE,GAAG,gBAAgB,OAAO,SAAS;IACpC;GACF,CAAC;;CAGJ,wBAAwB,OAAO,WAA8C;EAC3E,MAAM,YAAY,sBAAsB,OAAO,UAAU;AACzD,MAAI,CAAC,UACH;AAEF,QAAM,KAAK,kBAAkB;EAC7B,MAAM,aAAa,gBAAgB;GAAE,GAAG;GAAQ;GAAW,CAAC;AAC5D,QAAM,KAAK,cAAc,MAAM,WAAW;EAC1C,MAAM,UAAU,WAAW,SAAS,KAAK,SAAS,WAA6C;GAC7F,OAAO;GACP,SAAA;GACA,KAAK,QAAQ;GACb,WAAW,QAAQ,aAAa,WAAW;GAC3C,OAAO;IACL,MAAM;IACN,SAAS;KACP;KACA,SAAS,gBAAgB,QAAQ;KAClC;IACF;GACF,EAAE;AACH,QAAM,UACJ,KAAK,YAAY,UAAU,EAC3B,QAAQ,SAAS,IAAI,GAAG,QAAQ,IAAI,sBAAsB,CAAC,KAAK,KAAK,CAAC,MAAM,IAC5E,QACD;EACD,MAAM,UAAU,WAAW,SAAS,SAAS;AAC7C,OAAK,SAAS,IAAI,WAAW;GAC3B,QAAQ;GACR;GACD,CAAC;AACF,OAAK,iBAAiB,IAAI,WAAW,QAAQ;AAC7C,QAAM,KAAK,kBAAkB,OAAO,6BAA6B,WAAW,CAAC;;CAG/E,gBAAgB,OAAO,cAA0D;EAC/E,MAAM,sBAAsB,sBAAsB,UAAU;AAC5D,MAAI,CAAC,oBACH,QAAO;EAET,MAAM,WAAW,MAAM,KAAK,WAAW,oBAAoB;AAC3D,OAAK,SAAS,OAAO,oBAAoB;AACzC,OAAK,iBAAiB,OAAO,oBAAoB;AACjD,MAAI;AACF,SAAM,OAAO,KAAK,YAAY,oBAAoB,CAAC;UAC7C;AAGR,QAAM,KAAK,cAAc,OAAO,oBAAoB;AACpD,QAAM,KAAK,kBAAkB,OAAO,oBAAoB;AACxD,SAAO;;CAGT,aAAa,OAAO,cAAwC;EAC1D,MAAM,sBAAsB,sBAAsB,UAAU;AAC5D,MAAI,CAAC,oBACH,QAAO;AAET,SAAO,KAAK,kBAAkB,IAAI,oBAAoB;;CAGxD,wBAAgC,OAAO,WAGlB;EACnB,MAAM,EAAE,OAAO,cAAc;EAC7B,MAAM,6BAAY,IAAI,MAAM,EAAC,aAAa;AAC1C,QAAM,KAAK,kBAAkB;EAC7B,MAAM,WAAW,KAAK,SAAS,IAAI,UAAU,KACvC,KAAK,iBAAiB,IAAI,UAAU,GAAG,OAAO,MAAM,KAAK,YAAY,UAAU;EACrF,MAAM,UAAU,KAAK,iBAAiB,IAAI,UAAU,IAAI,UAAU,WAAW;EAC7E,MAAM,OAAO,KAAK,YAAY,UAAU;EACxC,MAAM,QAA0C;GAC9C,OAAO;GACP,SAAA;GACA,KAAK;GACL,WAAW;GACX,OAAO,gBAAgB,MAAM;GAC9B;AACD,QAAM,KAAK,mBAAmB,MAAM,MAAM;AAC1C,OAAK,iBAAiB,IAAI,WAAW,UAAU,EAAE;AACjD,OAAK,SAAS,OAAO,UAAU;AAC/B,QAAM,KAAK,kBAAkB,eAAe;GAC1C;GACA;GACA;GACD,CAAC;;CAGJ,eAAuB,OAAO,YAA2D;EACvF,MAAM,WAAW,MAAM,KAAK,cAAc,KAAK,QAAQ,WAAW;GAChE,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;GACvD,WAAW,QAAQ,aAAa,QAAQ;GACxC,WAAW,QAAQ;GACnB,UAAU,EAAE;GACb,CAAC;AACF,SAAO;GACL,GAAG;GACH,GAAI,CAAC,QAAQ,WAAW,SAAS,UAAU,EAAE,SAAS,SAAS,SAAS,GAAG,EAAE;GAC7E,GAAI,OAAO,KAAK,SAAS,SAAS,CAAC,SAAS,IAAI,EAAE,UAAU,SAAS,UAAU,GAAG,EAAE;GACrF;;CAGH,cAAsB,OAAO,cAAoE;EAC/F,IAAI;AACJ,MAAI;AACF,SAAM,MAAM,SAAS,KAAK,YAAY,UAAU,EAAE,QAAQ;UACpD;AACN,UAAO;;EAGT,MAAM,gBAAgB,KAAK,oBAAoB,IAAI;EAEnD,MAAM,EAAE,SAAS,WAAW,WAAW,aADf,MAAM,KAAK,cAAc,KAAK,WAAW,cAAc;EAE/E,MAAM,EAAE,QAAQ,YAAY;EAC5B,MAAM,WAAW,MAAM,4BAA4B,OAAO;EAC1D,MAAM,SAA6B;GACjC;GACA,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;GAC9B;GACA;GACA;GACA;GACD;AACD,OAAK,iBAAiB,IAAI,WAAW,QAAQ;AAC7C,SAAO;GACL;GACA;GACD;;CAGH,uBAA+B,QAA8C;EAC3E,IAAI,WAAoC,EAAE;EAC1C,IAAI;EACJ,IAAI,6BAAY,IAAI,MAAM,EAAC,aAAa;EACxC,IAAI,YAAY;EAChB,IAAI,UAAU;EACd,MAAM,SAA8C,EAAE;AACtD,OAAK,MAAM,CAAC,OAAO,SAAS,IAAI,MAAM,KAAK,CAAC,SAAS,EAAE;AACrD,OAAI,CAAC,KAAK,MAAM,CACd;GAEF,IAAI;AACJ,OAAI;AACF,aAAS,KAAK,MAAM,KAAK;YAClB,OAAO;AACd,YAAQ,KACN,8DAA8D,QAAQ,EAAE,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GACnI;AACD;;AAEF,OAAI,CAACA,WAAS,OAAO,CACnB;AAEF,OAAI,OAAO,UAAU,YAAY;AAC/B,eAAWA,WAAS,OAAO,SAAS,GAAG,gBAAgB,OAAO,SAAS,GAAG,EAAE;AAC5E,cAAU,oBAAoB,OAAO,OAAO,aAAa,WAAW,OAAO,WAAW,KAAA,EAAU;AAChG,gBAAY,YAAY,OAAO,YAAY,UAAU;AACrD,gBAAY,YAAY,OAAO,YAAY,UAAU;AACrD;;AAEF,OAAI,OAAO,UAAU,WAAWA,WAAS,OAAO,MAAM,EAAE;IACtD,MAAM,MAAM,OAAO,OAAO,IAAI;AAC9B,cAAU,KAAK,IAAI,SAAS,OAAO,SAAS,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,IAAI,QAAQ;AACjF,gBAAY,YAAY,OAAO,WAAW,UAAU;IACpD,MAAM,QAAQ,gBAAgB,OAAO,MAAM;AAC3C,WAAO,KAAK,MAAM;;;AAGtB,SAAO;GAAE;GAAU,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;GAAG;GAAW;GAAW;GAAS;GAAQ;;CAG7F,qBAA6B,OAC3B,MACA,UACkB;AAClB,QAAM,WAAW,MAAM,GAAG,sBAAsB,MAAM,CAAC,KAAK,QAAQ;;CAGtE,mBAA2B,YAA2B;AACpD,QAAM,MAAM,KAAK,YAAY,EAAE,WAAW,MAAM,CAAC;;CAGnD,eAAuB,cAA8B;AACnD,SAAO,KAAK,KAAK,YAAY,GAAG,uBAAuB,UAAU,QAAQ,MAAM,IAAI,CAAC,CAAC,QAAQ;;;;;ACtUjG,SAAS,gBAAgB,QAAgD;AACvE,QAAO,mBAAmB,OAAO,UAAU,MAAM,IAAI,KAAA;;AAGvD,IAAa,wBAAb,MAAmC;CACjC,YAAY,SAAwD;AAAvC,OAAA,UAAA;;CAE7B,yBAAyB,OACvB,WACsC;EACtC,MAAM,EACJ,iBACA,kBACA,sBACA,uBACA,mBACA,MACA,OACA,OACA,SACA,cACA,aACA,eACA,aACA,SACA,iBACA,WACE;EACJ,MAAM,YAAY,YAAY;EAC9B,MAAM,iBAAiB,MAAM,KAAK,QAAQ,kBAAkB,cAAc;GACxE;GACA,GAAI,kBAAkB,EAAE,iBAAiB,GAAG,EAAE;GAC9C;GACA;GACA;GACA,GAAI,oBAAoB,EAAE,mBAAmB,GAAG,EAAE;GAClD;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;AAEF,SAAO,KAAK,gBAAgB;GAC1B;GACA;GACA;GACA;GACA,iBAAiB,eAAe;GAChC;GACA,OAAO,eAAe,SAAS,4BAA4B,KAAK;GAChE,cAAc,gBAAgB;GAC9B;GACA,SAAS,eAAe;GACxB,gBAAgB,QAAQ,gBAAgB;GACxC,GAAI,kBAAkB,EAAE,iBAAiB,GAAG,EAAE;GAC9C,oBAAoB;GACrB,CAAC;;CAGJ,iBAAiB,OACf,WACsC;EACtC,MAAM,EACJ,iBACA,kBACA,sBACA,iBACA,MACA,OACA,QACA,iBACE;EACJ,MAAM,4BAA4B,gBAAgB,MAAM;AAExD,MAAI,8BAA8B,gBAAgB,MAAM,CACtD,OAAM,IAAI,MAAM,sDAAsD;EAExE,MAAM,gBAAgB,MAAM,KAAK,QAAQ,kBAAkB,iBAAiB,0BAA0B;AACtG,MAAI,CAAC,cACH,OAAM,IAAI,MAAM,6BAA6B,kBAAkB;EAEjE,MAAM,kBAAkB,oBAAoB,cAAc,SAAS;AAEnE,SAAO,KAAK,gBAAgB;GAC1B,WAAW,YAAY;GACvB;GACA;GACA;GACA,iBAAiB;GACjB;GACA,OACE,mBAAmB,MAAM,IACzB,gBAAgB,cAAc,IAC9B,4BAA4B,KAAK;GACnC,cAAc,gBAAgB;GAC9B;GACA,SAAS,cAAc;GACvB,gBAAgB,QAAQ,gBAAgB;GACxC,iBAAiB,mBAAmB,KAAA;GACpC,oBAAoB,KAAA;GACrB,CAAC;;CAGJ,kBAA0B,OACxB,WACsC;EACtC,MAAM,EACJ,WACA,iBACA,kBACA,sBACA,iBACA,MACA,OACA,cACA,QACA,SACA,gBACA,iBACA,uBACE;EACJ,MAAM,UAAU,4BAA4B;GAC1C;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;EACF,MAAM,gBAA6C;GACjD;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACD,MAAM,UAAU,KAAK,wBAAwB,SAAS,cAAc;AAEpE,MAAI,WAAW,cACb,QAAO,MAAM,KAAK,WAAW,QAAQ;AAGlC,OAAK,kCAAkC,QAAQ;AAEpD,SAAO,KAAK,gBAAgB;GAC1B,GAAG;GACH,SAAS;GACV,CAAC;;CAGJ,2BACE,SACA,mBAC2B;EAC3B;EACA;EACD;CAED,mBACE,YAC6B;EAC7B,MAAM,EACJ,MACA,OACA,SACA,gBACA,iBACA,uBACE,QAAQ;AACZ,SAAO,8BAA8B;GACnC,SAAS,QAAQ;GACjB;GACA;GACA;GACA,GAAI,UAAU,EAAE,SAAS,GAAG,EAAE;GAC9B,GAAI,kBAAkB,EAAE,iBAAiB,GAAG,EAAE;GAC9C,GAAI,qBAAqB,EAAE,oBAAoB,GAAG,EAAE;GACpD,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;GACxD,CAAC;;CAGJ,sBAA8B,OAC5B,SACA,SACkB;AAClB,QAAM,KAAK,mBAAmB,QAAQ,iBAAiB,MAAM,QAAQ;AACrE,QAAM,KAAK,mBAAmB,QAAQ,iBAAiB,MAAM,QAAQ;;CAGvE,aAAqB,OACnB,YACsC;EACtC,MAAM,EAAE,SAAS,kBAAkB;EACnC,MAAM,iBAAkC,EAAE;AAC1C,MAAI;GACF,MAAM,iBAAiB,MAAM,KAAK,QAAQ,WAAW,SAAS;IAC5D;IACA,MAAM,cAAc;IACpB,aAAa,cAAc;AACzB,oBAAe,KAAK,KAAK,2BAA2B,SAAS,UAAU,CAAC;;IAE3E,CAAC;AACF,SAAM,QAAQ,IAAI,eAAe;GACjC,MAAM,mBAAmB,8BAA8B;IACrD;IACA,wBAAwB,eAAe;IACvC,mBAAmB,eAAe;IACnC,CAAC;AACF,SAAM,KAAK,oBAAoB,kBAAkB,yCAAyC;AAC1F,UAAO,KAAK,gBAAgB,KAAK,wBAAwB,kBAAkB,cAAc,CAAC;WACnF,OAAO;AACd,SAAM,QAAQ,IAAI,eAAe;GACjC,MAAM,gBAAgB,2BAA2B;IAC/C;IACA;IACD,CAAC;AACF,SAAM,KAAK,oBAAoB,eAAe,sCAAsC;AACpF,UAAO,KAAK,gBAAgB,KAAK,wBAAwB,eAAe,cAAc,CAAC;;;CAI3F,oCAA4C,OAC1C,YACkB;AAClB,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,WAAW,QAAQ;AAC7C,SAAM,QAAQ,cAAc,qBAAqB,OAAO;WACjD,OAAO;AACd,WAAQ,MACN,wCAAwC,QAAQ,QAAQ,UAAU,YAChE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAEzD;;;CAIL,6BAAqC,OACnC,SACA,cACkB;EAClB,MAAM,kBAAwC;GAC5C,GAAG;GACH,iBAAiB;GAClB;AACD,QAAM,KAAK,mBAAmB,QAAQ,iBAAiB,yCAAyC,gBAAgB;AAChH,QAAM,KAAK,mBAAmB,QAAQ,iBAAiB,yCAAyC,gBAAgB;;CAGlH,qBAA6B,OAC3B,WACA,MACA,YACkB;EAClB,MAAM,QAAuC;GAC3C;GACA,SAAS;IACP;IACA,SAAS,gBAAgB,QAAQ;IAClC;GACF;AACD,QAAM,KAAK,QAAQ,kBAAkB,mBAAmB;GACtD;GACA;GACD,CAAC;;;;;AC9RN,SAAS,0BAA0B,SAAyC;CAC1E,MAAM,QAAQ,QAAQ,MACnB,SAAS,SAAS,KAAK,SAAS,UAAU,KAAK,SAAS,cAAc,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC,CACvF,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,EAAE;AACpC,QAAO,MAAM,SAAS,IAAI,MAAM,KAAK,OAAO,GAAG,KAAA;;AAGjD,SAAgB,gCAAgC,OAO9C;CACA,IAAI,oBAAmC;CACvC,MAAM,wCAAwB,IAAI,KAAyB;CAC3D,IAAI,oBAAiC,KAAA;CACrC,MAAM,mBAAmB,cAA4B;AACnD,sBAAoB;AACpB,QAAM,WAAW,UAAU;;CAE7B,MAAM,UAAU,IAAI,SAAqB,SAAS,WAAW;AAC3D,gBAAc,MAAM,SAAS,GAAG,UAAU,WAAW,UAAU;AAC7D,WAAQ,MAAM,MAAd;IACE,KAAK,aAAa;AAChB,SAAI,MAAM,QAAQ,kBAAkB,MAAM,UACxC,iBAAgB,MAAM,QAAQ,UAAU;AAE1C;IACF,KAAK,aAAa;AAChB,SAAI,MAAM,QAAQ,kBAAkB,MAAM,aAAa,MAAM,QAAQ,QAAQ,OAAO,mBAAmB;AACrG,mBAAa;AACb,cAAQ,MAAM,QAAQ,QAAQ;AAC9B;;AAEF,2BAAsB,IAAI,MAAM,QAAQ,QAAQ,IAAI,MAAM,QAAQ,QAAQ;AAC1E;IACF,KAAK,aAAa;AAChB,UACG,MAAM,QAAQ,kBAAkB,MAAM,aACrC,MAAM,QAAQ,cAAc,sBAC9B,MAAM,QAAQ,WACd;AACA,sBAAgB,MAAM,QAAQ,UAAU;MACxC,MAAM,mBAAmB,sBAAsB,IAAI,MAAM,QAAQ,UAAU;AAC3E,UAAI,kBAAkB;AACpB,oBAAa;AACb,eAAQ,iBAAiB;;;AAG7B;IACF,KAAK,aAAa;AAChB,SAAI,MAAM,QAAQ,kBAAkB,MAAM,aAAa,MAAM,QAAQ,cAAc,mBAAmB;AACpG,mBAAa;AACb,aAAO,IAAI,MAAM,MAAM,QAAQ,MAAM,QAAQ,CAAC;;AAEhD;IACF,KAAK,aAAa;AAChB,SACE,MAAM,QAAQ,kBAAkB,MAAM,aACtC,MAAM,QAAQ,cAAc,mBAC5B;AACA,mBAAa;AACb,aAAO,IAAI,MAAM,MAAM,QAAQ,SAAS,0BAA0B,CAAC;;AAErE;;IAEJ;GACF;AACF,QAAO;EACL,SAAS;EACT;EACD;;AAGH,eAAsB,mCAAmC,OAIvC;AAChB,OAAM,MAAM,QAAQ,OAAsD;EACxE,MAAM,YAAY,SAAS;EAC3B,SAAS;GACP,SAAS;IACP,IAAI,GAAG,MAAM,QAAQ,gBAAgB,wBAAwB,MAAM,QAAQ;IAC3E,WAAW,MAAM,QAAQ;IACzB,MAAM;IACN,QAAQ;IACR,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,OAAO,CAAC;KAAE,MAAM;KAAQ,MAAM,MAAM;KAAM,CAAC;IAC3C,UAAU,EAAE,oBAAoB,MAAM,QAAQ,WAAW;IAC1D;GACD,WAAW,MAAM,QAAQ;GACzB,WAAW,MAAM,QAAQ;GAC1B;EACF,EAAE,EAAE,QAAQ,mBAAmB,CAAC;;AAGnC,SAAgB,2CACd,SAC0B;AAC1B,QAAO,EACL,UAAU,OAAO,UAAU;EACzB,MAAM,QAAQ,gCAAgC;GAC5C,UAAU,QAAQ;GAClB,YAAY,MAAM;GAClB,WAAW,MAAM,QAAQ;GAC1B,CAAC;AACF,MAAI;AACF,SAAM,mCAAmC;IACvC,SAAS,QAAQ;IACjB,SAAS,MAAM;IACf,MAAM,MAAM;IACb,CAAC;GACF,MAAM,UAAU,MAAM,MAAM;AAC5B,UAAO;IACL,wBAAwB,QAAQ;IAChC,mBAAmB,0BAA0B,QAAQ;IACtD;WACM,OAAO;AACd,SAAM,SAAS;AACf,SAAM;;IAGX;;;;AC7HH,IAAa,mCAAb,MAA8C;CAC5C;CAEA,YACE,eACA,iBACA,mBACA;AADiB,OAAA,oBAAA;AAEjB,OAAK,mBAAmB,IAAI,kCAAkC;GAC5D;GACA;GACD,CAAC;;CAGJ,eAAe,OACb,UACyC;EACzC,MAAM,cAAc,KAAK,iBAAiB,MAAM;GAC9C,eAAe,EAAE;GACjB,iBAAiB,MAAM;GACvB,WAAW,MAAM;GACjB,iBAAiB,MAAM;GACvB,eAAe,MAAM;GACrB,gBAAgB,MAAM;GACvB,CAAC;EACF,MAAM,SAAS,MAAM,KAAK,SAAS,MAAM,WAAW,YAAY;AAChE,MAAI,CAAC,YAAY,kBACf,QAAO;EAET,MAAM,eAAe,MAAM,KAAK,iBAAiB,OAAO,YAAY,kBAAkB;AACtF,SAAO,CACL,GAAG,QACH,GAAI,MAAM,KAAK,SAAS,MAAM,WAAW,aAAa,CACvD;;CAGH,WAAmB,OACjB,WACA,WACgC;AAChC,MAAI,OAAO,KAAK,OAAO,cAAc,CAAC,SAAS,EAC7C,OAAM,KAAK,kBAAkB,qBAAqB,WAAW,OAAO,cAAc;AAEpF,MAAI,CAAC,OAAO,gBACV,QAAO,EAAE;AAEX,SAAO,CACL;GACE,MAAM,aAAa;GACnB,SAAS;IACP;IACA,SAAS,OAAO;IACjB;GACF,CACF;;;;;AChCL,SAAS,kBAAkB,UAAuD;CAChF,MAAM,WAAW,SAAS,YAAY,EAAE;CACxC,MAAM,kBAAkB;EACtB,gBAAgB,SAAS;EACzB,SAAS,SAAS;EAClB,aAAa,SAAS;EACtB,SAAS,SAAS;EAClB,eAAe,SAAS;EACxB,UAAU,gBAAgB,SAAS;EACnC,OAAO,SAAS;EAChB,WAAW,SAAS;EACpB,gBAAgB,SAAS;EAC1B;AACD,KAAI,MAAM,QAAQ,SAAS,QAAQ,CACjC,QAAO;EACL,GAAG;EACH,WAAW,SAAS;EACpB,SAAS;GACP,WAAW,SAAS,aAAa;GACjC,IAAI,gBAAgB,YAAY;GAChC,MAAM;GACN,QAAQ;GACR,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,OAAO,gBAAgB,SAAS,QAAQ;GACzC;EACF;CAEH,MAAM,gBAAgB,SAAS;AAC/B,KAAI,CAAC,cACH,OAAM,IAAI,MAAM,kCAAkC;CAEpD,MAAM,mBAAmB,cAAc;CACvC,MAAM,UAAsB;EAC1B,GAAG;EACH,WAAW,oBAAoB,SAAS,aAAa;EACrD,IAAI,cAAc,MAAM,gBAAgB,YAAY;EACpD,MAAM,cAAc,QAAQ;EAC5B,QAAQ,cAAc,UAAU;EAChC,WAAW,cAAc,8BAAa,IAAI,MAAM,EAAC,aAAa;EAC9D,OAAO,gBAAgB,cAAc,MAAM;EAC5C;AACD,QAAO;EACL,GAAG;EACH,WAAW,SAAS,aAAa;EACjC;EACD;;AAGH,SAAS,wBAAwB,SAAgE;AAC/F,QAAO;EACL,WAAW,QAAQ;EACnB,SAAS;GACP,GAAG,QAAQ;GACX,WAAW,QAAQ;GACpB;EACD,eAAe,QAAQ;EACxB;;AAGH,SAAS,YAAY,UAA0C;AAC7D,QAAO;EACL,WAAW,SAAS;EACpB,eAAe,SAAS;EACxB,oBAAoB;EACpB,OAAO,SAAS;EAChB,eAAe,SAAS;EACzB;;AAGH,SAAS,8BAA8B,UAAiC,WAAuC;AAC7G,QAAO,CAAC,GAAG,SAAS,CACjB,SAAS,CACT,MAAM,YACL,QAAQ,SAAS,eACjB,QAAQ,WAAW,YAClB,CAAC,aAAa,QAAQ,OAAO,WAAW,IAAI;;AAGnD,IAAaC,2BAAb,MAAoC;CAClC,WAAuC,EAAE;CACzC,UAAkB;CAElB,YACE,qBACA,eACA,wBACA,UACA,SACA,mBACA,mBACA,qBACA;AARiB,OAAA,sBAAA;AACA,OAAA,gBAAA;AACA,OAAA,yBAAA;AACA,OAAA,WAAA;AACA,OAAA,UAAA;AACA,OAAA,oBAAA;AACA,OAAA,oBAAA;AACA,OAAA,sBAAA;;CAGnB,cAAoB;AAClB,MAAI,KAAK,QACP;AAEF,OAAK,UAAU;AACf,OAAK,SAAS,KACZ,KAAK,QAAQ,WAAW,YAAY,SAAS,MAAM,KAAK,kBAAkB,EAC1E,KAAK,QAAQ,WAAW,YAAY,SAAS,OAAO,KAAK,mBAAmB,EAC5E,KAAK,QAAQ,WAAW,YAAY,SAAS,uBAAuB,KAAK,4BAA4B,CACtG;;CAGH,gBAAsB;AACpB,SAAO,KAAK,SAAS,SAAS,EAC5B,MAAK,SAAS,KAAK,IAAI;AAEzB,OAAK,UAAU;;CAGjB,oBAA4B,OAC1B,aAC0B;AAC1B,MAAI,CAAC,SAAS,QACZ,OAAM,IAAI,MAAM,kCAAkC;AAEpD,SAAO,YAAY,MAAM,KAAK,KAAK,kBAAkB,SAAS,QAAQ,CAAC,CAAC;;CAG1E,qBAA6B,OAC3B,aACkB;AAClB,MAAI,CAAC,SAAS,SAAS,UACrB,OAAM,IAAI,MAAM,mCAAmC;AAErD,QAAM,KAAK,MAAM,EAAE,WAAW,SAAS,QAAQ,WAAW,CAAC;;CAG7D,8BAAsC,OACpC,aAC0B;AAC1B,MAAI,CAAC,SAAS,QACZ,OAAM,IAAI,MAAM,6CAA6C;AAE/D,SAAO,YAAY,MAAM,KAAK,KAAK,wBAAwB,SAAS,QAAQ,CAAC,CAAC;;CAGhF,OAAe,OAAO,YAAwD;EAC5E,MAAM,UAAU,MAAM,KAAK,kBAAkB,mBAAmB;GAC9D,WAAW,QAAQ;GACnB,SAAS,QAAQ;GACjB,gBAAgB,QAAQ;GACxB,SAAS,QAAQ;GACjB,UAAU,QAAQ;GAClB,OAAO,QAAQ;GACf,aAAa,QAAQ;GACrB,MAAM,gBAAgB,QAAQ,QAAQ;GACtC,gBAAgB,QAAQ;GACzB,CAAC;EACF,MAAM,aACJ,KAAK,kBAAkB,cAAc,QAAQ,UAAU,IACvD,MAAM,KAAK,kBAAkB,iBAAiB,QAAQ,UAAU;EAClE,MAAM,UAAsB;GAC1B,GAAG,QAAQ;GACX,WAAW,QAAQ;GACpB;EACD,MAAM,kBAAmC;GACvC,GAAG;GACH,WAAW,QAAQ;GACnB;GACD;AACD,aAAW,MAAM,QAAQ,QAAQ;EACjC,MAAM,YAAY,WAAW,UAAU;EAEvC,MAAM,QAAQ,QAAQ,SAAS,QAAQ,SAAS,KAAK,cAAc,iBAAiB;EACpF,MAAM,UAAU,QAAQ,WAAW,QAAQ,WACzC,6BAA6B,KAAK,cAAc,YAAY,CAAC;EAC/D,MAAM,OAAqB;GACzB,OAAO,UAAU;GACjB;GACA;GACA,WAAW,QAAQ,aAAa,KAAK,cAAc,kBAAkB,MAAM;GAC3E,gBAAgB,QAAQ,kBAAkB,QAAQ,kBAAkB;GACpE,eAAe,QAAQ;GACxB;EAED,MAAM,UAAU,KAAK,oBAAoB,YAAY;GACnD,gBAAgB,QAAQ;GACxB;GACA;GACD,CAAC;EACF,MAAM,gBAAgB,MAAM,KAAK,uBAAuB,aAAa,gBAAgB;EACrF,MAAM,QAAQ,MAAM,KAAK,oBAAoB,WAAW,gBAAgB;EACxE,IAAI,uBAAuB;AAC3B,gBACE,KAAK,QAAQ,IAAI,MAAM;GACrB;GACA;GACA,QAAQ,UAAU;GAClB;GACD,CAAC,CAAC,CAAC,KACF,KAAK,UAAU;GACb,MAAM,kBAAsC,EAAE;AAC9C,OAAI,MAAM,SAAS,aAAa,iBAC9B,wBAAuB;AAEzB,OAAI,MAAM,SAAS,aAAa,eAAe,CAAC,sBAAsB;IACpE,MAAM,UAAU,8BACd,WAAW,aAAa,CAAC,UACzB,MAAM,QAAQ,UACf;AACD,QAAI,CAAC,QACH,OAAM,IAAI,MAAM,+DAA+D,QAAQ,UAAU,IAAI;AAEvG,oBAAgB,KAAK;KACnB,MAAM,aAAa;KACnB,SAAS;MACP,WAAW,MAAM,QAAQ,aAAa,QAAQ;MAC9C;MACA,eAAe,MAAM,QAAQ;MAC9B;KACF,CAAC;AACF,2BAAuB;;AAEzB,mBAAgB,KAAK,MAAM;AAC3B,QAAK,MAAM,kBAAkB,gBAC3B,MAAK,SAAS,KAAK,UAAU,UAAU,gBAAgB;IACrD,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,QAAQ;IACT,CAAC;IAEJ,EACF,WAAW,OAAO,UAAU;GAC1B,MAAM,QAA0B;IAC9B,MAAM,aAAa;IACnB,SAAS;KACP,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;KAC7D,OAAO,KAAK;KACZ,WAAW,QAAQ;KACnB,eAAe,KAAK;KACrB;IACF;AACD,SAAM,WAAW,YAAY,CAAC,MAAM,CAAC;AACrC,QAAK,SAAS,KAAK,UAAU,UAAU,OAAO;IAC5C,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,QAAQ;IACT,CAAC;IACF,CACH,EACD,EAAE,cAAc,KAAA,GAAW,CAC5B;AAED,SAAO;GACL,WAAW,QAAQ;GACnB,eAAe,QAAQ;GACvB,OAAO,KAAK;GACZ,eAAe,QAAQ;GACxB;;CAGH,QAAgB,OAAO,YAAiD;AACnD,OAAK,kBAAkB,cAAc,QAAQ,UAAU,EAC9D,SAAS,QAAQ,MAAM;;;;;AC5OvC,IAAaC,wBAAb,MAAiC;CAC/B,4BAA6B,IAAI,KAAuC;CACxE,0BAA2B,IAAI,KAAgC;CAC/D,iCAAkC,IAAI,KAA2B;CACjE,kCAAmC,IAAI,KAA2B;CAElE,YAAY,iBAAkE;EAC5E,MAAM,OAAO,KAAK,YAAY,aAAa,KAAK;AAChD,MAAI,KAAK,UAAU,IAAI,KAAK,CAC1B,OAAM,IAAI,MAAM,iDAAiD,OAAO;EAE1E,MAAM,yBAAyB;GAC7B,GAAG;GACH;GACD;AACD,OAAK,UAAU,IAAI,MAAM,uBAAuB;AAChD,SAAO,YAAY;AACjB,OAAI,KAAK,UAAU,IAAI,KAAK,KAAK,uBAC/B;AAEF,QAAK,UAAU,OAAO,KAAK;AAC3B,SAAM,KAAK,oBAAoB;;;CAInC,gBAAgB,YAAgD;AAC9D,OAAK,QAAQ,OAAO;AACpB,OAAK,MAAM,SAAS,QAClB,MAAK,QAAQ,IAAI,KAAK,YAAY,MAAM,GAAG,EAAE;GAC3C,GAAG;GACH,IAAI,KAAK,YAAY,MAAM,GAAG;GAC9B,MAAM,KAAK,YAAY,MAAM,KAAK;GACnC,CAAC;;CAIN,eAAe,WAAkD;EAC/D,MAAM,EAAE,gBAAgB,SAAS,eAAe;EAChD,MAAM,QAAQ,KAAK,SAAS,eAAe;EAC3C,MAAM,WAAW,KAAK,YAAY,MAAM,KAAK;EAC7C,MAAM,aAAa,KAAK,kBAAkB,OAAO,SAAS;EAC1D,MAAM,WAAW,eAAe,WAC5B,MAAM,KACN,GAAG,MAAM,GAAG,GAAG,QAAQ;EAC3B,MAAM,QAAQ,eAAe,WACzB,KAAK,iBACL,KAAK;EACT,MAAM,WAAW,MAAM,IAAI,SAAS;AACpC,MAAI,SACF,QAAO;EAET,MAAM,eAAe,SAAS,cAAc;GAC1C;GACA;GACA;GACD,CAAC;AACF,QAAM,IAAI,UAAU,aAAa;AACjC,SAAO;;CAGT,mBAAmB,OACjB,YAII;EACJ,MAAM,UAAU,CAAC,GAAG,KAAK,QAAQ,QAAQ,CAAC,CAAC,QAAQ,UAAU,MAAM,YAAY,MAAM;EACrF,MAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ,IAAI,OAAO,UAAU;GAC7D,MAAM,WAAW,KAAK,UAAU,IAAI,MAAM,KAAK;GAC/C,MAAM,aAAa,UAAU,8BACzB,MAAM,SAAS,4BAA4B;IAAE;IAAO,gBAAgB;IAAS,CAAC,GAC9E;AACJ,UAAO;IACL,OAAO,MAAM;IACb,OAAO,MAAM;IACb,MAAM,YAAY,QAAQ,MAAM,QAAQ;IACxC,OAAO,WAAW,YAAY,SAAS,OAAO;IAC9C,QAAQ,WAAW,YAAY,UAAU,OAAO;IAChD,eAAe,WACX,YAAY,iBAAiB,OAC7B,0CAA0C,MAAM,KAAK;IACzD,kBAAkB,YAAY,oBAAoB;IAClD,KAAK,YAAY,OAAO;IACxB,GAAI,YAAY,kBAAkB,EAAE,iBAAiB,WAAW,iBAAiB,GAAG,EAAE;IACvF;IACD,CAAC;AACH,SAAO;GACL,aAAa,KAAK,QAAQ,IAAA,SAAmC,GACzD,iCACA,QAAQ,IAAI,MAAA;GAChB;GACD;;CAGH,UAAU,YAA2B;AACnC,QAAM,KAAK,oBAAoB;AAC/B,OAAK,UAAU,OAAO;AACtB,OAAK,QAAQ,OAAO;;CAGtB,eAAuB,mBAAmC;EACxD,MAAM,eAAe,eAAe,MAAM;AAC1C,MAAI,CAAC,aACH,OAAM,IAAI,MAAM,gCAAgC;AAElD,SAAO;;CAGT,YAAoB,mBAA8C;EAChE,MAAM,eAAe,KAAK,YAAY,eAAe;EACrD,MAAM,QAAQ,KAAK,QAAQ,IAAI,aAAa;AAC5C,MAAI,CAAC,SAAS,MAAM,YAAY,MAC9B,OAAM,IAAI,MAAM,0CAA0C,eAAe;AAE3E,SAAO;;CAGT,eAAuB,SAA2C;EAChE,MAAM,WAAW,KAAK,UAAU,IAAI,KAAK,YAAY,KAAK,CAAC;AAC3D,MAAI,CAAC,SACH,OAAM,IAAI,MAAM,6CAA6C,OAAO;AAEtE,SAAO;;CAGT,qBACE,OACA,aAC2B;AAC3B,SAAO,MAAM,QAAQ,eAAe,aAAa,MAAM,QAAQ,eAAe,WAC1E,MAAM,OAAO,aACb,SAAS;;CAGf,qBAA6B,YAA2B;AACtD,OAAK,MAAM,WAAW,CAAC,GAAG,KAAK,eAAe,QAAQ,EAAE,GAAG,KAAK,gBAAgB,QAAQ,CAAC,CACvF,OAAM,QAAQ,WAAW;AAE3B,OAAK,eAAe,OAAO;AAC3B,OAAK,gBAAgB,OAAO;;;;;ACjMhC,IAAa,yBAAb,MAAoC;CAClC,4BAA6B,IAAI,KAAsB;CAEvD,YAAY,aAA4C;AACtD,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,eAAe,OAAO,YAA+D;EACnF,MAAM,SAAyB,EAAE;AACjC,OAAK,MAAM,YAAY,CAAC,GAAG,KAAK,UAAU,CACxC,QAAO,KAAK,GAAG,MAAM,SAAS,QAAQ,QAAQ,CAAC;AAEjD,SAAO;;CAGT,gBAAsB;AACpB,OAAK,UAAU,OAAO;;;;;ACD1B,IAAa,eAAb,MAA6B;CAC3B,WAAiC,EAAE;CAEnC,WAAW,YAAqB;AAC9B,OAAK,SAAS,KAAK,QAAQ;;CAG7B,cAAmB;AACjB,SAAO,KAAK,SAAS,OAAO,GAAG,KAAK,SAAS,OAAO;;CAGtD,gBAAyB,KAAK,SAAS,WAAW;;AAGpD,SAAS,yBAAyB,OAAkC;AAClE,QAAO,MAAM,SAAS,aAAa;;AAGrC,IAAa,aAAb,MAAwB;CACtB,QAAiB,IAAI,cAA0B;CAC/C;CACA,cAAqC;CACrC,sBAAsD;CAEtD,YACE,MACA,eAAkE,IAAI,yCAAyC,EAC/G;AADiB,OAAA,eAAA;AAEjB,OAAK,YAAY,KAAK;AACtB,OAAK,aAAa,QAAQ;GACxB,WAAW,KAAK;GAChB,UAAU,KAAK;GAChB,CAAC;;CAGJ,oBAAwC;EACtC,MAAM,WAAW,KAAK,aAAa,aAAa;AAChD,SAAO,EACL,UAAU,SAAS,mBAAmB,CAAC,GAAG,SAAS,UAAU,SAAS,iBAAiB,GAAG,SAAS,UACpG;;CAGH,cAAc,OAAO,WAAuD;AAC1E,OAAK,eAAe,OAAO;EAC3B,MAAM,qBAAqB,OAAO,OAAO,yBAAyB;AAClE,MAAI,mBAAmB,SAAS,EAC9B,OAAM,KAAK,aAAa,cAAc,mBAAmB;;CAI7D,iBAAsC;AACpC,MAAI,KAAK,YACP,OAAM,IAAI,MAAM,WAAW,KAAK,UAAU,6BAA6B;EAEzE,MAAM,QAAQ,aAAa,YAAY;EACvC,MAAM,aAAa,IAAI,iBAAiB;AACxC,OAAK,cAAc;AACnB,OAAK,sBAAsB;AAC3B,SAAO;GACL;GACA,QAAQ,WAAW;GACpB;;CAGH,YAAY,UAA4B;AACtC,MAAI,CAAC,KAAK,eAAe,CAAC,KAAK,oBAC7B,QAAO;AAET,MAAI,SAAS,KAAK,gBAAgB,MAChC,QAAO;AAET,OAAK,oBAAoB,OAAO;AAChC,SAAO;;CAGT,gBAAsB;AACpB,OAAK,qBAAqB,OAAO;AACjC,OAAK,sBAAsB;AAC3B,OAAK,cAAc;;CAGrB,kBAA0B,WAA8C;AACtE,OAAK,MAAM,SAAS,QAAQ;AAC1B,OAAI,MAAM,SAAS,aAAa,cAAc,MAAM,QAAQ,MAC1D,MAAK,cAAc,MAAM,QAAQ;AAEnC,OACE,MAAM,SAAS,aAAa,iBAC1B,MAAM,SAAS,aAAa,eAAe,MAAM,SAAS,aAAa,cACtE,CAAC,MAAM,QAAQ,SAAS,MAAM,QAAQ,UAAU,KAAK,cACxD;AACA,SAAK,cAAc;AACnB,SAAK,sBAAsB;;;;;AAMnC,IAAaC,sBAAb,MAA+B;CAC7B,uBAAwB,IAAI,KAAyB;CAErD,YAAY,mBAAuD;AAAtC,OAAA,oBAAA;;CAE7B,iBAAiB,cACf,KAAK,KAAK,IAAI,UAAU,IAAI;CAE9B,mBAAmB,OAAO,cAA2C;AACnE,MAAI,KAAK,KAAK,IAAI,UAAU,CAC1B,OAAM,IAAI,MAAM,+BAA+B,YAAY;EAO7D,MAAM,MAAM,IAAI,WAJH;GACX,UAFe,MAAM,KAAK,kBAAkB,oBAAoB,UAAU;GAG1E;GACD,CAC+B;AAChC,OAAK,KAAK,IAAI,WAAW,IAAI;AAC7B,SAAO;;CAGT,oBAAoB,cAA+B;EACjD,MAAM,MAAM,KAAK,KAAK,IAAI,UAAU;AACpC,MAAI,CAAC,IACH,QAAO;AAET,MAAI,SAAS;AACb,SAAO,KAAK,KAAK,OAAO,UAAU;;CAGpC,gBAAsB;AACpB,OAAK,MAAM,OAAO,KAAK,KAAK,QAAQ,CAClC,KAAI,SAAS;AAEf,OAAK,KAAK,OAAO;;;;;ACvJrB,IAAa,sBAAb,MAAiC;CAC/B,4BAA6B,IAAI,KAAmB;CAEpD,YAAY,aAAyC;AACnD,OAAK,UAAU,IAAI,SAAS;AAC5B,eAAa;AACX,QAAK,UAAU,OAAO,SAAS;;;CAInC,aAAa,OAAO,YAA0D;EAC5E,MAAM,QAAmB,EAAE;AAC3B,OAAK,MAAM,YAAY,CAAC,GAAG,KAAK,UAAU,CACxC,OAAM,KAAK,GAAG,MAAM,SAAS,QAAQ,QAAQ,CAAC;AAEhD,SAAO;;CAGT,gBAAsB;AACpB,OAAK,UAAU,OAAO;;;;;ACU1B,SAASC,aAAW,OAAoC;AAEtD,SADgB,OAAO,UAAU,WAAW,MAAM,MAAM,GAAG,OACzC,KAAA;;AAGpB,SAASC,qBAAmB,OAA6C;AACvE,QAAO,aAAa,SAAS,eAAe,MAAM,UAC9CD,aAAW,MAAM,QAAQ,UAAU,GACnC,KAAA;;AAGN,SAAS,sBAAsB,OAAkC;AAC/D,QAAO,MAAM,SAAS,aAAa;;AAGrC,SAAS,mBAAmB,UAAsE;AAChG,QAAOA,aAAW,UAAU,eAAe,IAAI;;AAGjD,SAAS,gBAAgB,UAAmE;AAC1F,QAAOA,aAAW,UAAU,aAAa,IAAIA,aAAW,UAAU,YAAY;;AAGhF,IAAa,oBAAb,MAA+B;CAC7B,WAAuC,EAAE;CACzC,UAAkB;CAElB,YACE,UACA,mBACA;AAFiB,OAAA,WAAA;AACA,OAAA,oBAAA;;CAGnB,cAAoB;AAClB,MAAI,KAAK,QACP;AAEF,OAAK,UAAU;AACf,OAAK,SAAS,KAAK,KAAK,SAAS,GAAG,UAAU,UAAU,OAAO,UAAU;GACvE,MAAM,YAAYC,qBAAmB,MAAM;AAC3C,OAAI,CAAC,aAAa,CAAC,sBAAsB,MAAM,CAC7C;AAEF,SAAM,KAAK,mBAAmB,WAAW,MAAM;IAC/C,CAAC;;CAGL,gBAAsB;AACpB,SAAO,KAAK,SAAS,SAAS,EAC5B,MAAK,SAAS,KAAK,IAAI;AAEzB,OAAK,UAAU;;CAGjB,aAAa,OAAO,cAAgD;EAClE,MAAM,SAAS,MAAM,KAAK,kBAAkB,iBAAiB,UAAU;AACvE,MAAI,CAAC,OACH,OAAM,IAAI,MAAM,sBAAsB,YAAY;EAEpD,MAAM,iBAAiBD,aAAW,OAAO,UAAU,eAAe,IAAA;EAElE,MAAM,QAAQA,aAAW,OAAO,UAAU,MAAM;AAChD,SAAO;GACL,WAAW,OAAO;GAClB,SAAS,OAAO;GAChB;GACA,UAAU,gBAAgB,OAAO,YAAY,EAAE,CAAC;GAChD;GACA,aAAa,gBAAgB,OAAO,SAAS;GAC7C,gBAAgB,mBAAmB,OAAO,SAAS;GACpD;;CAGH,gBAAgB,OAAO,WAAkE;EACvF,MAAM,EACJ,SACA,gBAAgB,yBAChB,SACA,UACA,OACA,aACA,WACA,MACA,mBACE;EACJ,MAAM,iBAAiB,2BAAA;EACvB,MAAM,UAAU,MAAM,KAAK,kBAAkB,cAAc;GACzD,uBAAuB,EAAE;GACzB;GACA,MAAM,QAAQ;GACd;GACA,mBAAmB;IACjB,GAAG,gBAAgB,YAAY,EAAE,CAAC;IAClC;IACA;IACD;GACD;GACA;GACA,SAAS;GACT,aAAa;GACb,eAAe,kBAAkB,KAAA;GAClC,CAAC;AACF,SAAO;GACL,WAAW,QAAQ;GACnB;GACA;GACA,UAAU,gBAAgB,QAAQ,YAAY,EAAE,CAAC;GACjD;GACA;GACA,gBAAgB,kBAAkB;GACnC;;CAGH,qBAAqB,OACnB,WAC6B;AAC7B,MAAI,CAAC,OAAO,UACV,QAAO,MAAM,KAAK,cAAc,OAAO;AAGzC,MADiB,MAAM,KAAK,kBAAkB,iBAAiB,OAAO,UAAU,CAE9E,QAAO,MAAM,KAAK,WAAW,OAAO,UAAU;AAEhD,SAAO,MAAM,KAAK,cAAc,OAAO;;CAGzC,sBAAsB,OAAO,cAAsD;AACjF,SAAO,MAAM,KAAK,kBAAkB,oBAAoB,UAAU;;CAGpE,uBAAuB,OACrB,WACA,UACkB;AAElB,MAAI,CADY,MAAM,KAAK,kBAAkB,sBAAsB,WAAW,MAAM,CAElF,OAAM,IAAI,MAAM,qCAAqC,YAAY;;CAIrE,qBAA6B,OAC3B,WACA,UACkB;AAClB,QAAM,KAAK,kBAAkB,mBAAmB;GAC9C;GACA;GACD,CAAC;;;;;AC7KN,IAAa,2BAAb,MAAsC;CACpC,WAAW,WACT,wCAAwC;EACtC,WAAW,OAAO;EAClB,iBAAiB,OAAO;EACzB,CAAC;;;;ACUN,IAAa,6BAAb,MAAwC;CACtC,oBAAqC,IAAI,mBAAmB;CAE5D,YAAY,eAA+C;AAA9B,OAAA,gBAAA;;CAE7B,QAAQ,OACN,WACmD;EACnD,MAAM,SAAS,KAAK,cAAc,YAAY;EAC9C,MAAM,iBAAiB,6BAA6B,OAAO;EAC3D,MAAM,UACJ,0BAA0B,QAAQ,OAAO,KAAK,QAAQ,IACtD,0BAA0B,QAAQ,eAAe;EACnD,MAAM,gBAAgB,SAAS,iBAAiB,OAAO,OAAO,SAAS;EACvE,MAAM,wBAAwB,2BAA2B,6BAA6B;GACpF;GACA,iCACE,SAAS,yBAAyB,OAAO,OAAO,SAAS;GAC5D,CAAC;EACF,MAAM,SAAS,KAAK,kBAAkB,MAAM;GAC1C,UAAU,OAAO,SAAS,KAAK,aAAa,EAAE,GAAG,SAAS,EAAE;GAC5D;GACA,oBAAoB;GACpB,qBAAqB;GACtB,CAAC;AAEF,SAAO;GACL,GAAG;GACH,UAAU,OAAO;GAClB;;;;;AClCL,IAAa,4BAAb,MAAyE;CACvE,YACE,kBACA,oBACA,aAAsD,MACtD;AAHiB,OAAA,mBAAA;AACA,OAAA,qBAAA;AACA,OAAA,aAAA;;CAGnB,QAAQ,OAAO,YAAkE;EAC/E,MAAM,iBAAiB,QAAQ,cAC5B,KAAK,UAAU,MAAM,MAAM,CAAC,CAC5B,OAAO,QAAQ,CACf,KAAK,OAAO;EACf,MAAM,kBAAuC,iBACzC,CAAC;GAAE,MAAM;GAAU,SAAS;GAAgB,CAAC,GAC7C,EAAE;EAKN,MAAM,uBAJoB,KAAK,iBAAiB,QAAQ;GACtD,WAAW,QAAQ;GACnB,UAAU,QAAQ;GACnB,CAAC,CAC6C,SAAS,YACtD,2BAA2B,SAAS,EAClC,YAAY,KAAK,YAClB,CAAC,CACH;EACD,MAAM,SAAS,MAAM,KAAK,mBAAmB,MAAM;GACjD,MAAM,QAAQ;GACd,UAAU,CAAC,GAAG,iBAAiB,GAAG,qBAAqB;GACxD,CAAC;EACF,MAAM,QAAQ,QAAQ,MAAM,KAAK,SAC/B,wBAAwB;GACtB,MAAM,KAAK;GACX,aAAa,KAAK;GAClB,YAAY,KAAK;GAClB,CAA6B,CAC/B;AAED,SAAO;GACL,UAAU,OAAO;GACjB,OAAO,MAAM,SAAS,IAAI,QAAQ,KAAA;GAClC,OAAO,QAAQ,KAAK;GACpB,eAAe,QAAQ,KAAK,kBAAkB;GAC9C,YAAY,QAAQ,KAAK;GAC1B;;;;;ACjCL,IAAa,yBAAb,MAA4D;CAC1D,eAAgC,IAAI,yCAAyC;CAC7E,UAA0C;CAC1C,eAAkD,EAAE;CAEpD,YAAY,QAAuD;AAAtC,OAAA,SAAA;;CAE7B,MAAM,iBAEJ,MACA,SACiC;EACjC,MAAM,EAAE,YAAY,UAAU;AAC9B,OAAK,eAAe,MAAM,IAAI,KAAK,aAAa;EAChD,MAAM,WAAW,WAAW,MAAM,OAAO;AACzC,OAAK,MAAM,SAAS,KAAK,oBAAoB,UAAU,MAAM,WAAW,UAAU,CAChF,OAAM,MAAM,KAAK,WAAW,YAAY,MAAM;EAEhD,MAAM,QAA+C;GACnD,WAAW,WAAW;GACtB,OAAO,KAAK;GACZ;GACA,eAAe,KAAK;GACpB,UAAU,KAAK,cAAc,KAAK;GACnC;AACD,aAAW,MAAM,SAAS,KAAK,YAAY,CAAC,IAAI,OAAO,EAAE,QAAQ,QAAQ,QAAQ,CAAC,CAChF,OAAM,MAAM,KAAK,WAAW,YAAY,MAAM;AAEhD,OAAK,eAAe,EAAE;;CAGxB,UAAU,YAA2B;AACnC,MAAI,KAAK,WAAW,aAAa,KAAK,WAAW,OAAO,KAAK,QAAQ,YAAY,WAC/E,OAAM,KAAK,QAAQ,SAAS;AAE9B,OAAK,UAAU;AACf,OAAK,eAAe,EAAE;;CAGxB,mBAA4C;AAC1C,MAAI,CAAC,KAAK,QACR,MAAK,UAAU,KAAK,OAAO,cAAc;GACvC,oBAAoB,KAAK;GACzB,cAAc,KAAK;GACpB,CAAC;AAEJ,SAAO,KAAK;;CAGd,uBACE,UACA,MACA,cAEA,SAAS,KAAK,aAAa;EACzB,MAAM,aAAa;EACnB,SAAS;GACP;GACA;GACA,eAAe,KAAK;GACrB;EACF,EAAE;CAEL,iBAAyB,UAAiD;EACxE,GAAG,KAAK,OAAO,QAAQ;EACvB,SAAS,KAAK;EACd,gBAAgB,KAAK,OAAO,QAAQ;EACpC,WAAW,KAAK;EAChB,OAAO,KAAK;EACZ,iBAAiB,KAAK;EACtB,gBAAgB,KAAK;EACtB;CAED,gBAAwB,SACtB,wBAAwB;EACtB,MAAM,KAAK;EACX,aAAa,KAAK;EAClB,YAAY,KAAK;EAClB,CAAC;CAEJ,aAAqB,OACnB,YACA,UAC8B;AAC9B,QAAM,WAAW,YAAY,CAAC,MAAM,CAAC;AACrC,SAAO;;;;;AC7GX,SAAS,gBAAgB,OAAsD;AAE7E,QADmB,OAAO,MAAM,IACX,KAAA;;AAGvB,SAAgB,6BAA6B,QAGjB;CAC1B,MAAM,EAAE,SAAS,YAAY;CAC7B,MAAM,UAAU,gBAAgB,QAAQ,WAAW,SAAS,QAAQ;CACpE,MAAM,cAAc,gBAAgB,QAAQ,eAAe,SAAS,YAAY;CAChF,MAAM,UAAU,gBAAgB,QAAQ,QAAQ;CAChD,MAAM,QAAQ,gBAAgB,QAAQ,SAAS,SAAS,MAAM;AAE9D,QAAO;EACL,GAAG,gBAAgB,SAAS,YAAY,EAAE,CAAC;EAC3C;EACA;EACA,cAAc;EACd;EACA;EACA,gBAAgB,QAAQ,kBAAkB,SAAS;EACpD;;;;ACEH,MAAM,uBAAuB;AAC7B,MAAa,yBAAyB;AACtC,MAAa,0BAA0B;AACvC,MAAM,4BAA4B,IAAI,iBAAiB,yBAAyB;AAIhF,SAAS,WAAW,OAAqD;AACvE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D;AAEF,QAAO;;AAGT,SAASE,aAAW,OAAoC;AACtD,KAAI,OAAO,UAAU,SACnB;AAGF,QADgB,MAAM,MAAM,IACV,KAAA;;AAGpB,SAAS,iBACP,OAC+B;AAC/B,QAAO,MAAM,QAAQ;;AAGvB,SAAS,sBAAsB,QAKR;CACrB,MAAM,EAAE,iBAAiB,cAAc,OAAO,oBAAoB;CAClE,MAAM,cAAc,WAAW,MAAM,SAAS;AAC9C,QACEA,aAAW,aAAa,gBAAgB,IACxCA,aAAW,aAAa,eAAe,IACvCA,aAAW,aAAa,MAAM,IAC9BA,aAAW,gBAAgB,gBAAgB,IAC3CA,aAAW,gBAAgB,eAAe,IAC1CA,aAAW,gBAAgB,MAAM,IACjC,mBACA;;AAIJ,SAAS,uBACP,YAC+D;CAC/D,MAAM,UAAU,WAAW,UAAU,SAAS,MAAM,CAAC,aAAa;AAClE,KAAI,YAAY,YACd,QAAO;AAET,KAAI,YAAY,OACd,QAAO;CAET,MAAM,eAAe,WAAW,cAAc,MAAM,CAAC,aAAa;CAClE,MAAM,UAAU,WAAW,SAAS,MAAM,CAAC,aAAa,IAAI;AAC5D,KAAI,iBAAiB,eAAe,QAAQ,SAAS,gBAAgB,CACnE,QAAO;AAET,QAAO;;AAGT,SAAS,mBAAmB,QAMY;CACtC,MAAM,QAAQ,sBAAsB,OAAO;AAC3C,KAAI,CAAC,MACH;CAEF,MAAM,aAAa,uBAAuB,OAAO,QAAQ,MAAM;AAC/D,KAAI,CAAC,WAAW,SACd;CAEF,MAAM,UACJ,WAAW,YACV,WAAW,eACR,0BAA0B,mBAAmB,WAAW,aAAa,EAAE,kBAAkB,OACzF;AACN,QAAO;EACL,OAAO,WAAW;EAClB,QAAQ,WAAW;EACnB;EACA,SAAS;GACP,GAAI,WAAW,SAAS,gBAAgB,EAAE;IACzC,uBAAuB,uBAAuB,WAAW;GAC3D;EACF;;AAGH,IAAM,uCAAN,MAA2C;CACzC,wCAAyC,IAAI,KAG1C;CAEH,YAAY,OAA2C,cAAwC;AAAlE,OAAA,QAAA;AAA2C,OAAA,eAAA;;CAExE,WAAW,OACT,mBACmC;EACnC,MAAM,eACJ,gBAAgB,iBAAiB,UAAU,UAAU;EACvD,MAAM,UAAU,KAAK,sBAAsB,IAAI,aAAa;AAC5D,MAAI,QACF,QAAO,MAAM;EAEf,MAAM,eAAe,KAAK,kBAAkB;AAC5C,OAAK,sBAAsB,IAAI,cAAc,aAAa;AAC1D,MAAI;AACF,UAAO,MAAM;YACL;AACR,QAAK,sBAAsB,OAAO,aAAa;;;CAInD,mBAA2B,YAA4C;EAErE,MAAM,SADW,IAAI,0BAA0B,KAAK,MAAM,UAAU,EAAE,CAAC,CAC/C,QAAQ,EAC9B,cAAc,KAAK,cACpB,CAAC;AAEF,MAAI,CAAC,OAAO,QACV,QAAO;GACL,MAAM,iBAAiB,KAAK,MAAM;GAClC,OAAO;GACP,QAAQ;GACR,eAAe;GACf,kBAAkB,OAAO,oBAAoB;GAC7C,KAAK;IACH,MAAM;IACN,OAAO;IACR;GACF;AAIH,MAAI,GADiB,OAAO,mBAAmB,SAAS,QAAQ,OAAO,eAAe,EAEpF,QAAO;GACL,MAAM,iBAAiB,KAAK,MAAM;GAClC,OAAO;GACP,QAAQ;GACR,eAAe;GACf,kBAAkB,OAAO,oBAAoB;GAC7C,GAAI,OAAO,kBAAkB,EAAE,iBAAiB,OAAO,iBAAiB,GAAG,EAAE;GAC7E,KAAK;GACN;EAGH,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,OAAO,wBAAwB;EACjD,MAAM,UAAU,iBAAiB,WAAW,OAAO,EAAE,UAAU;AAC/D,MAAI;GACF,MAAM,WAAW,MAAM,MAAM,OAAO,kBAAkB,IAAI;IACxD,QAAQ;IACR,SAAS,OAAO;IAChB,QAAQ,WAAW;IACpB,CAAC;AACF,OAAI,CAAC,SAAS,GACZ,QAAO;IACL,MAAM,iBAAiB,KAAK,MAAM;IAClC,OAAO;IACP,QAAQ;IACR,eAAe,0CAA0C,SAAS,OAAO;IACzE,kBAAkB,OAAO,oBAAoB;IAC7C,GAAI,OAAO,kBAAkB,EAAE,iBAAiB,OAAO,iBAAiB,GAAG,EAAE;IAC7E,KAAK;IACN;AAEH,UAAO;IACL,MAAM,iBAAiB,KAAK,MAAM;IAClC,OAAO;IACP,QAAQ;IACR,eAAe;IACf,kBAAkB,OAAO,oBAAoB;IAC7C,GAAI,OAAO,kBAAkB,EAAE,iBAAiB,OAAO,iBAAiB,GAAG,EAAE;IAC7E,KAAK;IACN;WACM,OAAO;AACd,UAAO;IACL,MAAM,iBAAiB,KAAK,MAAM;IAClC,OAAO;IACP,QAAQ;IACR,eACE,iBAAiB,QACb,MAAM,UACN;IACN,kBAAkB,OAAO,oBAAoB;IAC7C,GAAI,OAAO,kBAAkB,EAAE,iBAAiB,OAAO,iBAAiB,GAAG,EAAE;IAC7E,KAAK;IACN;YACO;AACR,gBAAa,QAAQ;;;;AAK3B,IAAM,wCAAN,MAA4C;CAC1C,wCAAyC,IAAI,KAG1C;CAEH,YAAY,OAA2C;AAA1B,OAAA,QAAA;;CAE7B,WAAW,OACT,mBACmC;EACnC,MAAM,eACJ,gBAAgB,iBAAiB,UAAU,UAAU;EACvD,MAAM,UAAU,KAAK,sBAAsB,IAAI,aAAa;AAC5D,MAAI,QACF,QAAO,MAAM;EAEf,MAAM,eAAe,KAAK,iBAAiB,aAAa;AACxD,OAAK,sBAAsB,IAAI,cAAc,aAAa;AAC1D,MAAI;AACF,UAAO,MAAM;YACL;AACR,QAAK,sBAAsB,OAAO,aAAa;;;CAInD,mBAA2B,OACzB,iBACmC;EACnC,MAAM,WAAW,IAAI,2BAA2B,KAAK,MAAM,UAAU,EAAE,CAAC;AACxE,MAAI;GACF,MAAM,SAAS,SAAS,SAAS;AAEjC,OAAI,CADmB,MAAM,sBAAsB,OAAO,QAAQ,CAEhE,QAAO;IACL,MAAM,iBAAiB,KAAK,MAAM;IAClC,OAAO;IACP,QAAQ;IACR,eAAe,6BAA6B,OAAO,QAAQ;IAC3D,KAAK;KACH,MAAM;KACN,OAAO;KACR;IACF;AAEH,OAAI,iBAAiB,QACnB,KAAI;AACF,UAAM,kBAAkB,OAAO;YACxB,OAAO;AACd,WAAO;KACL,MAAM,iBAAiB,KAAK,MAAM;KAClC,OAAO;KACP,QAAQ;KACR,eACE,iBAAiB,QACb,MAAM,UACN;KACN,KAAK;MACH,MAAM;MACN,OAAO;MACR;KACF;;AAGL,UAAO;IACL,MAAM,iBAAiB,KAAK,MAAM;IAClC,OAAO;IACP,QAAQ;IACR,eAAe;IACf,KAAK;IACN;WACM,OAAO;AACd,UAAO;IACL,MAAM,iBAAiB,KAAK,MAAM;IAClC,OAAO;IACP,QAAQ;IACR,eACE,iBAAiB,QACb,MAAM,UACN;IACN,KAAK;KACH,MAAM;KACN,OAAO;KACR;IACF;;;;AAKP,eAAe,sBAAsB,SAAyC;AAC5E,KAAI,QAAQ,SAAS,IAAI,IAAI,QAAQ,SAAS,KAAK,CACjD,QAAQ,MAAM,aAAa,QAAQ,GAAI,UAAU;CAEnD,MAAM,aAAa,QAAQ,IAAI,QAAQ;AACvC,MAAK,MAAM,aAAa,WAAW,MAAM,UAAU,EAAE;EACnD,MAAM,UAAU,UAAU,MAAM;AAChC,MAAI,CAAC,QACH;EAEF,MAAM,YAAY,GAAG,QAAQ,GAAG;AAChC,MAAI,MAAM,aAAa,UAAU,CAC/B,QAAO;;AAGX,QAAO;;AAGT,eAAe,aAAa,UAAoC;AAC9D,KAAI;AACF,QAAM,OAAO,UAAUC,UAAY,KAAK;AACxC,SAAO;SACD;AACN,SAAO;;;AAIX,IAAa,oCAAb,MAA+C;CAC7C,YACE,eACA;AADiB,OAAA,gBAAA;;CAGnB,wBAA4D;AAC1D,SAAO,CACL;GACE,MAAM;GACN,OAAO;GACP,eAAe,KAAK;GACpB,wBAAwB,EAAE,OAAO,oBAC/B,KAAK,kBAAkB,OAAO,cAAc;GAC9C,8BAA8B,EAAE,OAAO,qBACrC,IAAI,qCACF,OACA,KAAK,cAAc,YAAY,CAAC,OAAO,SAAS,MACjD,CAAC,SAAS,eAAe;GAC7B,EACD;GACE,MAAM;GACN,OAAO;GACP,eAAe,KAAK;GACpB,wBAAwB,EAAE,OAAO,oBAC/B,KAAK,mBAAmB,OAAO,cAAc;GAC/C,8BAA8B,EAAE,OAAO,qBACrC,IAAI,sCAAsC,MAAM,CAAC,SAAS,eAAe;GAC5E,CACF;;CAGH,iCAAgD;AAC9C,QAAM,IAAI,MAAM,gEAAgE;;CAGlF,qBACE,OACA,kBAC+B;EAC/B,MAAM,SAAS,WAAW,MAAM,OAAO,IAAI,EAAE;EAC7C,MAAM,WAAW,IAAI,0BAA0B,OAAO;EACtD,MAAM,iBAAiB,SAAS,QAAQ,EACtC,cAAc,KAAK,cAAc,YAAY,CAAC,OAAO,SAAS,OAC/D,CAAC;AACF,SAAO,IAAI,2BAA2B;GACpC,SAAS,SAAS,gBAAgB;GAClC,GAAI,eAAe,WAAW,EAAE,UAAU,eAAe,UAAU,GAAG,EAAE;GACxE,GAAI,eAAe,aAAa,EAAE,YAAY,eAAe,YAAY,GAAG,EAAE;GAC9E,GAAI,eAAe,UAAU,EAAE,SAAS,eAAe,SAAS,GAAG,EAAE;GACrE,cAAc,cAAc;GAC5B,cAAc,cAAc;GAC5B,uBAAuB,UACrB,mBAAmB;IACjB,QAAQ,KAAK,cAAc,YAAY;IACvC;IACA,iBAAiB,cAAc;IAC/B,cAAc,KAAK,cAAc,YAAY,CAAC,OAAO,SAAS;IAC9D,iBAAiBD,aAAW,OAAO,MAAM;IAC1C,CAAC;GACL,CAAC;;CAGJ,sBACE,OACA,kBACgC;EAChC,MAAM,SAAS,WAAW,MAAM,OAAO,IAAI,EAAE;AAG7C,SAAO,IAAI,4BAA4B;GACrC,GAHe,IAAI,2BAA2B,OAAO,CACvB,SAAS;GAGvC,WAAW,cAAc;GACzB,cAAc,cAAc;GAC5B,cAAc,cAAc;GAC5B,uBAAuB,UACrB,mBAAmB;IACjB,QAAQ,KAAK,cAAc,YAAY;IACvC;IACA,iBAAiB,cAAc;IAC/B,cAAc,KAAK,cAAc,YAAY,CAAC,OAAO,SAAS;IAC9D,iBAAiBA,aAAW,OAAO,MAAM;IAC1C,CAAC;GACL,CAAC;;;;;ACzZN,IAAa,8BAAb,MAAuE;CACrE,WAAwD,EAAE;CAC1D;CAEA,YACE,QACA,QACA;AAFiB,OAAA,SAAA;AACA,OAAA,SAAA;AAEjB,OAAK,oBAAoB,IAAI,0BAC3B,IAAI,0BAA0B,EAC9B,IAAI,2BAA2B,OAAO,cAAc,EACpD,OAAO,WACR;;CAGH,cAAoB;AAClB,MAAI,KAAK,SAAS,SAAS,EACzB;EAEF,MAAM,EAAE,YAAY,2BAA2B,EAC7C,QAAQ,KAAK,OAAO,cAAc,YAAY,EAC/C,CAAC;AACF,OAAK,OAAO,oBAAoB,aAAa,QAAQ;AACrD,OAAK,SAAS,KAAK,KAAK,uBAAuB,CAAC;AAChD,OAAK,MAAM,YAAY,IAAI,kCACzB,KAAK,OAAO,cACb,CAAC,iBAAiB,CACjB,MAAK,SAAS,KAAK,KAAK,oBAAoB,SAAS,CAAC;;CAI1D,UAAU,YAA2B;AACnC,SAAO,KAAK,SAAS,SAAS,EAC5B,OAAM,KAAK,SAAS,KAAK,IAAI;;CAIjC,8BACE,KAAK,OAAO,oBAAoB,SAAS;EACvC,MAAM;EACN,OAAO;EACP,mBAAmB;EACnB,qBACE,IAAIE,yBAAuB;GACzB,QAAQ,IAAI,yBAAyB,KAAK,OAAO,aAAa;GAC9D,mBAAmB,KAAK;GACxB,cAAc,OAAO,EAAE,MAAM,iBAAiB;IAC5C,MAAM,UAAU,MAAM,KAAK,OAAO,kBAAkB,WAAW,WAAW,UAAU;AACpF,WAAO,MAAM,KAAK,OAAO,yBAAyB,aAAa;KAC7D,SAAS,KAAK;KACd,UAAU,WAAW,aAAa,CAAC;KACnC,UAAU,QAAQ;KAClB,WAAW,WAAW;KACvB,CAAC;;GAEL,CAAC;EACL,CAAC;CAEJ,uBACE,aAEA,KAAK,OAAO,oBAAoB,SAAS;EACvC,MAAM,SAAS;EACf,OAAO,SAAS;EAChB,mBAAmB,SAAS,SAAA,eAAmC,YAAY;EAC3E,6BAA6B,SAAS;EACtC,gBAAgB,EAAE,OAAO,cAAc;AACrC,OAAI,CAAC,SAAS,sBACZ,OAAM,IAAI,MAAM,oDAAoD,SAAS,OAAO;AAEtF,UAAO,IAAI,uBAAuB;IAChC;IACA,gBAAgB,EAAE,cAAc,mBAC9B,SAAS,sBAAuB;KAC9B;KACA,eAAe;MACb,WAAW,QAAQ;MACnB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;MACvD,0BAA0B,aACxB,KAAK,OAAO,WAAW,mBAAmB,SAAS;MACrD;MACA,iBAAiB,QAAQ;MACzB;MACD;KACF,CAAC;IACL,CAAC;;EAEL,CAAC;;;;ACxFN,MAAMC,4BAA0B;AAEhC,SAASC,wBAAsB,OAAwB;AACrD,KAAI,iBAAiB,MACnB,QAAO,MAAM,SAAS,MAAM;AAE9B,QAAO,OAAO,MAAM;;AAGtB,IAAa,4BAAb,MAAqE;CACnE;CACA,kDAAmD,IAAI,KAAqB;CAC5E,gCAAiC,IAAI,KAA4C;CACjF,UAAkB;CAClB,sBAAkD;CAElD,YACE,QACA,QACA;AAFiB,OAAA,SAAA;AACA,OAAA,SAAA;AAEjB,OAAK,uBAAuB,IAAI,kCAAkC,EAChE,eAAe,OAAO,eACvB,CAAC;;CAGJ,cAAoB;AAClB,MAAI,KAAK,oBACP;AAEF,OAAK,UAAU;AACf,OAAK,sBAAsB,KAAK,OAAO,SAAS,GAAG,UAAU,UAAU,KAAK,eAAe;;CAG7F,gBAAsB;AACpB,OAAK,uBAAuB;AAC5B,OAAK,sBAAsB;AAC3B,OAAK,UAAU;AACf,OAAK,MAAM,SAAS,KAAK,cAAc,QAAQ,CAC7C,cAAa,MAAM;AAErB,OAAK,cAAc,OAAO;AAC1B,OAAK,gCAAgC,OAAO;;CAG9C,kBAA0B,UAAkC;EAC1D,MAAM,YAAY,gCAAgC,MAAM;AACxD,MAAI,CAAC,aAAa,CAAC,KAAK,OAAO,kBAAkB,cAAc,UAAU,CACvE;AAEF,MAAI,MAAM,SAAS,aAAa,sBAAsB;AACpD,QAAK,+BAA+B,WAAW,MAAM,QAAQ,cAAc;AAC3E;;AAEF,MAAI,sCAAsC,MAAM,EAAE;AAChD,QAAK,WAAW,UAAU;AAC1B;;AAEF,MAAI,uCAAuC,MAAM,CAC/C,MAAK,YAAY,UAAU;;CAI/B,eAAuB,cAA4B;AACjD,MAAI,KAAK,cAAc,IAAI,UAAU,CACnC;EAEF,MAAM,QAAQ,iBAAiB;AAC7B,QAAK,cAAc,OAAO,UAAU;AACpC,QAAK,WAAW,UAAU;KACzBD,0BAAwB;AAC3B,OAAK,cAAc,IAAI,WAAW,MAAM;;CAG1C,cAAsB,cAA4B;EAChD,MAAM,QAAQ,KAAK,cAAc,IAAI,UAAU;AAC/C,MAAI,OAAO;AACT,gBAAa,MAAM;AACnB,QAAK,cAAc,OAAO,UAAU;;AAEjC,OAAK,qBAAqB,UAAU,CAAC,OAAO,UAAmB;AAClE,WAAQ,MAAM,oDAAoD,UAAU,IAAIC,wBAAsB,MAAM,GAAG;IAC/G;;CAGJ,uBAA+B,OAAO,cAAqC;AACzE,MAAI,KAAK,QACP;EAEF,MAAM,aAAa,KAAK,OAAO,kBAAkB,cAAc,UAAU;AACzE,MAAI,CAAC,WACH;EAEF,MAAM,UAAU,MAAM,KAAK,OAAO,kBAAkB,WAAW,UAAU;EACzE,MAAM,gBAAgB,KAAK,qBAAqB,QAAQ;GACtD,iBAAiB,QAAQ;GACzB;GACA,iBAAiB,WAAW,aAAa,CAAC;GAC1C,eAAe,QAAQ;GACvB,gBAAgB,QAAQ;GACzB,CAAC;AACF,MAAI,CAAC,wBAAwB,cAAc,IAAI,KAAK,QAClD;EAEF,MAAM,YAAY,6BAA6B,cAAc;AAC7D,MAAI,KAAK,gCAAgC,IAAI,UAAU,KAAK,UAC1D;AAEF,OAAK,gCAAgC,IAAI,WAAW,UAAU;AAC9D,OAAK,OAAO,SAAS,KAAK,UAAU,UAAU;GAC5C,MAAM,aAAa;GACnB,SAAS;IACP;IACA;IACD;GACF,EAAE;GACD,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,QAAQ;GACT,CAAC;;CAGJ,kCACE,WACA,kBACS;AACT,OAAK,gCAAgC,IAAI,WAAW,6BAA6B,cAAc,CAAC;;;;;AC7HpG,IAAa,wBAAb,MAA8D;CAC5D,YACE,QACA,QACA;AAFiB,OAAA,SAAA;AACA,OAAA,SAAA;;CAGnB,UAAU,OAAO,YAA+D;EAC9E,MAAM,UAAU,QAAQ,YACpB,MAAM,KAAK,OAAO,kBAAkB,WAAW,QAAQ,UAAU,GACjE;EACJ,MAAM,YAAY,SAAS,aAAa,QAAQ,aAAa,QAAQ,QAAQ,aAAa;EAC1F,MAAM,kBAAkB,6BAA6B;GAAE;GAAS;GAAS,CAAC;EAC1E,MAAM,aAAa,6BAA6B;GAC9C,eAAe,KAAK,OAAO;GAC3B;GACA;GACA,iBAAiB,SAAS,YAAY;GACtC,eAAe,QAAQ,WAAW,SAAS;GAC5C,CAAC;EACF,MAAM,eAAe,KAAK,OAAO,YAAY,sBAAsB,EACjE,sBAAsB,YAAY,KAAA,GACnC,CAAC;AACF,eAAa,cAAc,WAAW,eAAe;AAErD,SAAO,CACL,KAAK,wBAAwB;GAC3B,gBAAgB,wBAAwB,aAAa,oBAAoB,CAAC;GAC1E;GACD,CAAC,CACH;;CAGH,2BAAmC,WAGf;EAClB,MAAM,EAAE,gBAAgB,eAAe;EAmBvC,MAAM,QAAQ;GAlBS,IAAI,eACzB,WAAW,oBACX,WAAW,OAAO,OAAO,SACzB;IACE,eAAe,WAAW,QAAQ;IAClC,oBAAoB,uBAAuB,WAAW,gBAAgB;IACvE,CACF,CACmC,kBAClC,KAAA,GACA,WAAW,YACX,gBACA,CACE,kCAAkC,EAClC,kCAAkC,WAAW,eAAe,CAC7D,CACF;GAIC;GACA,YAAY,WAAW;GACvB,YAAY,WAAW;GACvB,YAAY,WAAW;GACxB;AACD,MAAI,WAAW,gBACb,OAAM,KAAK,oBAAoB,WAAW,kBAAkB;AAE9D,SAAO,MAAM,KAAK,KAAK;;;;;AC/E3B,IAAa,8BAAb,MAAuE;CACrE,aAA0C;CAE1C,YACE,QACA,QACA;AAFiB,OAAA,SAAA;AACA,OAAA,SAAA;;CAGnB,cAAoB;AAClB,MAAI,KAAK,WACP;AAEF,OAAK,aAAa,KAAK,OAAO,uBAAuB,SACnD,IAAI,sBAAsB,KAAK,QAAQ,KAAK,OAAO,CACpD;;CAGH,gBAAsB;AACpB,OAAK,cAAc;AACnB,OAAK,aAAa;;;;;ACRtB,IAAa,qBAAb,MAAwD;CACtD,YACE,QACA,QACA;AAFiB,OAAA,SAAA;AACA,OAAA,SAAA;;CAGnB,UAAU,OAAO,YAA0D;EACzE,MAAM,UAAU,QAAQ,YACpB,MAAM,KAAK,OAAO,kBAAkB,WAAW,QAAQ,UAAU,GACjE;EACJ,MAAM,YAAY,SAAS,aAAa,QAAQ,aAAa,QAAQ,QAAQ,aAAa;EAC1F,MAAM,kBAAkB,6BAA6B;GAAE;GAAS;GAAS,CAAC;EAC1E,MAAM,aAAa,6BAA6B;GAC9C,eAAe,KAAK,OAAO;GAC3B;GACA;GACA,iBAAiB,SAAS,YAAY;GACtC,eAAe,QAAQ,WAAW,SAAS;GAC5C,CAAC;EACF,MAAM,eAAe,KAAK,OAAO,YAAY,sBAAsB,EACjE,sBAAsB,OAAO,EAAE,QAAQ,WAAW,iBAAiB,iBAAiB;AAClF,QAAK,OAAO,SAAS,KAAK,UAAU,UAAU;IAC5C,MAAM,aAAa;IACnB,SAAS;KACP,WAAW;KACX;KACA,SAAS;KACV;IACF,EAAE;IACD,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,QAAQ;IACT,CAAC;KAEL,CAAC;AACF,eAAa,cAAc,WAAW,eAAe;AACrD,SAAO,aAAa,WAAW;;;;;AC9CnC,IAAa,2BAAb,MAAoE;CAClE,aAA0C;CAE1C,YACE,QACA,QACA;AAFiB,OAAA,SAAA;AACA,OAAA,SAAA;;CAGnB,cAAoB;AAClB,MAAI,KAAK,WACP;AAEF,OAAK,aAAa,KAAK,OAAO,oBAAoB,SAChD,IAAI,mBAAmB,KAAK,QAAQ,KAAK,OAAO,CACjD;;CAGH,gBAAsB;AACpB,OAAK,cAAc;AACnB,OAAK,aAAa;;;;;ACPtB,IAAa,eAAb,MAAwD;CACtD,sBAA+B,IAAIC,uBAAqB;CACxD;CACA,yBAAkC,IAAI,wBAAwB;CAC9D;CACA;CACA,sBAA+B,IAAI,qBAAqB;CACxD;CACA;CACA,UAAkB;CAElB,YAAY,QAAyC;AAAxB,OAAA,SAAA;AAC3B,OAAK,oBAAoB,IAAI,kBAC3B,OAAO,UACP,OAAO,kBACR;AACD,OAAK,2BAA2B,IAAI,iCAClC,OAAO,eACP,OAAO,cACP,KAAK,kBACN;AACD,OAAK,oBAAoB,IAAIC,oBAAkB,KAAK,kBAAkB;AACtE,OAAK,yBAAyB,IAAIC,yBAChC,KAAK,qBACL,OAAO,eACP,KAAK,wBACL,OAAO,UACP,OAAO,SACP,KAAK,mBACL,KAAK,mBACL,KAAK,oBACN;AACD,OAAK,gBAAgB;GACnB,IAAI,yBAAyB,QAAQ,KAAK;GAC1C,IAAI,4BAA4B,QAAQ,KAAK;GAC7C,IAAI,0BAA0B,QAAQ,KAAK;GAC3C,IAAI,4BAA4B,QAAQ,KAAK;GAC9C;;CAGH,cAAoB;AAClB,MAAI,KAAK,QACP;AAEF,OAAK,UAAU;AACf,OAAK,kBAAkB,OAAO;AAC9B,OAAK,MAAM,gBAAgB,KAAK,cAC9B,cAAa,OAAO;AAEtB,OAAK,uBAAuB,OAAO;;CAGrC,oBAAoB,WAClB,KAAK,oBAAoB,iBAAiB,OAAO;CAEnD,UAAU,YAA2B;AACnC,MAAI,CAAC,KAAK,QACR;AAEF,OAAK,MAAM,gBAAgB,CAAC,GAAG,KAAK,cAAc,CAAC,SAAS,CAC1D,OAAM,aAAa,WAAW;AAEhC,OAAK,uBAAuB,SAAS;AACrC,OAAK,oBAAoB,SAAS;AAClC,OAAK,uBAAuB,SAAS;AACrC,QAAM,KAAK,oBAAoB,SAAS;AACxC,OAAK,kBAAkB,SAAS;AAChC,OAAK,kBAAkB,SAAS;AAChC,OAAK,UAAU;;;;;AChFnB,IAAa,2BAAb,MAAoE;CAClE,WAAsC,EAAE;CAExC,YAAY,QAAyC;AAAxB,OAAA,SAAA;;CAE7B,cAAoB;AAClB,MAAI,KAAK,SAAS,SAAS,EACzB;EAEF,MAAM,uBAAuB,IAAI,0BAA0B;GACzD,iBAAiB,KAAK,OAAO;GAC7B,eAAe,KAAK,OAAO;GAC3B,UAAU,KAAK,OAAO;GACtB,YAAY,KAAK,OAAO;GACxB,sBAAsB,KAAK,OAAO,kBAAkB;GACpD,aAAa,KAAK,OAAO;GAC1B,CAAC;EACF,MAAM,8BAA8B,IAAI,kCACtC,KAAK,OAAO,cACb,CAAC,iBAAiB;EACnB,MAAM,qBAAqB,KAAK,OAAO,oBAAoB,wBAAwB;GACjF,MAAM;GACN,OAAO;GACP,eAAe,qBAAqB;GACrC,CAAC;AACF,OAAK,WAAW,OACR,mBAAmB,SAAS,EAClC,GAAG,4BAA4B,KAAK,aAAa;GAC/C,MAAM,eAAe,KAAK,OAAO,oBAAoB,wBAAwB,SAAS;AACtF,gBAAa,aAAa,SAAS;IACnC,CACH;;CAGH,gBAAsB;AACpB,OAAK,MAAM,WAAW,KAAK,SACzB,UAAS;AAEX,OAAK,WAAW,EAAE;;;;;AC/BtB,MAAM,0BAA0B;AAEhC,SAAS,sBAAsB,OAAwB;AACrD,KAAI,iBAAiB,MACnB,QAAO,MAAM,SAAS,MAAM;AAE9B,QAAO,OAAO,MAAM;;AAGtB,IAAa,mCAAb,MAA4E;CAC1E,sBAAkD;CAClD,UAAkB;CAClB,gCAAiC,IAAI,KAA4C;CACjF,kDAAmD,IAAI,KAAqB;CAE5E,YAAY,QAAyC;AAAxB,OAAA,SAAA;;CAE7B,cAAoB;AAClB,MAAI,KAAK,oBACP;AAEF,OAAK,UAAU;AACf,OAAK,sBAAsB,KAAK,OAAO,SAAS,GAAG,UAAU,UAAU,KAAK,eAAe;;CAG7F,gBAAsB;AACpB,OAAK,uBAAuB;AAC5B,OAAK,sBAAsB;AAC3B,OAAK,UAAU;AACf,OAAK,MAAM,SAAS,KAAK,cAAc,QAAQ,CAC7C,cAAa,MAAM;AAErB,OAAK,cAAc,OAAO;AAC1B,OAAK,gCAAgC,OAAO;;CAG9C,kBAA0B,UAAkC;EAC1D,MAAM,YAAY,gCAAgC,MAAM;AACxD,MAAI,CAAC,UACH;AAEF,MAAI,MAAM,SAAS,aAAa,sBAAsB;AACpD,QAAK,+BAA+B,WAAW,MAAM,QAAQ,cAAc;AAC3E;;AAEF,MAAI,sCAAsC,MAAM,EAAE;AAChD,QAAK,WAAW,UAAU;AAC1B;;AAEF,MAAI,uCAAuC,MAAM,CAC/C,MAAK,YAAY,UAAU;;CAI/B,eAAuB,cAA4B;AACjD,MAAI,KAAK,cAAc,IAAI,UAAU,CACnC;EAEF,MAAM,QAAQ,iBAAiB;AAC7B,QAAK,cAAc,OAAO,UAAU;AACpC,QAAK,WAAW,UAAU;KACzB,wBAAwB;AAC3B,OAAK,cAAc,IAAI,WAAW,MAAM;;CAG1C,cAAsB,cAA4B;EAChD,MAAM,QAAQ,KAAK,cAAc,IAAI,UAAU;AAC/C,MAAI,OAAO;AACT,gBAAa,MAAM;AACnB,QAAK,cAAc,OAAO,UAAU;;AAEjC,OAAK,qBAAqB,UAAU,CAAC,OAAO,UAAmB;AAClE,WAAQ,MAAM,8CAA8C,UAAU,IAAI,sBAAsB,MAAM,GAAG;IACzG;;CAGJ,uBAA+B,OAAO,cAAqC;AACzE,MAAI,KAAK,QACP;EAEF,MAAM,gBAAgB,MAAM,KAAK,OAAO,kBAAkB,iBACxD,WACA,KAAK,OAAO,kBAAkB,qBAAqB,UAAU,CAC9D;AACD,MAAI,CAAC,wBAAwB,cAAc,IAAI,KAAK,QAClD;EAEF,MAAM,YAAY,6BAA6B,cAAc;AAC7D,MAAI,KAAK,gCAAgC,IAAI,UAAU,KAAK,UAC1D;AAEF,OAAK,gCAAgC,IAAI,WAAW,UAAU;AAC9D,OAAK,OAAO,SAAS,KAAK,UAAU,UAAU;GAC5C,MAAM,aAAa;GACnB,SAAS;IACP;IACA;IACD;GACF,EAAE;GACD,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC,QAAQ;GACT,CAAC;;CAGJ,kCACE,WACA,kBACS;AACT,OAAK,gCAAgC,IAAI,WAAW,6BAA6B,cAAc,CAAC;;;;;AClHpG,IAAa,6BAAb,MAAsE;CACpE;CACA,UAAkB;CAElB,YAAY,QAAyC;AAAxB,OAAA,SAAA;AAC3B,OAAK,gBAAgB,CACnB,IAAI,yBAAyB,OAAO,EACpC,IAAI,iCAAiC,OAAO,CAC7C;;CAGH,cAAoB;AAClB,MAAI,KAAK,QACP;AAEF,OAAK,UAAU;AACf,OAAK,MAAM,gBAAgB,KAAK,cAC9B,cAAa,OAAO;AAEtB,OAAK,OAAO,uBAAuB,OAAO;;CAG5C,oBAAoB,WAClB,KAAK,OAAO,oBAAoB,iBAAiB,OAAO;CAE1D,UAAU,YAA2B;AACnC,MAAI,CAAC,KAAK,QACR;AAEF,QAAM,KAAK,OAAO,uBAAuB,SAAS;AAClD,QAAM,KAAK,OAAO,kBAAkB,SAAS;AAC7C,OAAK,MAAM,gBAAgB,CAAC,GAAG,KAAK,cAAc,CAAC,SAAS,CAC1D,OAAM,aAAa,SAAS;AAE9B,OAAK,UAAU;;;;;ACtCnB,MAAa,sCAAsC;AACnD,MAAa,kDACX;AACF,MAAa,+CACX;AACF,MAAa,oDACX;AACF,MAAa,+CACX;AACF,MAAa,iCAAiC,CAAC,gBAAgB;AAQ/D,SAAgB,8BACd,QAC2B;AAC3B,QAAO;EACL,SAAS,OAAO,OAAO,aAAa;EACpC,mBACE,OAAO,OAAO,aAAa,qBAAA;EAE9B;;;;AC3BH,SAAS,mBAAmB,OAAuB;AACjD,QAAO,UAAU,IAAI,gBAAgB,GAAG,MAAM;;AAGhD,SAAgB,sBAAsB,QAI3B;AACT,QAAO;EACL;EACA,sBAAsB,OAAO,UAAU;EACvC,mBAAmB,mBAAmB,OAAO,qBAAqB,CAAC,wCAAwC,OAAO,qBAAqB;EACvI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;;;ACKd,SAAS,0BAA0B,SAA6B;AAC9D,KAAI,CAAC,MAAM,QAAQ,QAAQ,MAAM,CAC/B,QAAO;CAET,MAAM,0BAAU,IAAI,KAAa;CACjC,IAAI,iBAAiB;AACrB,MAAK,MAAM,QAAQ,QAAQ,OAAO;AAChC,MAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,KAAK,CAC1D;EAEF,MAAM,YAAY;AAIlB,MAAI,UAAU,SAAS,kBACrB;AAEF,MAAI,OAAO,UAAU,eAAe,YAAY,UAAU,WAAW,MAAM,EAAE;AAC3E,WAAQ,IAAI,UAAU,WAAW,MAAM,CAAC;AACxC;;AAEF,oBAAkB;;AAEpB,QAAO,QAAQ,OAAO;;AAGxB,SAAS,sBAAsB,UAAyC;AACtE,QAAO,SAAS,QAAQ,OAAO,YAAY,QAAQ,0BAA0B,QAAQ,EAAE,EAAE;;AAG3F,SAAS,iBAAiB,UAAuD;CAC/E,MAAM,QAAQ,SAAS;AACvB,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS,IAAI,MAAM,MAAM,GAAG,KAAA;;AAG/E,SAAS,uBAAuB,UAA4C;AAC1E,QAAO,SAAS,yCAAyC;;AAG3D,SAAS,kCACP,UACQ;CACR,MAAM,QAAQ,SAAS;AACvB,QAAO,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,GAAG,QAAQ;;AAGvE,SAAS,yBAAyB,OAAwC;AACxE,KAAI,MAAM,SAAS,aAAa,YAC9B,QAAO;AAET,QAAO,MAAM,QAAQ,WAAW,MAAM,IAAI;;AAG5C,IAAa,2BAAb,MAAoE;CAClE;CACA;CACA,qCAAsC,IAAI,KAAa;CACvD,cAA0C;CAE1C,YAAY,QAAyC;AAAxB,OAAA,SAAA;AAC3B,OAAK,eAAe,OAAO;AAC3B,OAAK,mBAAmB,OAAO;;CAGjC,cAAoB;AAClB,MAAI,KAAK,YACP;AAEF,OAAK,cAAc,KAAK,OAAO,SAAS,GAAG,UAAU,UAAU,KAAK,eAAe;;CAGrF,gBAAsB;AACpB,OAAK,eAAe;AACpB,OAAK,cAAc;AACnB,OAAK,mBAAmB,OAAO;;CAGjC,kBAA0B,UAAkC;EAC1D,MAAM,YAAY,yBAAyB,MAAM;AACjD,MAAI,CAAC,UACH;AAEG,OAAK,8BAA8B,UAAU,CAAC,OAAO,UAAU;AAClE,WAAQ,KACN,8BAA8B,UAAU,IACtC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAEzD;IACD;;CAGJ,gCAAwC,OACtC,cACkB;AAClB,MAAI,KAAK,mBAAmB,IAAI,UAAU,CACxC;EAEF,MAAM,UAAU,MAAM,KAAK,aAAa,iBAAiB,UAAU;EACnE,MAAM,WAAW,SAAS,YAAY,EAAE;AACxC,MAAI,CAAC,WAAW,oBAAoB,SAAS,CAC3C;EAEF,MAAM,gBAAgB,KAAK,mBAAmB;AAC9C,MAAI,CAAC,cAAc,WAAW,uBAAuB,SAAS,CAC5D;EAEF,MAAM,iBAAiB,sBAAsB,QAAQ,SAAS;EAI9D,MAAM,uBAAuB,iBAHK,kCAChC,SACD;AAED,MAAI,uBAAuB,cAAc,kBACvC;AAGF,OAAK,mBAAmB,IAAI,UAAU;AACtC,MAAI;GACF,MAAM,gBAAgB,MAAM,KAAK,iBAAiB,uBAAuB;IACvE,iBAAiB;IACjB,sBAAsB,YAAY,KAAA;IAClC,uBAAuB;IACvB,mBAAmB;KACjB,kBAAkB;MACjB,sCAAsC;MACtC,+CAA+C;KACjD;IACD,iBAAiB;IACjB,QAAQ;IACR,OAAO,KAAK,iBAAiB,SAAS;IACtC,MAAM,sBAAsB;KAC1B;KACA;KACA,sBAAsB;KACvB,CAAC;IACH,CAAC;AACF,SAAM,KAAK,aAAa,sBAAsB,WAAW;KACtD,kDAAkD;KAClD,gEAA+C,IAAI,MAAM,EAAC,aAAa;KACvE,oDACC,cAAc;IACjB,CAAC;YACM;AACR,QAAK,mBAAmB,OAAO,UAAU;;;CAI7C,0BAA6D;AAC3D,SAAO,8BAA8B,KAAK,OAAO,cAAc,YAAY,CAAC;;CAG9E,oBAA4B,aAA8C;EACxE,MAAM,QAAQ,iBAAiB,SAAS;AACxC,SAAO,QAAQ,kBAAkB,UAAU;;;;;ACnL/C,MAAM,0BAA0B;AAEhC,SAAS,cAAc,OAA+B;AACpD,KAAI,OAAO,UAAU,SACnB,QAAO;CAET,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU;;AAGxC,SAAS,mBAAmB,OAAuB;AACjD,QAAO,MAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM;;AAG1C,SAAS,oBAAoB,OAAuB;CAClD,MAAM,YAAY,mBAAmB,MAAM;AAC3C,KAAI,UAAU,UAAU,wBACtB,QAAO;AAET,QAAO,UAAU,MAAM,GAAG,0BAA0B,EAAE,CAAC,SAAS;;AAGlE,SAAS,uBAAuB,SAAoC;CAClE,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,QAAQ,QAAQ,MACzB,MAAK,KAAK,SAAS,UAAU,KAAK,SAAS,gBAAgB,KAAK,KAAK,MAAM,CACzE,QAAO,KAAK,KAAK,KAAK;CAG1B,MAAM,cAAc,oBAAoB,OAAO,KAAK,IAAI,CAAC;AACzD,QAAO,YAAY,SAAS,IAAI,cAAc;;AAGhD,SAAS,iBACP,WACA,SACyC;AACzC,KAAI,CAAC,UACH,QAAO;AAET,QAAO;EAAE;EAAW;EAAS;;AAG/B,SAAS,kBAAkB,OAAwB;AACjD,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAC3C,QAAO,QAAQ,oBAAoB,MAAM;AAE3C,KAAI,SAAS,OAAO,UAAU,YAAY,aAAa,OAAO;EAC5D,MAAM,UAAW,MAAgC;AACjD,MAAI,OAAO,YAAY,YAAY,QAAQ,MAAM,CAC/C,QAAO,QAAQ,oBAAoB,QAAQ;;AAG/C,QAAO;;AAGT,SAAgB,yCACd,OACA,WACyC;AACzC,SAAQ,MAAM,MAAd;EACE,KAAK,aAAa,WAChB,QAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;GAC9D,OAAO;GACP,YAAY;GACZ;GACD,CAAC;EACJ,KAAK,aAAa,YAChB,QAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;GAC9D,OAAO;GACP;GACD,CAAC;EACJ,KAAK,aAAa,SAChB,QAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;GAC9D,OAAO;GACP,YAAY,kBAAkB,MAAM,QAAQ,MAAM;GAClD;GACD,CAAC;EACJ,KAAK,aAAa,aAAa;GAC7B,MAAM,OAAO,uBAAuB,MAAM,QAAQ,QAAQ;AAC1D,OAAI,CAAC,QAAQ,MAAM,QAAQ,QAAQ,SAAS,OAC1C,QAAO;AAET,UAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;IAC9D,OAAO;IACP,YAAY;IACZ,WAAW,MAAM,QAAQ,QAAQ,aAAa;IAC/C,CAAC;;EAEJ,KAAK,aAAa,kBAAkB;GAClC,MAAM,OAAO,uBAAuB,MAAM,QAAQ,QAAQ;AAC1D,OAAI,CAAC,QAAQ,MAAM,QAAQ,QAAQ,SAAS,YAC1C,QAAO;AAET,UAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;IAC9D,OAAO;IACP,WAAW;IACX,WAAW,MAAM,QAAQ,QAAQ,aAAa;IAC/C,CAAC;;EAEJ,KAAK,aAAa,cAChB,QAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;GAC9D,OAAO;GACP,YAAY,kBAAkB,MAAM,QAAQ,MAAM;GAClD;GACD,CAAC;EACJ,KAAK,aAAa,qBAChB,QAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;GAC9D,OAAO;GACP,YAAY,UAAU,MAAM,QAAQ;GACpC;GACD,CAAC;EACJ,KAAK,aAAa;EAClB,KAAK,aAAa,sBAChB,QAAO,iBAAiB,cAAc,MAAM,QAAQ,UAAU,EAAE;GAC9D,OAAO;GACP,YAAY;GACZ;GACD,CAAC;EACJ,QACE,QAAO;;;;;ACxHb,MAAa,wCAAwC;AAErD,MAAM,kCAAkC,IAAI,IAAiC;CAC3E;CACA;CACA;CACA;CACD,CAAC;AAEF,SAASC,WAAS,OAAkD;AAClE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAASC,qBAAmB,OAAoC;AAC9D,KAAI,OAAO,UAAU,SACnB;CAEF,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,SAAS,mCAAmC,OAAuD;AACjG,KAAI,CAACD,WAAS,MAAM,CAClB,QAAO;CAET,MAAM,QAAQ,MAAM;CACpB,MAAM,YAAYC,qBAAmB,MAAM,UAAU;AACrD,KAAI,CAAC,gCAAgC,IAAI,MAAqC,IAAI,CAAC,UACjF,QAAO;AAET,QAAO;EACE;EACP;EACA,GAAIA,qBAAmB,MAAM,WAAW,GAAG,EAAE,YAAYA,qBAAmB,MAAM,WAAW,EAAE,GAAG,EAAE;EACpG,GAAIA,qBAAmB,MAAM,UAAU,GAAG,EAAE,WAAWA,qBAAmB,MAAM,UAAU,EAAE,GAAG,EAAE;EAClG;;AAGH,SAAS,oBAAoB,MAAc,OAAuB;CAChE,MAAM,WAAW,KAAK,MAAM,KAAK;CACjC,MAAM,YAAY,KAAK,MAAM,MAAM;AACnC,KAAI,CAAC,OAAO,SAAS,SAAS,IAAI,CAAC,OAAO,SAAS,UAAU,CAC3D,QAAO,KAAK,cAAc,MAAM;AAElC,QAAO,WAAW;;AAGpB,SAAS,4BACP,SACA,UACgC;AAChC,KAAI,WAAW,oBAAoB,SAAS,WAAW,QAAQ,UAAU,GAAG,EAC1E,QAAO,SAAS,aAAa,CAAC,QAAQ,YAAY;EAAE,GAAG;EAAS,WAAW,SAAS;EAAW,GAAG;AAEpG,QAAO;EACL,OAAO,SAAS;EAChB,WAAW,SAAS;EACpB,GAAI,SAAS,eAAe,SAAS,UAAU,cAAc,SAAS,aAAa,KAAA,KAC/E,EAAE,YAAY,SAAS,cAAc,SAAS,YAAY,GAC1D,EAAE;EACN,GAAI,SAAS,aAAa,SAAS,YAAY,EAAE,WAAW,SAAS,aAAa,SAAS,WAAW,GAAG,EAAE;EAC5G;;AAGH,SAAS,gCACP,MACA,OACS;AACT,QAAO,QAAQ,KAAK,IAClB,MAAM,UAAU,MAAM,SACtB,KAAK,cAAc,MAAM,aACzB,KAAK,eAAe,MAAM,cAC1B,KAAK,cAAc,MAAM;;AAG7B,SAAgB,oCACd,UACA,YACgC;CAChC,MAAM,UAAU,mCAAmC,WAAW,uCAAuC;CACrG,MAAM,OAAO,4BAA4B,SAAS,WAAW,QAAQ;AACrE,KAAI,gCAAgC,SAAS,KAAK,CAChD,QAAO;AAET,QAAO;EACL,GAAI,YAAY,EAAE;GACjB,wCAAwC;EAC1C;;;;ACtFH,IAAa,qCAAb,MAA8E;CAC5E,sBAAkD;CAClD,sCAAuC,IAAI,KAA4B;CAEvE,YAAY,QAAyC;AAAxB,OAAA,SAAA;;CAE7B,cAAoB;AAClB,MAAI,KAAK,oBACP;AAEF,OAAK,sBAAsB,KAAK,OAAO,SAAS,GAAG,UAAU,WAAW,UAAU;GAChF,MAAM,aAAa,yCAAyC,wBAAO,IAAI,MAAM,EAAC,aAAa,CAAC;AAC5F,OAAI,CAAC,WACH;AAEF,QAAK,cAAc,WAAW;IAC9B;;CAGJ,gBAAsB;AACpB,OAAK,uBAAuB;AAC5B,OAAK,sBAAsB;AAC3B,OAAK,oBAAoB,OAAO;;CAGlC,iBAAyB,eAAuD;EAE9E,MAAM,QADW,KAAK,oBAAoB,IAAI,WAAW,UAAU,IAAI,QAAQ,SAAS,EAClE,WAAW,KAAK,sBAAsB,WAAW,CAAC;AACxE,OAAK,oBAAoB,IAAI,WAAW,WAAW,KAAK,YAAY,KAAA,EAAU,CAAC;AAC1E,OACF,OAAO,UAAmB;GACzB,MAAM,UAAU,iBAAiB,QAAQ,MAAM,SAAS,MAAM,UAAU,OAAO,MAAM;AACrF,WAAQ,MACN,+CAA+C,WAAW,UAAU,IAAI,UACzE;IACD;;CAGN,wBAAgC,OAAO,eAAgE;EAErG,MAAM,eAAe,qCADL,MAAM,KAAK,OAAO,kBAAkB,iBAAiB,WAAW,UAAU,GACxB,UAAU,WAAW;AACvF,MAAI,CAAC,aACH;AAEF,QAAM,KAAK,OAAO,kBAAkB,sBAAsB,WAAW,WAAW,aAAa;;;;;AChDjG,SAASC,qBAAmB,QAAiC,KAAqB;CAChF,MAAM,QAAQ,OAAO;AACrB,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,WAAW,EACvD,OAAM,IAAI,MAAM,GAAG,IAAI,8BAA8B;AAEvD,QAAO,MAAM,MAAM;;AAGrB,SAASC,qBAAmB,QAAiC,KAAiC;CAC5F,MAAM,QAAQ,OAAO;AACrB,KAAI,OAAO,UAAU,SACnB;CAEF,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAGxC,IAAa,qBAAb,cAAwC,KAAK;CAC3C,kBAA0B;CAC1B,eAAuB;CAEvB,YAAY,SAAiD;AAC3D,SAAO;AADoB,OAAA,UAAA;;CAI7B,IAAI,OAAe;AACjB,SAAO;;CAGT,IAAI,cAAsB;AACxB,SAAO;;CAGT,IAAI,aAAsC;AACxC,SAAO;GACL,MAAM;GACN,YAAY;IACV,QAAQ;KACN,MAAM;KACN,aAAa;KACb,YAAY,EACV,YAAY;MACV,MAAM;MACN,aAAa;MACd,EACF;KACD,UAAU,CAAC,aAAa;KACzB;IACD,MAAM;KACJ,MAAM;KACN,aAAa;KACd;IACD,QAAQ;KACN,MAAM;KACN,MAAM,CAAC,QAAQ,cAAc;KAC7B,aAAa;KACd;IACD,OAAO;KACL,MAAM;KACN,aAAa;KACd;IACF;GACD,UAAU;IAAC;IAAU;IAAQ;IAAS;GACvC;;CAGH,cAAc,WAGF;AACV,OAAK,kBAAkB,OAAO;AAC9B,OAAK,eAAe,OAAO,gBAAgB;;CAG7C,UAAU,OACR,QACA,YACqB;EACrB,MAAM,SAAS,OAAO;AACtB,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CAChE,OAAM,IAAI,MAAM,4BAA4B;EAE9C,MAAM,OAAOD,qBAAmB,QAAQ,OAAO;EAC/C,MAAM,aAAaC,qBAAmB,QAAQ,SAAS,EAAE,aAAa;AACtE,MAAI,eAAe,UAAU,eAAe,cAC1C,OAAM,IAAI,MAAM,8CAA0C;EAE5D,MAAM,EAAE,YAAY,yBAAyB;AAE7C,SAAO,KAAK,QAAQ,eAAe;GACjC,iBAAiB,KAAK;GACtB,GAAI,aAAa,EAAE,kBAAkB,YAAY,GAAG,EAAE;GACtD;GACA,iBAAiBD,qBAAmB,QAAmC,aAAa;GACpF;GACA,OAAOC,qBAAmB,QAAQ,QAAQ;GAC1C,QAAQ;GACR,cAAc,KAAK;GACpB,CAAC;;;;;ACjGN,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB,KAAK;AAC/B,MAAM,yBAAyB;AAE/B,SAAS,MAAM,OAAgB,UAA0B;CACvD,MAAM,SAAS,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW,OAAO,MAAM,GAAG;AACxF,QAAO,OAAO,SAAS,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC,GAAG;;AAGrE,SAASC,aAAW,OAAoC;AACtD,QAAO,OAAO,UAAU,YAAY,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,KAAA;;AAGpE,SAAS,YAAY,SAA6B;CAChD,MAAM,OAAO,QAAQ,MAClB,KAAK,SAAU,KAAK,SAAS,UAAU,KAAK,SAAS,eAAe,KAAK,SAAS,cAAc,KAAK,OAAO,GAAI,CAChH,OAAO,QAAQ,CACf,KAAK,KAAK;AACb,KAAI,KAAM,QAAO;AACjB,QAAO,KAAK,UAAU,QAAQ,OAAO,MAAM,EAAE;;AAG/C,SAAS,gBAAgB,SAAqB;CAC5C,MAAM,UAAU,YAAY,QAAQ;CACpC,MAAM,YAAY,QAAQ,SAAS;AACnC,QAAO;EACL,MAAM,QAAQ;EACd,SAAS,YAAY,GAAG,QAAQ,MAAM,GAAG,uBAAuB,CAAC,uBAAuB;EACxF,WAAW,QAAQ;EACnB,GAAI,YAAY,EAAE,WAAW,MAAM,GAAG,EAAE;EACzC;;AAGH,SAAS,WAAW,OAA6B;CAC/C,MAAM,OAAO,KAAK,UAAU,MAAM;AAClC,KAAI,OAAO,WAAW,MAAM,OAAO,IAAI,kBAAmB,QAAO;CACjE,MAAM,OAAO,MAAM,GAAG,GAAG;AACzB,QAAO,QAAQ,OAAO,WAAW,KAAK,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,IAAI,oBAChE,CAAC,KAAK,GACN,CAAC;EAAE,MAAM;EAAa,SAAS;EAAiD,CAAC;;AAGvF,SAAS,aAAa,SAAgD;AACpE,QAAOA,aAAW,QAAQ,UAAU,MAAM,IAAIA,aAAW,QAAQ,UAAU,cAAc;;AAG3F,IAAa,mBAAb,cAAsC,KAAK;CACzC,YAAY,UAA8C;AACxD,SAAO;AADoB,OAAA,WAAA;;CAI7B,IAAI,OAAe;AACjB,SAAO;;CAGT,IAAI,cAAsB;AACxB,SAAO;;CAGT,IAAI,aAAsC;AACxC,SAAO;GACL,MAAM;GACN,YAAY;IACV,YAAY;KAAE,MAAM;KAAU,aAAa;KAAsC;IACjF,OAAO;KAAE,MAAM;KAAW,SAAS;KAAG,aAAa;KAAwC;IAC3F,cAAc;KAAE,MAAM;KAAW,SAAS;KAAG,aAAa;KAAoC;IAC/F;GACF;;CAGH,UAAU,OAAO,WAAqD;EACpE,MAAM,EAAE,OAAO,cAAc,eAAe;EAC5C,MAAM,kBAAkBA,aAAW,WAAW;EAC9C,MAAM,YAAY,kBACd,CAAC,MAAM,KAAK,SAAS,WAAW,gBAAgB,CAAC,CAAC,QAAQ,YAA0C,QAAQ,QAAQ,CAAC,GACrH,MAAM,KAAK,SAAS,cAAc;EACtC,MAAM,cAAc,MAAM,OAAO,cAAc;EAC/C,MAAM,cAAc,KAAK,IAAI,MAAM,cAAc,EAAE,EAAE,kBAAkB;EACvE,MAAM,SAAoC,EAAE;AAE5C,OAAK,MAAM,WAAW,WAAW;GAC/B,MAAM,QAAiC;IACrC,KAAK,QAAQ;IACb,WAAW,QAAQ;IACnB,SAAS,QAAQ;IACjB,OAAO,aAAa,QAAQ;IAC5B,WAAW,QAAQ;IACnB,WAAW,QAAQ;IACnB,QAAQ,QAAQ;IACjB;AACD,OAAI,cAAc,EAChB,OAAM,YAAY,MAAM,KAAK,SAAS,oBAAoB,QAAQ,UAAU,EACzE,QAAQ,YAAY,QAAQ,SAAS,OAAO,CAC5C,MAAM,CAAC,YAAY,CACnB,IAAI,gBAAgB;AAEzB,UAAO,KAAK,MAAM;AAClB,OAAI,OAAO,UAAU,YAAa;;AAEpC,SAAO,KAAK,UAAU,EAAE,UAAU,QAAQ,EAAE,MAAM,EAAE;;;AAIxD,IAAa,sBAAb,cAAyC,KAAK;CAC5C,YAAY,UAA8C;AACxD,SAAO;AADoB,OAAA,WAAA;;CAI7B,IAAI,OAAe;AACjB,SAAO;;CAGT,IAAI,cAAsB;AACxB,SAAO;;CAGT,IAAI,aAAsC;AACxC,SAAO;GACL,MAAM;GACN,YAAY;IACV,YAAY;KAAE,MAAM;KAAU,aAAa;KAAc;IACzD,OAAO;KAAE,MAAM;KAAW,SAAS;KAAG,aAAa;KAAwC;IAC3F,cAAc;KAAE,MAAM;KAAW,aAAa;KAAyB;IACxE;GACD,UAAU,CAAC,aAAa;GACzB;;CAGH,UAAU,OAAO,WAAqD;EACpE,MAAM,EAAE,cAAc,OAAO,YAAY,kBAAkB;EAC3D,MAAM,aAAaA,aAAW,cAAc;AAC5C,MAAI,CAAC,WAAY,QAAO;EACxB,MAAM,UAAU,MAAM,KAAK,eAAe,WAAW;AACrD,MAAI,CAAC,QAAS,QAAO,mBAAmB,WAAW;EACnD,MAAM,WAAW,MAAM,KAAK,SAAS,oBAAoB,QAAQ,UAAU;EAC3E,MAAM,WAAW,iBAAiB,OAAO,WAAW,SAAS,QAAQ,YAAY,QAAQ,SAAS,OAAO;AACzG,SAAO,KAAK,UAAU;GACpB,YAAY,QAAQ;GACpB,UAAU,WAAW,SAAS,MAAM,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC,IAAI,gBAAgB,CAAC;GACxF,EAAE,MAAM,EAAE;;CAGb,iBAAyB,OAAO,eAA0D;EACxF,MAAM,QAAQ,MAAM,KAAK,SAAS,WAAW,WAAW;AACxD,MAAI,MAAO,QAAO;AAElB,UADkB,MAAM,KAAK,SAAS,cAAc,EACnC,MAAM,YACrB,QAAQ,UAAU,SAAS,IAAI,aAAa,IAAI,aAAa,QAAQ,KAAK,WAC3E,IAAI;;;;;AChJT,SAAS,SAAS,OAAkD;AAClE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,oBAAoB,OAAoC;AAC/D,KAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,MAAM,CACtD;AAEF,QAAO,KAAK,MAAM,MAAM;;AAG1B,SAAS,oBAAoB,OAAqC;AAChE,QAAO,OAAO,UAAU,YAAY,QAAQ,KAAA;;AAG9C,IAAa,oBAAb,MAAkD;CAChD,OAAgB;CAChB,cACE;CACF,aAAsB;EACpB,MAAM;EACN,YAAY;GACV,OAAO;IACL,MAAM;IACN,aAAa;IACd;GACD,OAAO;IACL,MAAM;IACN,SAAS;IACT,SAAS;IACT,aAAa,uCAAuC,6BAA6B;IAClF;GACD,uBAAuB;IACrB,MAAM;IACN,aAAa;IACd;GACF;EACD,UAAU,CAAC,QAAQ;EACnB,sBAAsB;EACvB;CAED,YACE,cAGA,SAGA;AANiB,OAAA,eAAA;AAGA,OAAA,UAAA;;CAKnB,gBAAgB,SAA4C;EAC1D,MAAM,SAAmB,EAAE;EAC3B,MAAM,QAAQC,kBAAgB,KAAK,MAAM;EACzC,MAAM,QAAQ,oBAAoB,KAAK,MAAM;EAC7C,MAAM,wBAAwB,oBAAoB,KAAK,sBAAsB;AAE7E,MAAI,CAAC,MACH,QAAO,KAAK,oCAAoC;AAElD,MAAI,OAAO,KAAK,UAAU,eAAe,OAAO,UAAU,YACxD,QAAO,KAAK,kCAAkC;AAEhD,MAAI,OAAO,UAAU,aAAa,QAAQ,KAAK,QAAQ,0BACrD,QAAO,KAAK,+BAA+B,yBAAyB,GAAG;AAEzE,MACE,OAAO,KAAK,0BAA0B,eACtC,OAAO,0BAA0B,YAEjC,QAAO,KAAK,2CAA2C;AAGzD,SAAO;;CAGT,UAAU,OAAO,SAAoC;AACnD,MAAI,CAAC,SAAS,KAAK,CACjB,OAAM,IAAI,MAAM,8CAA8C;EAGhE,MAAM,SAAS,KAAK,aAAa,KAAK;AACtC,MAAI,OAAO,SAAS,EAClB,OAAM,IAAI,MAAM,OAAO,KAAK,IAAI,CAAC;AAGnC,SAAO,KAAK,aAAa,OAAO;GAC9B,OAAOA,kBAAgB,KAAK,MAAM,IAAI;GACtC,OAAO,oBAAoB,KAAK,MAAM;GACtC,uBAAuB,oBAAoB,KAAK,sBAAsB;GACtE,kBAAkB,KAAK,QAAQ;GAChC,CAAC;;;;;AC3FN,SAAS,mBAAmB,OAAgB,KAAqB;AAC/D,KAAI,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,WAAW,EACvD,OAAM,IAAI,MAAM,GAAG,IAAI,8BAA8B;AAEvD,QAAO,MAAM,MAAM;;AAGrB,SAASC,qBAAmB,OAAoC;AAC9D,KAAI,OAAO,UAAU,SACnB;CAEF,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;AAKxC,SAAS,eAAe,OAAmC;CACzD,MAAM,aAAaA,qBAAmB,MAAM,EAAE,aAAa;AAC3D,KAAI,CAAC,cAAc,eAAe,aAChC,QAAO;AAET,KAAI,eAAe,QACjB,QAAO;AAET,OAAM,IAAI,MAAM,6CAAyC;;AAG3D,SAAS,gBAAgB,OAAsD;CAC7E,MAAM,aAAaA,qBAAmB,MAAM,EAAE,aAAa;AAC3D,KAAI,CAAC,cAAc,OAAO,UAAU,YAClC;AAEF,KAAI,eAAe,UAAU,eAAe,cAC1C,QAAO;AAET,OAAM,IAAI,MAAM,8CAA0C;;AAG5D,IAAa,mBAAb,cAAsC,KAAK;CACzC,kBAA0B;CAC1B,wBAAyD,EAAE;CAC3D,eAAuB;CAEvB,YACE,mBACA,uBACA;AACA,SAAO;AAHU,OAAA,oBAAA;AACA,OAAA,wBAAA;;CAKnB,IAAI,OAAe;AACjB,SAAO;;CAGT,IAAI,cAAsB;AACxB,SAAO;;CAGT,IAAI,aAAsC;AACxC,SAAO;GACL,MAAM;GACN,YAAY;IACV,MAAM;KACJ,MAAM;KACN,aAAa;KACd;IACD,OAAO;KACL,MAAM;KACN,MAAM,CAAC,cAAc,QAAQ;KAC7B,aAAa;KACd;IACD,OAAO;KACL,MAAM;KACN,aAAa;KACd;IACD,OAAO;KACL,MAAM;KACN,aAAa;KACd;IACD,SAAS;KACP,MAAM;KACN,aAAa;KACd;IACD,SAAS;KACP,MAAM;KACN,aAAa;KACd;IACD,QAAQ;KACN,MAAM;KACN,MAAM,CAAC,QAAQ,cAAc;KAC7B,aAAa;KACd;IACF;GACD,UAAU,CAAC,OAAO;GAClB,sBAAsB;GACvB;;CAGH,cAAc,WAIF;AACV,OAAK,kBAAkB,OAAO;AAC9B,OAAK,wBAAwB,gBAAgB,OAAO,sBAAsB;AAC1E,OAAK,eAAe,OAAO,gBAAgB;;CAG7C,UAAU,OAAO,QAAiC,YAAoD;EACpG,MAAM,EACJ,SAAS,YACT,OAAO,UACP,QAAQ,WACR,SAAS,YACT,OAAO,UACP,MAAM,SACN,OAAO,aACL;EACJ,MAAM,OAAO,mBAAmB,SAAS,OAAO;EAChD,MAAM,QAAQ,eAAe,SAAS;EACtC,MAAM,SAAS,gBAAgB,UAAU;EACzC,MAAM,kBAAkB,UAAU,UAAU,KAAK,4BAA4B,GAAG,KAAA;EAChF,MAAM,EAAE,YAAY,yBAAyB;AAE7C,MAAI,OACF,QAAO,KAAK,sBAAsB,uBAAuB;GACvD,iBAAiB,KAAK;GACtB,GAAI,aAAa,EAAE,kBAAkB,YAAY,GAAG,EAAE;GACtD;GACA,uBAAuB,KAAK;GAC5B;GACA,OAAOA,qBAAmB,SAAS;GACnC,SAASA,qBAAmB,WAAW;GACvC,OAAOA,qBAAmB,SAAS;GACnC,SAASA,qBAAmB,WAAW;GACvC,cAAc,KAAK;GACnB,GAAI,kBAAkB,EAAE,iBAAiB,GAAG,EAAE;GAC9C;GACD,CAAC;EAGJ,MAAM,UAAU,MAAM,KAAK,kBAAkB,cAAc;GACzD,iBAAiB,KAAK;GACtB;GACA,OAAOA,qBAAmB,SAAS;GACnC,uBAAuB,KAAK;GAC5B,SAASA,qBAAmB,WAAW;GACvC,OAAOA,qBAAmB,SAAS;GACnC,SAASA,qBAAmB,WAAW;GACvC,GAAI,kBAAkB,EAAE,iBAAiB,GAAG,EAAE;GAC/C,CAAC;AAEF,SAAO;GACL,MAAM;GACN,WAAW,QAAQ;GACnB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;GACvD,GAAI,QAAQ,kBAAkB,EAAE,iBAAiB,QAAQ,iBAAiB,GAAG,EAAE;GAC/E,gBAAgB,QAAQ,QAAQ,gBAAgB;GAChD,WAAW,QAAQ;GACnB,OAAO,QAAQ;GACf,aAAa,QAAQ;GACrB,WAAW,QAAQ;GACpB;;CAGH,mCAAmD;EACjD,MAAM,kBAAkB,KAAK,gBAAgB,MAAM;AACnD,MAAI,CAAC,gBACH,OAAM,IAAI,MAAM,qDAAmD;AAErE,SAAO;;;;;ACvJX,SAAS,sBAAsB,UAAuD;CACpF,MAAM,aAAa,CAAC,SAAS,WAAW,SAAS,WAAW;AAC5D,MAAK,MAAM,aAAa,YAAY;EAClC,MAAM,aAAaC,kBAAgB,UAAU;AAC7C,MAAI,WACF,QAAO;;;AAMb,IAAa,mBAAb,MAA4D;CAC1D,eAAuD;CAEvD,YAAY,QAAyC;AAAxB,OAAA,SAAA;;CAE7B,cAAoB;AAClB,MAAI,KAAK,aACP;AAEF,OAAK,eAAe,KAAK,OAAO,YAAY,aAAa;GACvD,IAAI;GACJ,eAAe,KAAK;GACrB,CAAC;;CAGJ,gBAAsB;AACpB,OAAK,cAAc,SAAS;AAC5B,OAAK,eAAe;;CAGtB,iBACE,SACA,aACS;AACT,OAAK,qBAAqB,SAAS,SAAS;AAC5C,OAAK,uBAAuB,SAAS,SAAS;AAC9C,OAAK,MAAM,QAAQ,iBAAiB,EAAE,YAAY,KAAK,OAAO,YAAY,CAAC,CACzE,UAAS,gBAAgB,KAAK;AAEhC,OAAK,MAAM,QAAQ,KAAK,OAAO,WAAW,gBAAgB,EAAE,SAAS,QAAQ,SAAS,CAAC,CACrF,UAAS,gBAAgB,KAAK;AAEhC,OAAK,0BAA0B,SAAS,SAAS;;CAGnD,wBACE,SACA,aACS;EACT,MAAM,EACJ,SACA,QACA,oBACA,cACA,UACA,qBACA,cACA,WACA,cACE;EACJ,MAAM,aAAa,sBAAsB,YAAY,KAAA;AACrD,WAAS,aAAa,IAAI,aAAa,WAAW,CAAC;AACnD,WAAS,aAAa,IAAI,cAAc,WAAW,CAAC;AACpD,WAAS,aAAa,IAAI,aAAa,WAAW,CAAC;AACnD,WAAS,aAAa,IAAI,YAAY,WAAW,CAAC;EAElD,MAAM,WAAW,IAAI,SAAS;GAC5B,YAAY;GACZ,SAAS;GACT;GACD,CAAC;AACF,WAAS,WAAW;GAClB,YAAY;GACZ;GACA;GACD,CAAC;AACF,WAAS,aAAa,SAAS;AAE/B,WAAS,aAAa,IAAI,cAAc,aAAa,CAAC;AACtD,WAAS,aAAa,IAAI,cAAc,CAAC;AACzC,OAAK,uBAAuB;GAAE;GAAS;GAAQ;GAAU,EAAE,SAAS;EAEpE,MAAM,oBAAoB,IAAI,iBAC5B,KAAK,OAAO,mBACZ,KAAK,OAAO,gBACb;AACD,oBAAkB,WAAW;GAC3B,iBAAiB;GACjB,uBAAuB;GACvB;GACD,CAAC;AACF,WAAS,aAAa,kBAAkB;EAExC,MAAM,sBAAsB,IAAI,mBAAmB,KAAK,OAAO,gBAAgB;AAC/E,sBAAoB,WAAW;GAC7B,iBAAiB;GACjB;GACD,CAAC;AACF,WAAS,aAAa,oBAAoB;AAE1C,WAAS,aAAa,IAAI,iBAAiB,KAAK,OAAO,kBAAkB,CAAC;AAC1E,WAAS,aAAa,IAAI,oBAAoB,KAAK,OAAO,kBAAkB,CAAC;AAE7E,WAAS,aAAa,IAAI,iBAAiB,UAAU,CAAC;AACtD,WAAS,aAAa,IAAI,cAAc,UAAU,CAAC;EAEnD,MAAM,cAAc,IAAI,YAAY,KAAK,OAAO,sBAAsB,CAAC;AACvE,cAAY,WAAW,EAAE,YAAY,WAAW,CAAC;AACjD,WAAS,aAAa,YAAY;;CAGpC,0BACE,SACA,aACS;EACT,MAAM,EAAE,SAAS,QAAQ,aAAa;EACtC,MAAM,YAAY,sBAAsB,SAAS;EACjD,MAAM,cAAc,IAAI,aACrB,YAAY,KAAK,OAAO,WAAW,gBAAgB,QAAQ,EAC5D,EAAE,iBAAiB,KAAK,wBAAwB,CACjD;AACD,cAAY,WAAW,SAAS,QAAQ,aAAa,KAAK;AAC1D,WAAS,aAAa,YAAY;EAElC,MAAM,WAAW,IAAI,SAAS,KAAK,OAAO,WAAW;AACrD,WAAS,WAAW,SAAS,QAAQ,aAAa,KAAK;AACvD,WAAS,aAAa,SAAS;;CAGjC,+BAAiD;EAE/C,MAAM,WADoB,KAAK,OAAO,WAAW,sBAAsB,EACnC,YAAY,EAAE;AAClD,SAAO,CAAC,GAAG,IAAI,IAAI,SAAS,KAAK,iBAAiB,aAAa,QAAQ,GAAG,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM;;CAG5G,0BACE,SACA,aACS;EACT,MAAM,oBAAoB,KAAK,OAAO,WAAW,sBAAsB;AACvE,MAAI,CAAC,qBAAqB,kBAAkB,MAAM,WAAW,EAC3D;EAGF,MAAM,uBAAO,IAAI,KAAa;AAC9B,OAAK,MAAM,gBAAgB,kBAAkB,MAC3C,MAAK,MAAM,SAAS,aAAa,OAAO;AACtC,OAAI,KAAK,IAAI,MAAM,IAAI,SAAS,QAAQ,MAAM,CAC5C;AAEF,QAAK,IAAI,MAAM;AACf,YAAS,aACP,IAAI,qBAAqB;IACvB;IACA;IACA,QAAQ,QAAQ;IAChB,cAAc,QAAQ;IACtB,iBAAiB,SAAS;IAC1B,aAAa,kBAAkB;IAChC,CAAC,CACH;;;CAKP,6BACE,SACA,aACS;AACT,MAAI,CAAC,KAAK,OAAO,cAAc,SAAS,CACtC;AAEF,WAAS,gBACP,IAAI,kBACF,EAAE,QAAQ,KAAK,OAAO,cAAc,QAAQ,EAC5C,EAAE,kBAAkB,QAAQ,WAAW,CACxC,CACF;;;;;AC1JL,MAAM,kBAAiC;AAEvC,SAAS,yBAAyB,SAAwC;CACxE,MAAM,UAAU,QAAQ,SAAS,MAAM;AACvC,KAAI,QACF,QAAO,UAAU,QAAQ,WAAW,QAAQ,EAAE,WAAW,CAAC;AAE5D,QAAO,iBAAiB;;AAG1B,SAAS,iCAAiC,SAAwC;CAChF,MAAM,UAAU,QAAQ,SAAS,MAAM;AACvC,KAAI,QACF,QAAO,QAAQ,WAAW,QAAQ,EAAE,QAAQ,YAAY;AAE1D,QAAO,QAAQ,YAAY,EAAE,QAAQ,YAAY;;AAgBnD,IAAM,+BAAN,MAIE;CACA,iBAIW;CAEX,yBACE,mBAKG;AACH,OAAK,iBAAiB;;CAGxB,8BAA8B;AAC5B,MAAI,CAAC,KAAK,eACR,OAAM,IAAI,MAAM,2CAA2C;AAE7D,SAAO,KAAK;;;AAIhB,IAAa,iBAAb,MAA4B;CAC1B,WAA8B,IAAI,UAAU;CAC5C,UAA4B,IAAI,SAAS;CACzC,aAAkC,IAAI,YAAY;CAClD,eAA4C,IAAI,oBAAoB;CACpE,WAAqC,IAAI,iBAAiB;CAC1D;CACA;CACA;CACA;CAKA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,UAAiC,EAAE,EAAE;EAC/C,MAAM,cAAc,yBAAyB,QAAQ;AACrD,OAAK,WAAW,IAAI,eAAe,EACjC,aACD,CAAC;AACF,OAAK,gBAAgB,IAAI,qBAAqB;GAC5C,cAAc,QAAQ,YAAY,EAAE,oBAAoB;GACxD;GACD,CAAC;AACF,OAAK,8BAA8B,IAAI,4BACrC,QAAQ,aAAa,qBAAqB,CAC3C;AACD,OAAK,aAAa,IAAI,kBAAkB,EACtC,WAAW,iCAAiC,QAAQ,EACrD,CAAC;AACF,OAAK,aAAa,IAAI,gBAAgB,EACpC,SAAS,QAAQ,YAAY,EAAE,SAAS,EACzC,CAAC;AACF,OAAK,SAAS,IAAI,cAAc;AAChC,OAAK,UAAU,IAAI,8BAIhB;AACH,OAAK,cAAc,IAAI,aAAa;AACpC,OAAK,WAAW,IAAIC,iBAAe;GACjC,KAAK,KAAK;GACV,gBAAgB,KAAK;GACtB,CAAC;AACF,OAAK,gBAAgB,IAAI,cAAc;GACrC,YAAY,QAAQ;GACpB,UAAU,KAAK;GACf,iBAAiB,KAAK;GACvB,CAAC;AACF,OAAK,aAAa,IAAI,iBAAiB;GACrC,eAAe,KAAK;GACpB,UAAU,KAAK;GACf,SAAS,KAAK;GACd,YAAY,KAAK;GACjB,gBAAgB,KAAK;GACtB,CAAC;AACF,OAAK,SAAS,IAAI,aAAa,EAC7B,WAAW,iBAAiB,KAAK,cAAc,OAAO,OAAO,SAAS,UAAU,EACjF,CAAC;AACF,OAAK,aAAa,IAAI,WAAW,KAAK,cAAc,WAAW;AAC/D,OAAK,cAAc,oBAAoB;GACrC,sBAAsB,KAAK,WAAW;GACtC,4BAA4B,KAAK,WAAW,sBAAsB,CAAC;GACnE,WAAW,OAAO,EAAE,aAAa,MAAM,KAAK,WAAW,YAAY,OAAO;GAC3E,CAAC;AACF,OAAK,sBAAsB,IAAI,oBAAoB;GACjD,eAAe,KAAK;GACpB,YAAY,KAAK;GAClB,CAAC;AACF,OAAK,oBAAoB,IAAI,kBAAkB;GAC7C,eAAe,KAAK;GACpB,UAAU,KAAK;GACf,cAAc,KAAK;GACnB,eAAe,KAAK;GACrB,CAAC;AACF,OAAK,kBAAkB,IAAI,sBAAsB;GAC/C,mBAAmB,KAAK;GACxB,YAAY,2CAA2C;IACrD,UAAU,KAAK;IACf,SAAS,KAAK;IACf,CAAC;GACH,CAAC;AACF,OAAK,oBAAoB,IAAI,kBAAkB;GAC7C,qBAAqB,KAAK;GAC1B,UAAU,KAAK;GACf,mBAAmB,KAAK;GACzB,CAAC;AACF,OAAK,yBAAyB,IAAI,uBAAuB;GACvD,0BAA0B,IAAI,yBAAyB;IACrD,eAAe,KAAK;IACpB,iBAAiB,KAAK;IACtB,mBAAmB,KAAK;IACzB,CAAC;GACF,SAAS,KAAK;GACd,mBAAmB,KAAK;GACxB,mBAAmB,KAAK;GACzB,CAAC;AACF,OAAK,uBACH,oBAAoB,WAChB,IAAI,aAAa,KAAK,GACtB,IAAI,2BAA2B,KAAK;AAC1C,OAAK,gBAAgB;GACnB,IAAI,iBAAiB,KAAK;GAC1B,IAAI,mCAAmC,KAAK;GAC5C,IAAI,yBAAyB,KAAK;GAClC,KAAK;GACN;;CAGH,oBAAoB,WAClB,KAAK,qBAAqB,iBAAiB,OAAO;CAEpD,4BAA4B,sBAA+C;AACzE,OAAK,oBAAoB;;CAG3B,6BAA4D,KAAK;CAEjE,QAAQ,YAA2B;AAC5B,OAAK,cAAc,OAAO;AAC/B,OAAK,WAAW,OAAO;AACvB,OAAK,MAAM,gBAAgB,KAAK,cAC9B,cAAa,OAAO;;CAIxB,UAAU,YAA2B;AACnC,OAAK,MAAM,gBAAgB,CAAC,GAAG,KAAK,cAAc,CAAC,SAAS,CAC1D,OAAM,aAAa,SAAS;AAE9B,OAAK,kBAAkB,SAAS;AAChC,QAAM,KAAK,oBAAoB,SAAS;AACxC,QAAM,KAAK,WAAW,SAAS;AAC/B,QAAM,KAAK,cAAc,SAAS;;;;;AC7MtC,SAASC,0BAAwB,OAAoC;AACnE,KAAI,OAAO,UAAU,SACnB;AAGF,QADgB,MAAM,MAAM,IACV,KAAA;;AAGpB,SAAS,sBAAsB,YAAuC;CACpE,MAAM,eAAeA,0BAAwB,WAAW,KAAK;AAC7D,KAAI,aACF,QAAO;CAET,MAAM,eAAeA,0BAAwB,WAAW,KAAK;AAC7D,KAAI,aACF,QAAO,SAAS,aAAa;CAE/B,MAAM,cAAcA,0BAAwB,WAAW,IAAI;AAC3D,KAAI,YACF,KAAI;AAEF,SAAO,SADQ,IAAI,IAAI,YAAY,CACZ,SAAS,IAAI;SAC9B;AACN,SAAO,SAAS,YAAY,IAAI;;AAGpC,QAAO;;AAGT,eAAe,iBACb,YACA,UACyB;CACzB,MAAM,WAAWA,0BAAwB,WAAW,SAAS;AAC7D,KAAI,SACF,QAAO,2BAA2B,YAAY,SAAS;CAGzD,MAAM,YAAYA,0BAAwB,WAAW,IAAI;CACzD,MAAM,YAAYA,0BAAwB,WAAW,KAAK;AAC1D,KAAI,UACF,QAAO,MAAM,4BAA4B,YAAY,WAAW,SAAS;AAG3E,KAAI,UACF,QAAO,4BAA4B,YAAY,UAAU;AAG3D,OAAM,IAAI,MACR,uCAAuC,sBAAsB,WAAW,CAAC,IAC1E;;AAGH,SAAS,mBAAmB,YAI1B;AACA,QAAO;EACL,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,MAAM,GAAG,EAAE;EACpD,GAAI,WAAW,WAAW,EAAE,UAAU,WAAW,UAAU,GAAG,EAAE;EAChE,GAAI,OAAO,WAAW,SAAS,WAC3B,EAAE,WAAW,WAAW,MAAM,GAC9B,EAAE;EACP;;AAGH,SAAS,2BACP,YACA,UACgB;AAChB,QAAO;EACL,MAAM;EACN;EACA,GAAG,mBAAmB,WAAW;EAClC;;AAGH,eAAe,4BACb,YACA,WACA,UACyB;AACzB,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,sDAAsD;CAGxE,MAAM,WAAW,sBAAsB,WAAW;CAClD,MAAM,QAAQ,MAAM,SAAS,UAAU;AAMvC,QAAO;EACL,MAAM;EACN,WAPa,MAAM,SAAS,SAAS;GACrC;GACA,UAAU,WAAW,YAAY;GACjC;GACD,CAAC,EAGiB;EACjB,MAAM,WAAW,QAAQ;EACzB,GAAI,WAAW,WAAW,EAAE,UAAU,WAAW,UAAU,GAAG,EAAE;EAChE,GAAI,OAAO,WAAW,SAAS,WAC3B,EAAE,WAAW,WAAW,MAAM,GAC9B,EAAE;EACP;;AAGH,SAAS,4BACP,YACA,WACgB;AAChB,QAAO;EACL,MAAM;EACN,KAAK;EACL,MAAM,WAAW,QAAQ,sBAAsB,WAAW;EAC1D,GAAI,WAAW,WAAW,EAAE,UAAU,WAAW,UAAU,GAAG,EAAE;EAChE,GAAI,OAAO,WAAW,SAAS,WAC3B,EAAE,WAAW,WAAW,MAAM,GAC9B,EAAE;EACP;;AAGH,eAAsB,sBAAsB,QAId;CAC5B,MAAM,EAAE,UAAU,aAAa,YAAY;CAC3C,MAAM,QAA0B,EAAE;AAClC,KAAI,QAAQ,SAAS,EACnB,OAAM,KAAK;EACT,MAAM;EACN,MAAM;EACP,CAAC;AAGJ,MAAK,MAAM,cAAc,eAAe,EAAE,CACxC,OAAM,KAAK,MAAM,iBAAiB,YAAY,SAAS,CAAC;AAG1D,QAAO;;AAGT,eAAsB,yBACpB,QACqC;CACrC,MAAM,EAAE,UAAU,aAAa,SAAS,UAAU,cAAc;AAChE,QAAO;EACL;EACA,SAAS,MAAM,sBAAsB;GACnC;GACA;GACA;GACD,CAAC;EACF,UAAU,gBAAgB,YAAY,EAAE,CAAC;EAC1C;;AAGH,SAAS,uBAAuB,OAA6C;AAC3E,KAAI,EAAE,aAAa,OACjB;CAEF,MAAM,gBAAgB,mBAAmB,MAAM,UAC3C,MAAM,QAAQ,gBACd,KAAA;AACJ,QAAO,OAAO,kBAAkB,YAAY,cAAc,SAAS,IAC/D,gBACA,KAAA;;AAGN,SAAS,mBAAmB,OAA6C;AACvE,KAAI,EAAE,aAAa,OACjB;CAEF,MAAM,YAAY,eAAe,MAAM,UACnC,MAAM,QAAQ,YACd,KAAA;AACJ,QAAO,OAAO,cAAc,YAAY,UAAU,SAAS,IACvD,YACA,KAAA;;AAGN,SAAS,eAAe,OAA6C;AACnE,KAAI,EAAE,aAAa,OACjB;CAEF,MAAM,QAAQ,WAAW,MAAM,UAAU,MAAM,QAAQ,QAAQ,KAAA;AAC/D,QAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ,KAAA;;AAGjE,SAAS,gBAAgB,OAAkC;AACzD,QAAO,MAAM,SAAS,aAAa,iBACjC,MAAM,SAAS,aAAa,YAC5B,MAAM,SAAS,aAAa;;AAGhC,SAAS,gBAAgB,QAKb;CACV,MAAM,qBAAqB,uBAAuB,OAAO,MAAM;AAC/D,KAAI,mBACF,QAAO,uBAAuB,OAAO;AAEvC,KAAI,CAAC,OAAO,aAAa,CAAC,OAAO,MAC/B,QAAO;AAET,QAAO,mBAAmB,OAAO,MAAM,KAAK,OAAO,aACjD,eAAe,OAAO,MAAM,KAAK,OAAO;;AAG5C,IAAM,kBAAN,MAAqD;CACnD,SAA+B,EAAE;CACjC,UAAuE,EAAE;CACzE,SAAiB;CACjB;CACA,aAAqB;CAErB,QAAQ,UAAmB;AACzB,MAAI,KAAK,UAAU,KAAK,WACtB;EAEF,MAAM,SAAS,KAAK,QAAQ,OAAO;AACnC,MAAI,QAAQ;AACV,UAAO;IAAE,MAAM;IAAO;IAAO,CAAC;AAC9B;;AAEF,OAAK,OAAO,KAAK,MAAM;;CAGzB,cAAoB;AAClB,MAAI,KAAK,OACP;AAEF,OAAK,SAAS;AACd,SAAO,KAAK,QAAQ,SAAS,EAC3B,MAAK,QAAQ,OAAO,GAAG;GAAE,MAAM;GAAM,OAAO,KAAA;GAAgB,CAAC;;CAIjE,QAAQ,UAAyB;AAC/B,MAAI,KAAK,UAAU,KAAK,WACtB;AAEF,OAAK,aAAa;AAClB,OAAK,UAAU;AACf,SAAO,KAAK,QAAQ,SAAS,EAC3B,MAAK,QAAQ,OAAO,GAAG;GAAE,MAAM;GAAM,OAAO,KAAA;GAAgB,CAAC;;CAIjE,OAAO,YAAwC;AAC7C,MAAI,KAAK,OAAO,SAAS,EACvB,QAAO;GACL,MAAM;GACN,OAAO,KAAK,OAAO,OAAO;GAC3B;AAEH,MAAI,KAAK,WACP,OAAM,KAAK;AAEb,MAAI,KAAK,OACP,QAAO;GACL,MAAM;GACN,OAAO,KAAA;GACR;AAEH,SAAO,MAAM,IAAI,SAA4B,YAAY;AACvD,QAAK,QAAQ,KAAK,QAAQ;IAC1B;;CAGJ,CAAC,OAAO,wBAA0C,EAChD,MAAM,KAAK,MACZ;;AAGH,IAAM,mBAAN,MAAuB;CACrB,QAAyB,IAAI,iBAAmC;CAChE;CACA;CACA;CACA,WAAmB;CACnB;CACA;CAEA,YACE,SAOA;AAPiB,OAAA,UAAA;AAQjB,OAAK,cAAc,QAAQ,SAAS,GAAG,UAAU,UAAU,KAAK,YAAY;;CAG9E,gBAAgB,WAA+B;AAC7C,OAAK,YAAY,OAAO;AACxB,OAAK,QAAQ,OAAO,SAAS,KAAA;EAC7B,MAAM,EAAE,gBAAgB,KAAK;AAC7B,MAAI,CAAC,YACH;EAEF,MAAM,cAAoB;AACnB,QAAK,QAAQ,QAAQ,OACxB;IACE,MAAM,YAAY,SAAS;IAC3B,SAAS;KACP,WAAW,OAAO;KAClB,eAAe,KAAK,QAAQ;KAC7B;IACF,EACD,EAAE,QAAQ,oBAAoB,CAC/B;;AAEH,MAAI,YAAY,SAAS;AACvB,UAAO;AACP;;AAEF,cAAY,iBAAiB,SAAS,OAAO,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAK,qBAAqB,YAAY,oBAAoB,SAAS,MAAM;;CAG3E,SAAS,mBAA2E;AAClF,aAAW,MAAM,SAAS,KAAK,MAC7B,OAAM;;CAIV,eAAe,OAAO,UAAgC,EAAE,KAA0B;AAChF,aAAW,MAAM,SAAS,KAAK,OAAO;AACpC,OAAI,MAAM,SAAS,aAAa,kBAAkB;AAChD,YAAQ,mBAAmB,MAAM,QAAQ,MAAM;AAC/C;;AAEF,OAAI,MAAM,SAAS,aAAa,kBAAkB;AAChD,SAAK,mBAAmB,MAAM,QAAQ;AACtC;;AAEF,OAAI,MAAM,SAAS,aAAa,cAC9B,OAAM,IAAI,MAAM,MAAM,QAAQ,MAAM,QAAQ;AAE9C,OAAI,MAAM,SAAS,aAAa,SAC9B,OAAM,IAAI,MAAM,MAAM,QAAQ,SAAS,QAAQ,mBAAmB,kBAAkB;AAEtF,OAAI,MAAM,SAAS,aAAa,aAAa;AAC3C,QAAI,CAAC,KAAK,iBACR,OAAM,IAAI,MACR,QAAQ,gCACN,uDACH;AAEH,WAAO,KAAK;;;AAGhB,QAAM,IAAI,MACR,QAAQ,gCACN,uDACH;;CAGH,gBAAsB;AACpB,MAAI,KAAK,SACP;AAEF,OAAK,WAAW;AAChB,OAAK,gBAAgB;AACrB,OAAK,aAAa;AAClB,OAAK,MAAM,OAAO;;CAGpB,eAAuB,UAAkC;AACvD,MAAI,KAAK,YAAY,CAAC,gBAAgB;GACpC,eAAe,KAAK,QAAQ;GAC5B;GACA,OAAO,KAAK;GACZ,WAAW,KAAK;GACjB,CAAC,CACA;AAEF,OAAK,QAAQ,UAAU,MAAM;AAC7B,OAAK,MAAM,KAAK,MAAM;AACtB,MAAI,gBAAgB,MAAM,CACxB,MAAK,MAAM,OAAO;;;AAKxB,IAAa,iBAAb,MAA4B;CAC1B,YACE,SAIA;AAJiB,OAAA,UAAA;;CAMnB,OAAO,OAAO,UAA6D;AACzE,SAAO,MAAM,KAAK,oBAAoB,OAAO,YAAY,CAAC;;CAG5D,sBAAsB,OACpB,OACA,UAAgC,EAAE,KACP;EAC3B,MAAM,gBAAgB,YAAY;EAClC,MAAM,WAAW,KAAK,gBAAgB,eAAe,QAAQ;AAC7D,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,oBAAoB,OAAO,cAAc;AACnE,YAAS,aAAa,OAAO;GAC7B,MAAM,mBAAmB,MAAM,SAAS,aAAa,QAAQ;AAC7D,UAAO;IACL;IACA;IACA,MAAM,0BAA0B,iBAAiB;IAClD;YACO;AACR,YAAS,SAAS;;;CAItB,sBAAsB,iBAEpB,OACA,UAAiC,EAAE,EACD;EAClC,MAAM,gBAAgB,YAAY;EAClC,MAAM,WAAW,KAAK,gBAAgB,eAAe,QAAQ;AAC7D,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,oBAAoB,OAAO,cAAc;AACnE,YAAS,aAAa,OAAO;AAC7B,cAAW,MAAM,SAAS,SAAS,QAAQ,CACzC,OAAM;YAEA;AACR,YAAS,SAAS;;;CAItB,mBACE,eACA,YACqB;AACrB,SAAO,IAAI,iBAAiB;GAC1B,aAAa,QAAQ;GACrB;GACA,UAAU,KAAK,QAAQ;GACvB,SAAS,KAAK,QAAQ;GACtB,SAAS,QAAQ;GAClB,CAAC;;CAGJ,sBAA8B,OAC5B,OACA,kBAC0B;AAC1B,SAAO,MAAM,KAAK,QAAQ,QAAQ,OAChC;GACE,MAAM,YAAY,SAAS;GAC3B,SAAS;IACP,GAAG;IACH;IACD;GACF,EACD,EAAE,QAAQ,oBAAoB,CAC/B;;;;;ACleL,SAAS,WAAW,OAAoC;AACtD,KAAI,OAAO,UAAU,SACnB;AAGF,QADgB,MAAM,MAAM,IACV,KAAA;;AAGpB,SAAgB,sBACd,SACgC;AAChC,QACE,QAAQ,QAAQ,IAChB,OAAQ,QAAyC,oBAAoB;;AAIzE,SAAgB,yBAAyB,QAIZ;CAC3B,MAAM,EAAE,SAAS,SAAS,UAAU;AACpC,KAAI,CAAC,sBAAsB,QAAQ,CACjC,QAAO;CAGT,MAAM,WAAW,gBAAgB,QAAQ,YAAY,EAAE,CAAC;CACxD,MAAM,YACJ,WAAW,MAAM,UAAU,IAC3B,WAAW,SAAS,UAAU,IAC9B,WAAW,SAAS,WAAW;AAEjC,QAAO;EACL,QAAQ;GACN,gBAAgB,QAAQ;GACxB,GAAI,YAAY,EAAE,WAAW,GAAG,EAAE;GAClC,GAAI,OAAO,KAAK,SAAS,CAAC,SAAS,IAAI,EAAE,UAAU,GAAG,EAAE;GACzD;EACD;EACD;;AAGH,eAAsB,0BACpB,QACe;CACf,MAAM,EACJ,aACA,gBACA,UACA,aACA,SACA,UACA,SACA,OACA,cACE;CACJ,MAAM,QAAuB;EAC3B,QAAQ;GACN,GAAG,MAAM;GACT,GAAI,UAAU,qBACV,EACE,yBACE,SAAS,oBACZ,GACD,EAAE;GACP;EACD,aAAa,eAAe,oBAAoB,MAAM,yBAAyB;GAC7E;GACA;GACA;GACA;GACA;GACD,CAAC,EAAE;GACF;GACA;GACD,CAAC;EACH;AACD,OAAM,MAAM,QAAQ,gBAAgB,MAAM;;;;ACrH5C,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,uBACP,UACyB;CACzB,MAAM,eAAe,gBAAgB,SAAS;AAC9C,MAAK,MAAM,OAAO,yBAChB,QAAO,aAAa;AAEtB,QAAO;;AAGT,SAAgB,iBAAiB,QAIL;CAC1B,MAAM,EAAE,SAAS,UAAU,UAAU;AAKrC,QAAO;EACL,GALsB,uBAAuB;GAC7C,GAAI,QAAQ,YAAY,EAAE;GAC1B,GAAI,YAAY,EAAE;GACnB,CAAC;EAGA,SAAS,QAAQ;EACjB,QAAQ,QAAQ;EAChB,WAAW,MAAM;EACjB,SAAS,MAAM;EACf,YAAY,MAAM;EAClB,UAAU,QAAQ;EACnB;;;;ACDH,SAAS,sBAAsB,OAAgB,WAAW,KAAa;CAErE,MAAM,cADM,iBAAiB,QAAQ,MAAM,WAAW,MAAM,OAAO,OAAO,SAAS,gBAAgB,EAC5E,QAAQ,QAAQ,IAAI,CAAC,MAAM;AAClD,KAAI,CAAC,WACH,QAAO;AAET,QAAO,WAAW,UAAU,WACxB,aACA,GAAG,WAAW,MAAM,GAAG,KAAK,IAAI,GAAG,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC;;AAGlE,IAAa,0BAAb,MAAqC;CACnC,YAAY,SAA4C;AAApC,OAAA,UAAA;;CAEpB,UAAU,OAAO,YAA2C;AAC1D,MAAI;GACF,MAAM,QAAQ,KAAK,aAAa,QAAQ;GACxC,MAAM,cAAc,iBAAiB;IACnC;IACA;IACD,CAAC;AACF,OAAI,MAAM,KAAK,0BAA0B,SAAS,OAAO,YAAY,CACnE;AAEF,OAAI,MAAM,KAAK,+BAA+B,SAAS,OAAO,YAAY,CACxE;AAEF,OAAI,QAAQ,YAAY,SACtB,OAAM,KAAK,QAAQ,WAAW,gBAC5B,yCAAyC,QAAQ,CAClD;GAEH,MAAM,SAAS,MAAM,KAAK,QAAQ,eAAe,oBAAoB,MAAM,yBAAyB;IAClG,WAAW,MAAM;IACjB,SAAS,QAAQ;IACjB,aAAa,QAAQ;IACrB,UAAU;IACV,UAAU,KAAK,QAAQ,OAAO;IAC/B,CAAC,EAAE;IACF,kBACE,QAAQ,YAAY,YACf,UAAU;AACT,SAAI,CAAC,MACH;AAEG,UAAK,QAAQ,WAAW,gBAC3B,yCAAyC,SAAS,MAAM,CACzD;QAEH,KAAA;IACN,8BAA8B,YAAY,MAAM,WAAW;IAC3D,iBAAiB,YAAY,MAAM,WAAW;IAC/C,CAAC;AACF,SAAM,KAAK,mBAAmB,SAAS,OAAO,OAAO;WAC9C,OAAO;AACd,SAAM,KAAK,QAAQ,WAAW,gBAAgB;IAC5C,SAAS,QAAQ;IACjB,QAAQ,QAAQ;IAChB,SAAS,kCAAkC,sBAAsB,MAAM;IACvE,OAAO,EAAE;IACT,UAAU,EAAE;IACb,CAAC;;;CAIN,gBAAwB,YAA0C;EAChE,MAAM,aAAa,UACjB,OAAO,UAAU,WAAW,MAAM,MAAM,IAAI,KAAA,IAAY,KAAA;AAC1D,SAAO,IAAI,mBAAmB,KAAK,QAAQ,cAAc,YAAY,CAAC,CAAC,eAAe;GACpF;GACA,eAAe,UAAU,QAAQ,SAAS,gBAAgB;GAC1D,oBAAoB,UAAU,QAAQ,SAAS,qBAAqB;GACrE,CAAC;;CAGJ,4BAAoC,OAClC,SACA,OACA,gBACqB;AACrB,MAAI,QAAQ,YAAY,SACtB,QAAO;EAET,MAAM,UAAU,QAAQ,QAAQ,MAAM;AACtC,MAAI,CAAC,QAAQ,WAAW,IAAI,CAC1B,QAAO;EAMT,MAAM,SAAS,MAJE,IAAI,gBACnB,KAAK,QAAQ,cAAc,YAAY,EACvC,KAAK,QAAQ,eACd,CAC6B,YAAY,SAAS;GACjD,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,UAAU,QAAQ;GAClB,YAAY,MAAM;GACnB,CAAC;AACF,MAAI,CAAC,OACH,QAAO;AAET,QAAM,KAAK,QAAQ,WAAW,gBAAgB;GAC5C,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,SAAS,OAAO;GAChB,OAAO,EAAE;GACT,UAAU;GACX,CAAC;AACF,SAAO;;CAGT,iCAAyC,OACvC,SACA,OACA,gBACqB;AACrB,MAAI,QAAQ,YAAY,SACtB,QAAO;EAGT,MAAM,aAAa,yBAAyB;GAC1C,SAAS,KAAK,QAAQ,OAAO,SAAS,WAAW,QAAQ,QAAQ;GACjE;GACA;GACD,CAAC;AACF,MAAI,CAAC,WACH,QAAO;AAGT,QAAM,0BAA0B;GAC9B,gBAAgB,KAAK,QAAQ;GAC7B,UAAU,KAAK,QAAQ,OAAO;GAC9B,OAAO;GACP,WAAW,MAAM;GACjB,SAAS,QAAQ;GACjB,aAAa,QAAQ;GACrB,UAAU;GACX,CAAC;AACF,SAAO;;CAGT,qBAA6B,OAC3B,SACA,OACA,WACkB;AAClB,MAAI,QAAQ,YAAY,UAAU;AAChC,QAAK,QAAQ,aAAa,KAAK,UAAU,gBAAgB,EAAE,YAAY,MAAM,YAAY,EAAE;IACzF,4BAAW,IAAI,MAAM,EAAC,aAAa;IACnC,QAAQ;IACT,CAAC;AACF;;AAIF,MAAI,CADc,OAAO,KAAK,MAAM,EACpB;AACd,SAAM,KAAK,QAAQ,WAAW,gBAC5B,+BAA+B,QAAQ,CACxC;AACD;;AAGF,QAAM,KAAK,QAAQ,WAAW,gBAAgB;GAC5C,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,SAAS,OAAO;GAChB,OAAO,EAAE;GACT,UAAU,iBAAiB;IACzB;IACA;IACA,UAAU,OAAO,iBAAiB;IACnC,CAAC;GACH,CAAC;;;AAIN,eAAsB,sBACpB,SACe;CACf,MAAM,YAAY,IAAI,wBAAwB,QAAQ;AACtD,QAAO,KACL,OAAM,UAAU,QAAQ,MAAM,QAAQ,WAAW,gBAAgB,CAAC;;;;AClMtE,SAASC,0BAAwB,OAAoC;AACnE,KAAI,OAAO,UAAU,SACnB;AAGF,QADgB,MAAM,MAAM,IACV,KAAA;;AAGpB,SAAS,2BAA2B,QAMjB;CACjB,MAAM,EAAE,aAAa,SAAS,QAAQ,SAAS,aAAa;AAC5D,QAAO;EACL,SAAS,WAAW;EACpB,UAAU;EACV,QAAQ,UAAU;EAClB;EACA,2BAAW,IAAI,MAAM;EACrB,aAAa,eAAe,EAAE;EAC9B,UAAU,gBAAgB,YAAY,EAAE,CAAC;EAC1C;;AAGH,eAAe,yBAAyB,QAMb;CACzB,MAAM,EAAE,SAAS,QAAQ,QAAQ,YAAY,eAAe;AAE5D,KAAI,CADY,WAAW,MAAM,CACpB,WAAW,IAAI,CAC1B,QAAO;AAST,SANe,MADE,IAAI,gBAAgB,OAAO,CACd,YAAY,YAAY;EACpD;EACA;EACA,UAAU;EACV;EACD,CAAC,GACa,WAAW;;AAG5B,SAAS,mBAAmB,QAY1B;CACA,MAAM,EAAE,SAAS,QAAQ,eAAe;CACxC,MAAM,UAAU,2BAA2B,OAAO;CAClD,MAAM,gBACJA,0BAAwB,QAAQ,IAChC,2BAA2B,WAAW,EAAE,WACxC,KAAA;AAOF,QAAO;EACL;EACA,OARoB,IAAI,mBAAmB,OAAO,CACxB,eAAe;GACzC;GACA;GACA,oBAAoB;GACrB,CAAC;EAID;;AAGH,eAAsB,sBACpB,QACiB;CACjB,MAAM,EACJ,aACA,SACA,aACA,SACA,QACA,QACA,SACA,UACA,kBACA,gBACA,eACE;CACJ,MAAM,EAAE,SAAS,UAAU,mBAAmB;EAC5C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CACF,MAAM,gBAAgB,MAAM,yBAAyB;EACnD;EACA,YAAY;EACZ,SAAS,QAAQ;EACjB,QAAQ,QAAQ;EAChB,YAAY,MAAM;EACnB,CAAC;AACF,KAAI,cACF,QAAO;AAiBT,SAde,MAAM,eAAe,oBAAoB,MAAM,yBAAyB;EACrF,WAAW,MAAM;EACjB;EACA;EACA,UAAU,iBAAiB;GACzB;GACA;GACD,CAAC;EACH,CAAC,EAAE;EACF;EACA;EACA,8BAA8B,YAAY,MAAM,WAAW;EAC3D,iBAAiB,YAAY,MAAM,WAAW;EAC/C,CAAC,EACY;;;;AC9IhB,SAAS,aAAa,OAAwB;AAC5C,KAAI;AACF,SAAO,KAAK,MAAM,MAAM;SAClB;AACN,SAAO;;;AAIX,SAAS,WAAW,MAAqC;AACvD,QAAO,KAAK,SAAS,IAAI;EAAE,MAAM;EAAQ;EAAM,GAAG;;AAGpD,SAAS,eAAe,SAAoC;AAC1D,KAAI,OAAO,YAAY,UAAU;EAC/B,MAAM,WAAW,WAAW,QAAQ;AACpC,SAAO,WAAW,CAAC,SAAS,GAAG,EAAE;;AAEnC,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,QAAQ,SAAS,IACpB,CACE;EACE,MAAM;EACN,eAAe;EACf,MAAM,gBAAgB,QAAQ;EAC/B,CACF,GACD,EAAE;AAER,KAAI,WAAW,OAAO,YAAY,SAChC,QAAO,CACL;EACE,MAAM;EACN,eAAe;EACf,MAAM,gBAAgB,QAAQ;EAC/B,CACF;AAEH,QAAO,EAAE;;AAGX,SAAS,2BAA2B,OAAyB;AAC3D,KAAI,OAAO,UAAU,SACnB,QAAO,gBAAgB,MAAM;CAE/B,MAAM,UAAU,MAAM,MAAM;AAC5B,KAAI,CAAC,QACH,QAAO;AAET,KAAI,CAAC,QAAQ,WAAW,IAAI,IAAI,CAAC,QAAQ,WAAW,IAAI,CACtD,QAAO;AAET,QAAO,aAAa,QAAQ;;AAG9B,SAAS,qBAAqB,OAAkC;AAC9D,KAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,QAAO,EAAE;AAEX,QAAO,MACJ,KAAK,UAAU;AACd,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;EAET,MAAM,WAAW;EACjB,MAAM,KAAKC,kBAAgB,SAAS,GAAG;EACvC,MAAM,cAAc,SAAS;AAC7B,MAAI,CAAC,MAAM,CAAC,eAAe,OAAO,gBAAgB,YAAY,MAAM,QAAQ,YAAY,CACtF,QAAO;EAET,MAAM,KAAK;EACX,MAAM,OAAOA,kBAAgB,GAAG,KAAK;EACrC,MAAM,OAAO,OAAO,GAAG,cAAc,WAAW,GAAG,YAAY,KAAK,UAAU,GAAG,aAAa,EAAE,CAAC;AACjG,MAAI,CAAC,KACH,QAAO;AAET,SAAO;GACL;GACA,MAAM;GACN,UAAU;IACR;IACA,WAAW;IACZ;GACF;GACD,CACD,QAAQ,UAAmC,UAAU,KAAK;;AAG/D,SAAS,gBAAgB,WAAmB,OAAe,MAAc,WAA2B;AAClG,QAAO,GAAG,UAAU,GAAG,KAAK,MAAM,CAAC,aAAa,IAAI,UAAU,GAAG,MAAM,GAAG;;AAG5E,SAAS,iBAAiB,QAMf;CACT,MAAM,EAAE,OAAO,SAAS,MAAM,WAAW,cAAc;AACvD,QAAOA,kBAAgB,QAAQ,eAAe,IAC5C,gBAAgB,WAAW,OAAO,MAAM,UAAU;;AAGtD,SAAS,iBAAiB,OAAyC;AACjE,QAAO,QAAQ,MAAM,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,IAAI,OAAQ,MAA6B,SAAS;;AAG/H,SAAS,mBAAmB,SAAkD;CAC5E,MAAM,WAAW,QAAQ;AACzB,KAAI,CAAC,MAAM,QAAQ,SAAS,CAC1B,QAAO;CAET,MAAM,QAAQ,SAAS,QAAQ,SAAiC,iBAAiB,KAAK,CAAC;AACvF,KAAI,MAAM,WAAW,SAAS,OAC5B,QAAO;AAET,QAAO,gBAAgB,MAAM;;AAG/B,SAAS,sBAAsB,SAA8D;CAC3F,MAAM,cAAc,QAAQ;AAC5B,KAAI,CAAC,eAAe,OAAO,gBAAgB,YAAY,MAAM,QAAQ,YAAY,CAC/E;AAEF,QAAO,gBAAgB,YAAuC;;AAGhE,SAAS,sBAAsB,QAAmF;CAChH,MAAM,EAAE,OAAO,SAAS,cAAc;CACtC,MAAM,YAAY,mBAAmB,QAAQ,4BAAW,IAAI,MAAM,EAAC,aAAa,CAAC;CACjF,MAAM,UACJ,OAAO,QAAQ,aAAa,YAAY,QAAQ,SAAS,MAAM,CAAC,SAAS,IACrE,QAAQ,SAAS,MAAM,GACvB,KAAA;CACN,MAAM,cAAc,mBAAmB,QAAQ;AAC/C,KAAI,YACF,QAAO,2BAA2B;EAChC,IAAI,iBAAiB;GAAE;GAAO;GAAS,MAAM;GAAa;GAAW;GAAW,CAAC;EACjF;EACA,MAAM;EACN,QAAQ;EACR;EACA,OAAO;EACP,UAAU,UAAU,EAAE,UAAU,SAAS,GAAG,KAAA;EAC7C,CAAC;CAGJ,MAAM,YAAY,qBAAqB,QAAQ,WAAW;CAC1D,MAAM,QAA0B,CAAC,GAAG,eAAe,QAAQ,QAAQ,CAAC;AACpE,KAAI,OAAO,QAAQ,sBAAsB,SACvC,OAAM,KAAK;EACT,MAAM;EACN,MAAM,QAAQ;EACf,CAAC;AAGJ,MAAK,MAAM,YAAY,UACrB,OAAM,KAAK;EACT,MAAM;EACN,YAAY,SAAS;EACrB,UAAU,SAAS,SAAS;EAC5B,OAAO;EACP,MAAM,aAAa,SAAS,SAAS,UAAU;EAChD,CAAC;AAGJ,QAAO,2BAA2B;EAChC,IAAI,iBAAiB;GAAE;GAAO;GAAS,MAAM;GAAa;GAAW;GAAW,CAAC;EACjF;EACA,MAAM;EACN,QAAQ;EACR;EACA;EACA,UAAU,UAAU,EAAE,UAAU,SAAS,GAAG,KAAA;EAC7C,CAAC;;AAGJ,SAAS,oBACP,QACY;CACZ,MAAM,EAAE,OAAO,SAAS,MAAM,cAAc;CAC5C,MAAM,YAAY,mBAAmB,QAAQ,4BAAW,IAAI,MAAM,EAAC,aAAa,CAAC;CACjF,MAAM,cAAc,mBAAmB,QAAQ;CAC/C,MAAM,iBAAiB,sBAAsB,QAAQ;AACrD,KAAI,YACF,QAAO;EACL,IAAI,iBAAiB;GAAE;GAAO;GAAS;GAAM;GAAW;GAAW,CAAC;EACpE;EACA;EACA,QAAQ;EACR;EACA,OAAO;EACP,GAAI,iBAAiB,EAAE,UAAU,gBAAgB,GAAG,EAAE;EACvD;AAEH,QAAO;EACL,IAAI,iBAAiB;GAAE;GAAO;GAAS;GAAM;GAAW;GAAW,CAAC;EACpE;EACA;EACA,QAAQ;EACR;EACA,OAAO,eAAe,QAAQ,QAAQ;EACtC,GAAI,iBAAiB,EAAE,UAAU,gBAAgB,GAAG,EAAE;EACvD;;AAGH,SAAS,iBACP,QACA,YACA,QACA,UACA,oBACY;CACZ,MAAM,mBAAmB,2BAA2B,OAAO;CAC3D,MAAM,yBAAyB,MAAM,QAAQ,mBAAmB,GAC5D,gBAAgB,mBAAmB,GACnC,KAAA;AACJ,QAAO;EACL,GAAG;EACH,OAAO,OAAO,MAAM,KAAK,SAAS;AAChC,OAAI,KAAK,SAAS,qBAAqB,KAAK,eAAe,WACzD,QAAO;AAIT,OADE,KAAK,UAAU,YAAY,OAAO,UAAU,eAAe,KAAK,MAAM,SAAS,CAE/E,QAAO;IACL,GAAG;IACH,GAAI,WAAW,EAAE,UAAU,GAAG,EAAE;IACjC;AAEH,UAAO;IACL,GAAG;IACH,UAAU,YAAY,KAAK;IAC3B,OAAO;IACP,QAAQ;IACR,GAAI,yBAAyB,EAAE,oBAAoB,wBAAwB,GAAG,EAAE;IACjF;IACD;EACH;;AAGH,SAAgB,cAAc,WAAmB,UAA0C;CACzF,MAAM,cAA4B,EAAE;CACpC,MAAM,6CAA6B,IAAI,KAAqB;AAE5D,UAAS,SAAS,SAAS,UAAU;EACnC,MAAM,OAAOA,kBAAgB,QAAQ,KAAK,EAAE,aAAa,IAAI;AAC7D,MAAI,SAAS,QAAQ;GACnB,MAAM,aAAaA,kBAAgB,QAAQ,aAAa;AACxD,OAAI,YAAY;IACd,MAAM,iBAAiB,2BAA2B,IAAI,WAAW;AACjE,QAAI,mBAAmB,KAAA,GAAW;AAChC,iBAAY,kBAAkB,iBAC5B,YAAY,iBACZ,YACA,gBAAgB,QAAQ,QAAQ,EAChCA,kBAAgB,QAAQ,KAAK,IAAI,KAAA,GACjC,QAAQ,8BACT;AACD;;;AAGJ,eAAY,KACV,oBAAoB;IAClB;IACA;IACA,MAAM;IACN;IACD,CAAC,CACH;AACD;;AAGF,MAAI,SAAS,aAAa;GACxB,MAAM,YAAY,sBAAsB;IAAE;IAAW;IAAO;IAAS,CAAC;GACtE,MAAM,oBAAoB,YAAY,KAAK,UAAU,GAAG;AACxD,QAAK,MAAM,QAAQ,UAAU,MAC3B,KAAI,KAAK,SAAS,qBAAqB,KAAK,WAC1C,4BAA2B,IAAI,KAAK,YAAY,kBAAkB;AAGtE;;EAGF,MAAM,iBAAkB,SAAS,YAAY,SAAS,UAAU,SAAS,YAAY,OAAO;AAC5F,cAAY,KACV,oBAAoB;GAClB;GACA;GACA,MAAM;GACN;GACD,CAAC,CACH;GACD;AAEF,QAAO;;AAGT,SAAgB,uBAAuB,SAAiC;CACtE,MAAM,OAAOA,kBAAgB,QAAQ,KAAK,EAAE,aAAa,IAAI;AAC7D,KAAI,SAAS,eAAe,MAAM,QAAQ,QAAQ,WAAW,IAAI,QAAQ,WAAW,SAAS,EAC3F,QAAO;AAET,KAAI,SAAS,OACX,QAAO;AAET,KAAI,SAAS,YACX,QAAO;AAET,KAAI,SAAS,OACX,QAAO;AAET,KAAI,SAAS,SACX,QAAO;AAET,QAAO,WAAW,QAAQ"}