@nextclaw/kernel 0.3.3 → 0.3.4-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.d.ts +42 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +866 -553
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["normalizeString","readRequestedAgentId","normalizeString","readOptionalString","readString","readStringArray","readRecord","readString","readRecord","readRequiredString","isRecord","isRecord","readOptionalString","readOptionalString","readEventSessionId","EMPTY_GRANTS","normalizeStoreData","isMissingFileError","isRecord","isRecord","readOptionalString","readRequiredString","readStringArray","isMissingFileError","isRecord","isRecord","isRecord","readRequiredString","readOptionalString","readOptionalBoolean","readString","parseYaml","isRecord","isRecord","isRecord","readRecord","readString","fsConstants","readOptionalString","readString","isRecord","readOptionalString","normalizeString","readString","readRequiredString","readOptionalString","isRecord","normalizeString","readOptionalString","ChannelManager","normalizeOptionalString","normalizeOptionalString","normalizeString"],"sources":["../src/managers/agent.manager.ts","../src/utils/ncp-message-bridge.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/agent-run-context-compaction.manager.ts","../src/managers/agent-run-request.manager.ts","../src/configs/agent-runtime.config.ts","../src/managers/agent-runtime.manager.ts","../src/utils/access-token.utils.ts","../src/stores/access-session.store.ts","../src/utils/access-password.utils.ts","../src/managers/access.manager.ts","../src/managers/automation.manager.ts","../src/managers/config.manager.ts","../src/managers/context-provider.manager.ts","../src/services/command-registry.service.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/types/llm-usage.types.ts","../src/stores/llm-usage.store.ts","../src/managers/llm-usage.manager.ts","../src/managers/mcp.manager.ts","../src/utils/ncp-agent-session-journal.utils.ts","../src/utils/agent-peer-session.utils.ts","../src/managers/session.manager.ts","../src/types/panel-app.types.ts","../src/services/panel-app-asset-token.service.ts","../src/stores/panel-app-state.store.ts","../src/stores/panel-app-capability-grant.store.ts","../src/services/agent-run-client.service.ts","../src/utils/panel-app-bridge.utils.ts","../src/utils/panel-app-manifest.utils.ts","../src/utils/panel-app-source.utils.ts","../src/services/panel-app-source.service.ts","../src/utils/panel-app-time.utils.ts","../src/tools/structured-result.tools.ts","../src/utils/panel-app-agent.utils.ts","../src/managers/panel-app.manager.ts","../src/utils/service-action.utils.ts","../src/services/mcp-service-app-runtime.service.ts","../src/stores/service-action-grant.store.ts","../src/utils/service-app-manifest.utils.ts","../src/utils/service-app-runtime-action.utils.ts","../src/managers/service-app.manager.ts","../src/managers/session-run.manager.ts","../src/utils/skill-frontmatter.utils.ts","../src/managers/skill.manager.ts","../src/managers/tool-provider.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/features/native-runtime/services/provider-manager-ncp-llm-api.service.ts","../src/features/native-runtime/tools/ncp-asset.tools.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/runtime-registry/services/agent-runtime-registry.service.ts","../src/services/agent-run-message-projector.service.ts","../src/services/agent-run-model-input-budgeter.service.ts","../src/services/agent-run-model-input-builder.service.ts","../src/services/ncp-agent-runtime-wrapper.service.ts","../src/contributions/agent-run-runtime/index.ts","../src/utils/agent-run-request-metadata.utils.ts","../src/contributions/context-provider/providers/kernel-context.provider.ts","../src/contributions/context-provider/index.ts","../src/contributions/context-window/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/contributions/tool-provider/providers/asset-tool.provider.ts","../src/contributions/tool-provider/utils/tool-provider-run-context.utils.ts","../src/contributions/tool-provider/providers/core-tool.provider.ts","../src/contributions/tool-provider/providers/mcp-tool.provider.ts","../src/contributions/tool-provider/providers/messaging-tool.provider.ts","../src/tools/session-history.tools.ts","../src/tools/session-request.tools.ts","../src/tools/session-search.tools.ts","../src/tools/session-spawn.tools.ts","../src/contributions/tool-provider/providers/session-tool.provider.ts","../src/contributions/tool-provider/providers/structured-result-tool.provider.ts","../src/contributions/tool-provider/index.ts","../src/app/nextclaw-kernel.ts","../src/utils/agent-run-send-payload.utils.ts","../src/features/ncp-dispatch/utils/channel-reply.utils.ts","../src/utils/agent-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 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 { 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 { type NcpMessage } from \"@nextclaw/ncp\";\nimport { ContextCompactionPreflightService } 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","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 type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.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 sessionManager: SessionManager,\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.sessionManager.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 { catchError, from, lastValueFrom, tap } from \"rxjs\";\nimport { resolveDefaultAgentProfileId } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { AgentRuntimeManager } from \"./agent-runtime.manager.js\";\nimport type { ContextProviderManager } from \"./context-provider.manager.js\";\nimport type { SessionRunManager } from \"./session-run.manager.js\";\nimport type { ToolProviderManager } from \"./tool-provider.manager.js\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.js\";\nimport type {\n AgentRunAbortRequest,\n AgentRunAccepted,\n AgentRunRequest,\n AgentRunSpec,\n} from \"@kernel/types/agent-run.types.js\";\n\nfunction toAgentRunRequest(\n envelope: AgentRunSendIngressPayload,\n): AgentRunRequest {\n const metadata = envelope.metadata ?? {};\n const peerId = readOptionalString(envelope.peerId);\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 const sessionId = readOptionalString(envelope.sessionId);\n if (sessionId && peerId) {\n throw new Error(\"agent-run.send cannot accept both sessionId and peerId.\");\n }\n return {\n ...requestMetadata,\n sessionId,\n peerId,\n message: {\n sessionId: 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 envelopeSessionId = readOptionalString(envelope.sessionId);\n const messageSessionId = readOptionalString(sourceMessage.sessionId);\n const sessionId = envelopeSessionId ?? messageSessionId;\n if (sessionId && peerId) {\n throw new Error(\"agent-run.send cannot accept both sessionId and peerId.\");\n }\n const message: NcpMessage = {\n ...sourceMessage,\n sessionId: 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,\n peerId,\n message,\n };\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 toSessionMessageRequest(\n payload: AgentRunSessionMessageRequestPayload,\n): 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(\n messages: readonly NcpMessage[],\n messageId?: string,\n): NcpMessage | null {\n return (\n [...messages]\n .reverse()\n .find(\n (message) =>\n message.role === \"assistant\" &&\n message.status === \"final\" &&\n (!messageId || message.id === messageId),\n ) ?? null\n );\n}\n\nfunction readMessageTask(message: NcpMessage): string {\n return (\n message.parts.flatMap((part) =>\n (part.type === \"text\" ||\n part.type === \"rich-text\" ||\n part.type === \"reasoning\") &&\n part.text.trim()\n ? [part.text.trim()]\n : [],\n )[0] ?? \"Session\"\n );\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 sessionManager: SessionManager,\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(\n ingressKeys.agentRun.send,\n this.handleSendRequest,\n ),\n this.ingress.addHandler(\n ingressKeys.agentRun.abort,\n this.handleAbortRequest,\n ),\n this.ingress.addHandler(\n ingressKeys.agentRun.sessionMessageRequest,\n this.handleSessionMessageRequest,\n ),\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(\n await this.send(toSessionMessageRequest(envelope.payload)),\n );\n };\n\n private send = async (\n request: AgentRunRequest,\n ): Promise<AgentRunAccepted> => {\n const session = await this.sessionManager.getOrCreateAgentRunSession({\n sessionId: request.sessionId,\n peerId: request.peerId,\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 =\n request.model ?? session.model ?? this.configManager.getDefaultModel();\n const agentId =\n request.agentId ??\n session.agentId ??\n resolveDefaultAgentProfileId(this.configManager.loadConfig());\n const spec: AgentRunSpec = {\n runId: activeRun.runId,\n agentId,\n model,\n maxTokens:\n 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 =\n await this.contextProviderManager.buildContext(providerRequest);\n const tools = await this.toolProviderManager.buildTools(providerRequest);\n let messageCompletedSeen = false;\n lastValueFrom(\n from(\n runtime.run(spec, {\n contextBlocks,\n sessionRun,\n signal: activeRun.signal,\n tools,\n }),\n ).pipe(\n tap((event) => {\n const eventsToPublish: NcpEndpointEvent[] = [];\n if (event.type === NcpEventType.MessageCompleted) {\n messageCompletedSeen = true;\n }\n if (\n event.type === NcpEventType.RunFinished &&\n !messageCompletedSeen\n ) {\n const message = findCompletedAssistantMessage(\n sessionRun.getSnapshot().messages,\n event.payload.messageId,\n );\n if (!message) {\n throw new Error(\n `Run finished without a final assistant message for session \"${session.sessionId}\".`,\n );\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","export const DEFAULT_AGENT_RUNTIME_ENTRY_ID = \"native\";\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/types/agent-run.types.js\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport type { AgentRunSession } from \"@kernel/types/session.types.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 { createHash, randomBytes } from \"node:crypto\";\n\nexport function createAccessSessionToken(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\nexport function hashAccessSessionToken(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"hex\");\n}\n\n","import type {\n AccessPrincipal,\n AccessSessionRecord,\n AccessSessionState,\n} from \"@kernel/types/access.types.js\";\nimport { hashAccessSessionToken } from \"@kernel/utils/access-token.utils.js\";\nimport { existsSync, chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst ACCESS_SESSION_STATE_VERSION = 1;\nconst ACCESS_SESSION_STATE_KIND = \"nextclaw.access.sessions\";\n\nfunction createEmptyState(): AccessSessionState {\n return {\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: [],\n };\n}\n\nfunction isAccessPrincipal(value: unknown): value is AccessPrincipal {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const record = value as { id?: unknown; role?: unknown };\n return typeof record.id === \"string\" && record.id.trim().length > 0 && record.role === \"admin\";\n}\n\nfunction parseAccessSessionRecord(value: unknown): AccessSessionRecord | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n const record = value as {\n tokenHash?: unknown;\n principal?: unknown;\n createdAt?: unknown;\n expiresAt?: unknown;\n };\n if (\n typeof record.tokenHash !== \"string\" ||\n !record.tokenHash.trim() ||\n !isAccessPrincipal(record.principal) ||\n typeof record.createdAt !== \"string\" ||\n typeof record.expiresAt !== \"string\"\n ) {\n return null;\n }\n return {\n tokenHash: record.tokenHash,\n principal: record.principal,\n createdAt: record.createdAt,\n expiresAt: record.expiresAt,\n };\n}\n\nfunction parseAccessSessionState(value: unknown): AccessSessionState {\n if (!value || typeof value !== \"object\") {\n return createEmptyState();\n }\n const record = value as { version?: unknown; sessions?: unknown };\n if (\n (record as { kind?: unknown }).kind !== ACCESS_SESSION_STATE_KIND ||\n record.version !== ACCESS_SESSION_STATE_VERSION ||\n !Array.isArray(record.sessions)\n ) {\n return createEmptyState();\n }\n return {\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: record.sessions\n .map(parseAccessSessionRecord)\n .filter((session): session is AccessSessionRecord => session !== null),\n };\n}\n\nfunction isSessionActive(session: AccessSessionRecord, nowMs: number): boolean {\n const expiresAtMs = Date.parse(session.expiresAt);\n return Number.isFinite(expiresAtMs) && expiresAtMs > nowMs;\n}\n\nexport class AccessSessionStore {\n constructor(private readonly storePath: string) {}\n\n findPrincipalByToken = (token: string | null | undefined, now: Date): AccessPrincipal | null => {\n const normalizedToken = token?.trim();\n if (!normalizedToken) {\n return null;\n }\n const tokenHash = hashAccessSessionToken(normalizedToken);\n const nowMs = now.getTime();\n const session = this.readState().sessions.find(\n (entry) => entry.tokenHash === tokenHash && isSessionActive(entry, nowMs),\n );\n return session?.principal ?? null;\n };\n\n saveSession = (session: AccessSessionRecord, now: Date): void => {\n const activeSessions = this.readState().sessions.filter(\n (entry) => entry.tokenHash !== session.tokenHash && isSessionActive(entry, now.getTime()),\n );\n this.writeState({\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: [...activeSessions, session],\n });\n };\n\n deleteToken = (token: string | null | undefined): void => {\n const normalizedToken = token?.trim();\n if (!normalizedToken) {\n return;\n }\n const tokenHash = hashAccessSessionToken(normalizedToken);\n this.writeState({\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: this.readState().sessions.filter((session) => session.tokenHash !== tokenHash),\n });\n };\n\n clear = (): void => {\n this.writeState(createEmptyState());\n };\n\n private readState = (): AccessSessionState => {\n if (!existsSync(this.storePath)) {\n return createEmptyState();\n }\n try {\n return parseAccessSessionState(JSON.parse(readFileSync(this.storePath, \"utf-8\")));\n } catch {\n return createEmptyState();\n }\n };\n\n private writeState = (state: AccessSessionState): void => {\n mkdirSync(dirname(this.storePath), { recursive: true });\n const temporaryPath = `${this.storePath}.${process.pid}.tmp`;\n writeFileSync(temporaryPath, JSON.stringify(state, null, 2), { mode: 0o600 });\n renameSync(temporaryPath, this.storePath);\n chmodSync(this.storePath, 0o600);\n };\n}\n","import { randomBytes, scryptSync, timingSafeEqual } from \"node:crypto\";\n\nexport function createAccessPasswordRecord(password: string): { passwordHash: string; passwordSalt: string } {\n const passwordSalt = randomBytes(16).toString(\"hex\");\n return {\n passwordHash: scryptAccessPassword(password, passwordSalt),\n passwordSalt,\n };\n}\n\nexport function verifyAccessPassword(password: string, expectedHash: string, salt: string): boolean {\n const actualHashBuffer = Buffer.from(scryptAccessPassword(password, salt), \"hex\");\n const expectedHashBuffer = Buffer.from(expectedHash, \"hex\");\n if (actualHashBuffer.length !== expectedHashBuffer.length) {\n return false;\n }\n return timingSafeEqual(actualHashBuffer, expectedHashBuffer);\n}\n\nfunction scryptAccessPassword(password: string, salt: string): string {\n return scryptSync(password, salt, 64).toString(\"hex\");\n}\n\n","import { ConfigSchema, getConfigPath, getDataDir, loadConfig, saveConfig, type Config } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { AccessSessionStore } from \"@kernel/stores/access-session.store.js\";\nimport type {\n AccessLoginResult,\n AccessPasswordStatus,\n AccessPrincipal,\n AccessSessionRecord,\n} from \"@kernel/types/access.types.js\";\nimport { createAccessPasswordRecord, verifyAccessPassword } from \"@kernel/utils/access-password.utils.js\";\nimport { createAccessSessionToken, hashAccessSessionToken } from \"@kernel/utils/access-token.utils.js\";\nimport { dirname, resolve } from \"node:path\";\n\nconst PASSWORD_MIN_LENGTH = 8;\nconst DEFAULT_ACCESS_SESSION_TTL_MS = 30 * 24 * 60 * 60 * 1000;\n\ntype AccessAuthConfig = Config[\"ui\"][\"auth\"];\n\nexport type AccessManagerOptions = {\n configManager?: ConfigManager;\n configPath?: string;\n homeDir?: string;\n sessionStorePath?: string;\n sessionTtlMs?: number;\n now?: () => Date;\n};\n\nfunction normalizeUsername(value: string): string {\n return value.trim();\n}\n\nfunction validateUsernameAndPassword(username: string, password: string): void {\n if (!username) {\n throw new Error(\"Username is required.\");\n }\n if (password.trim().length < PASSWORD_MIN_LENGTH) {\n throw new Error(`Password must be at least ${PASSWORD_MIN_LENGTH} characters.`);\n }\n}\n\nfunction resolveAccessSessionStorePath(options: AccessManagerOptions): string {\n const { configPath, homeDir, sessionStorePath } = options;\n if (sessionStorePath?.trim()) {\n return sessionStorePath.trim();\n }\n if (homeDir?.trim()) {\n return resolve(homeDir.trim(), \"access\", \"access-sessions.json\");\n }\n if (configPath?.trim()) {\n return resolve(dirname(configPath.trim()), \"access\", \"access-sessions.json\");\n }\n return resolve(getDataDir(), \"access\", \"access-sessions.json\");\n}\n\nexport class AccessManager {\n readonly sessions: AccessSessionStore;\n private readonly configPath: string;\n private readonly sessionTtlMs: number;\n private readonly now: () => Date;\n\n constructor(private readonly options: AccessManagerOptions = {}) {\n this.configPath = options.configManager?.configPath ?? options.configPath ?? getConfigPath();\n this.sessions = new AccessSessionStore(resolveAccessSessionStorePath({\n ...options,\n configPath: this.configPath,\n }));\n this.sessionTtlMs = Math.max(1, Math.trunc(options.sessionTtlMs ?? DEFAULT_ACCESS_SESSION_TTL_MS));\n this.now = options.now ?? (() => new Date());\n }\n\n isPasswordProtectionEnabled = (): boolean => {\n const auth = this.readAuthConfig();\n return Boolean(auth.enabled && this.isConfigured(auth));\n };\n\n authenticateSession = (token: string | null | undefined): AccessPrincipal | null => {\n const auth = this.readAuthConfig();\n if (!auth.enabled || !this.isConfigured(auth)) {\n return { id: \"admin\", role: \"admin\" };\n }\n return this.sessions.findPrincipalByToken(token, this.now());\n };\n\n getPasswordAuthStatus = (token: string | null | undefined): AccessPasswordStatus => {\n const auth = this.readAuthConfig();\n const configured = this.isConfigured(auth);\n const enabled = Boolean(auth.enabled && configured);\n const username = configured ? normalizeUsername(auth.username) : undefined;\n return {\n enabled,\n configured,\n authenticated: enabled ? this.sessions.findPrincipalByToken(token, this.now()) !== null : false,\n username,\n };\n };\n\n setupPasswordAdmin = async (input: { username: string; password: string }): Promise<AccessLoginResult> => {\n const config = this.loadCurrentConfig();\n const currentAuth = config.ui.auth;\n if (this.isConfigured(currentAuth)) {\n throw new Error(\"UI authentication is already configured.\");\n }\n\n const username = normalizeUsername(input.username);\n validateUsernameAndPassword(username, input.password);\n\n const nextPassword = createAccessPasswordRecord(input.password);\n config.ui.auth = {\n enabled: true,\n username,\n passwordHash: nextPassword.passwordHash,\n passwordSalt: nextPassword.passwordSalt,\n };\n await this.saveCurrentConfig(config, \"setup password access\");\n\n this.sessions.clear();\n return this.createLoginResult(username, true);\n };\n\n loginWithPassword = (input: { username: string; password: string }): AccessLoginResult => {\n const auth = this.readAuthConfig();\n if (!auth.enabled || !this.isConfigured(auth)) {\n throw new Error(\"UI authentication is not enabled.\");\n }\n\n const username = normalizeUsername(input.username);\n if (username !== normalizeUsername(auth.username) || !verifyAccessPassword(input.password, auth.passwordHash, auth.passwordSalt)) {\n throw new Error(\"Invalid username or password.\");\n }\n\n return this.createLoginResult(username, true);\n };\n\n logout = (token: string | null | undefined): void => {\n this.sessions.deleteToken(token);\n };\n\n updatePassword = async (input: { token: string | null | undefined; password: string }): Promise<AccessLoginResult> => {\n const config = this.loadCurrentConfig();\n const auth = config.ui.auth;\n if (!this.isConfigured(auth)) {\n throw new Error(\"UI authentication is not configured.\");\n }\n if (auth.enabled && this.sessions.findPrincipalByToken(input.token, this.now()) === null) {\n throw new Error(\"Authentication required.\");\n }\n\n const username = normalizeUsername(auth.username);\n validateUsernameAndPassword(username, input.password);\n\n const nextPassword = createAccessPasswordRecord(input.password);\n config.ui.auth = {\n enabled: auth.enabled,\n username: auth.username,\n passwordHash: nextPassword.passwordHash,\n passwordSalt: nextPassword.passwordSalt,\n };\n await this.saveCurrentConfig(config, \"update password access\");\n\n this.sessions.clear();\n if (!auth.enabled) {\n return {\n status: {\n enabled: false,\n configured: true,\n authenticated: false,\n username,\n },\n };\n }\n\n return this.createLoginResult(username, true);\n };\n\n setPasswordAuthEnabled = async (input: {\n token: string | null | undefined;\n enabled: boolean;\n }): Promise<AccessLoginResult> => {\n const config = this.loadCurrentConfig();\n const auth = config.ui.auth;\n const configured = this.isConfigured(auth);\n const currentlyEnabled = Boolean(auth.enabled && configured);\n\n if (currentlyEnabled && this.sessions.findPrincipalByToken(input.token, this.now()) === null) {\n throw new Error(\"Authentication required.\");\n }\n\n if (input.enabled && !configured) {\n throw new Error(\"UI authentication must be configured before it can be enabled.\");\n }\n\n config.ui.auth = {\n enabled: Boolean(input.enabled),\n username: auth.username,\n passwordHash: auth.passwordHash,\n passwordSalt: auth.passwordSalt,\n };\n await this.saveCurrentConfig(config, \"update password access enabled\");\n\n if (!input.enabled) {\n this.sessions.clear();\n return {\n status: {\n enabled: false,\n configured,\n authenticated: false,\n username: configured ? normalizeUsername(auth.username) : undefined,\n },\n };\n }\n\n return this.createLoginResult(normalizeUsername(auth.username), true);\n };\n\n createTrustedSession = (): AccessLoginResult | null => {\n const auth = this.readAuthConfig();\n if (!auth.enabled || !this.isConfigured(auth)) {\n return null;\n }\n return this.createLoginResult(normalizeUsername(auth.username), true);\n };\n\n private loadCurrentConfig = (): Config => {\n return this.options.configManager?.loadConfig() ?? loadConfig(this.configPath);\n };\n\n private saveCurrentConfig = async (config: Config, note: string): Promise<void> => {\n const parsed = ConfigSchema.parse(config);\n if (this.options.configManager) {\n await this.options.configManager.applyConfig(parsed, note);\n return;\n }\n saveConfig(parsed, this.configPath);\n };\n\n private readAuthConfig = (): AccessAuthConfig => {\n return this.loadCurrentConfig().ui.auth;\n };\n\n private isConfigured = (auth: AccessAuthConfig): boolean => {\n return Boolean(\n normalizeUsername(auth.username).length > 0 &&\n auth.passwordHash.trim().length > 0 &&\n auth.passwordSalt.trim().length > 0\n );\n };\n\n private createLoginResult = (username: string, authenticated: boolean): AccessLoginResult => {\n const session = this.createSession(username);\n return {\n status: {\n enabled: true,\n configured: true,\n authenticated,\n username,\n },\n token: session.token,\n expiresAt: session.record.expiresAt,\n };\n };\n\n private createSession = (username: string): { token: string; record: AccessSessionRecord } => {\n const token = createAccessSessionToken();\n const now = this.now();\n const expiresAt = new Date(now.getTime() + this.sessionTtlMs).toISOString();\n const record: AccessSessionRecord = {\n tokenHash: hashAccessSessionToken(token),\n principal: {\n id: username,\n role: \"admin\",\n },\n createdAt: now.toISOString(),\n expiresAt,\n };\n this.sessions.saveSession(record, now);\n return { token, record };\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 applyConfig = async (nextConfig: Config, note?: string): Promise<ConfigMutationResult> =>\n this.applyConfigChange({ nextConfig, note });\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 type {\n AgentRunRequest,\n ContextBlock,\n ContextProvider,\n} from \"@kernel/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 {\n CLEAR_THINKING_TOKENS,\n THINKING_LEVELS,\n parseThinkingLevel,\n type Config,\n} from \"@nextclaw/core\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.js\";\n\nexport type CommandOptionType = \"string\" | \"boolean\" | \"number\";\n\nexport type CommandOption = {\n name: string;\n description: string;\n type: CommandOptionType;\n required?: boolean;\n};\n\nexport type CommandExecutionContext = {\n channel: string;\n chatId: string;\n senderId: string;\n sessionKey?: string;\n};\n\nexport type CommandResult = {\n content: string;\n ephemeral?: boolean;\n};\n\nexport type ParsedTextCommand = {\n name: string;\n args: Record<string, unknown>;\n};\n\ntype CommandHandlerContext = CommandExecutionContext & {\n config: Config;\n sessionKey: string;\n};\n\ntype CommandSpec = {\n name: string;\n description: string;\n options?: CommandOption[];\n aliases?: string[];\n execute: (\n ctx: CommandHandlerContext,\n args: Record<string, unknown>,\n ) => Promise<CommandResult> | CommandResult;\n};\n\ntype SlashCommandSpec = {\n name: string;\n description: string;\n options?: CommandOption[];\n};\n\nconst DEFAULT_EPHEMERAL = true;\nconst CLEAR_MODEL_TOKENS = new Set([\"clear\", \"reset\", \"off\", \"none\"]);\n\nfunction normalizeCommandName(name: string): string {\n return name.trim().replace(/^\\//, \"\").toLowerCase();\n}\n\nfunction cloneSessionMetadata(metadata: Record<string, unknown> | undefined): Record<string, unknown> {\n return structuredClone(metadata ?? {});\n}\n\nexport class CommandRegistry {\n private readonly specs: CommandSpec[] = [];\n private readonly lookup = new Map<string, CommandSpec>();\n\n constructor(\n private readonly config: Config,\n private readonly sessionManager?: SessionManager,\n ) {\n this.registerDefaults();\n }\n\n listSlashCommands = (): SlashCommandSpec[] => {\n const commands: SlashCommandSpec[] = [];\n for (const spec of this.specs) {\n commands.push({\n description: spec.description,\n name: spec.name,\n options: spec.options,\n });\n for (const alias of spec.aliases ?? []) {\n commands.push({\n description: spec.description,\n name: alias,\n options: spec.options,\n });\n }\n }\n return commands;\n };\n\n execute = async (\n name: string,\n args: Record<string, unknown> | undefined,\n ctx: CommandExecutionContext,\n ): Promise<CommandResult> => {\n const trimmedName = normalizeCommandName(name);\n const spec = this.lookup.get(trimmedName);\n if (!spec) {\n return {\n content: `Unknown command: /${trimmedName}. Try /help for the command list.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const sessionKey = ctx.sessionKey ?? `${ctx.channel}:${ctx.chatId}`;\n return await spec.execute({\n ...ctx,\n config: this.config,\n sessionKey,\n }, args ?? {});\n };\n\n parseTextCommand = (input: string): ParsedTextCommand | null => {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) {\n return null;\n }\n const withoutSlash = trimmed.slice(1).trim();\n if (!withoutSlash) {\n return null;\n }\n const [nameToken, ...restTokens] = withoutSlash.split(/\\s+/);\n const name = normalizeCommandName(nameToken);\n if (!name) {\n return null;\n }\n const spec = this.lookup.get(name);\n const restText = restTokens.join(\" \").trim();\n return {\n args: spec ? this.parseTextArgs(spec, restText) : {},\n name,\n };\n };\n\n executeText = async (\n input: string,\n ctx: CommandExecutionContext,\n ): Promise<CommandResult | null> => {\n const parsed = this.parseTextCommand(input);\n if (!parsed) {\n return null;\n }\n return await this.execute(parsed.name, parsed.args, ctx);\n };\n\n private registerDefaults = (): void => {\n this.register({\n name: \"help\",\n description: \"Show available commands\",\n aliases: [\"commands\"],\n execute: () => ({\n content: this.buildHelpText(),\n ephemeral: DEFAULT_EPHEMERAL,\n }),\n });\n\n this.register({\n name: \"whoami\",\n description: \"Show your sender and session info\",\n aliases: [\"id\"],\n execute: (ctx) => ({\n content: [\n `Channel: ${ctx.channel}`,\n `Sender: ${ctx.senderId}`,\n `Chat: ${ctx.chatId}`,\n `Session: ${ctx.sessionKey}`,\n ].join(\"\\n\"),\n ephemeral: DEFAULT_EPHEMERAL,\n }),\n });\n\n this.register({\n name: \"status\",\n description: \"Show current session status\",\n execute: async (ctx) => {\n const session = await this.sessionManager?.getSessionRecord(ctx.sessionKey);\n const model = this.resolveSessionModel(session?.metadata);\n const thinking = this.resolveSessionThinking(session?.metadata);\n return {\n content: [\n `Session: ${ctx.sessionKey}`,\n `Model: ${model}`,\n `Thinking: ${thinking ? `${thinking} (session override)` : \"default\"}`,\n ].join(\"\\n\"),\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n\n this.register({\n name: \"reset\",\n description: \"Reset conversation history\",\n aliases: [\"new\"],\n execute: async (ctx) => {\n if (!this.sessionManager) {\n return { content: \"Session management is not available.\", ephemeral: DEFAULT_EPHEMERAL };\n }\n const totalCleared = await this.sessionManager.clearSessionMessages(ctx.sessionKey);\n return {\n content: `Conversation history cleared (${totalCleared} messages).`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n\n this.register({\n name: \"model\",\n description: \"Get or set the session model\",\n options: [{\n name: \"name\",\n description: \"Model name (or 'clear' to reset)\",\n type: \"string\",\n }],\n execute: async (ctx, args) => {\n if (!this.sessionManager) {\n return { content: \"Session management is not available.\", ephemeral: DEFAULT_EPHEMERAL };\n }\n const session = await this.getOrCreateCommandSession(ctx.sessionKey);\n const raw = typeof args.name === \"string\" ? args.name.trim() : \"\";\n if (!raw) {\n return {\n content: `Current model: ${this.resolveSessionModel(session.metadata)}`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const metadata = cloneSessionMetadata(session.metadata);\n if (CLEAR_MODEL_TOKENS.has(raw.toLowerCase())) {\n delete metadata.preferred_model;\n delete metadata.model;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: `Model override cleared. Current model: ${this.resolveSessionModel(metadata)}`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n metadata.preferred_model = raw;\n metadata.model = raw;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: `Model set to ${raw}.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n\n this.register({\n name: \"thinking\",\n description: \"Get or set the session thinking effort\",\n aliases: [\"effort\"],\n options: [{\n name: \"level\",\n description: `Thinking level (${THINKING_LEVELS.join(\"|\")} or clear/reset/default)`,\n type: \"string\",\n }],\n execute: async (ctx, args) => {\n if (!this.sessionManager) {\n return { content: \"Session management is not available.\", ephemeral: DEFAULT_EPHEMERAL };\n }\n const session = await this.getOrCreateCommandSession(ctx.sessionKey);\n const raw = typeof args.level === \"string\" ? args.level.trim() : \"\";\n if (!raw) {\n const current = this.resolveSessionThinking(session.metadata);\n return {\n content: current\n ? `Current thinking effort: ${current} (session override)`\n : \"Current thinking effort: default\",\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const normalized = raw.toLowerCase();\n const metadata = cloneSessionMetadata(session.metadata);\n if (CLEAR_THINKING_TOKENS.has(normalized)) {\n delete metadata.preferred_thinking;\n delete metadata.thinking;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: \"Thinking override cleared. Current thinking effort: default\",\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const level = parseThinkingLevel(normalized);\n if (!level) {\n return {\n content: `Invalid thinking level: ${raw}. Allowed: ${THINKING_LEVELS.join(\", \")}. Use clear/reset/default to remove override.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n metadata.preferred_thinking = level;\n metadata.thinking = level;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: `Thinking effort set to ${level}.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n };\n\n private register = (spec: CommandSpec): void => {\n const name = normalizeCommandName(spec.name);\n if (this.lookup.has(name)) {\n return;\n }\n const normalizedSpec: CommandSpec = { ...spec, name };\n this.specs.push(normalizedSpec);\n this.lookup.set(name, normalizedSpec);\n for (const alias of spec.aliases ?? []) {\n const normalized = normalizeCommandName(alias);\n if (!this.lookup.has(normalized)) {\n this.lookup.set(normalized, normalizedSpec);\n }\n }\n };\n\n private buildHelpText = (): string => {\n const lines = [\"Available commands:\"];\n const specs = [...this.specs].sort((a, b) => a.name.localeCompare(b.name));\n for (const spec of specs) {\n const optionText = (spec.options ?? [])\n .map((option) => `${option.required ? \"<\" : \"[\"}${option.name}${option.required ? \">\" : \"]\"}`)\n .join(\" \");\n const aliasText =\n spec.aliases && spec.aliases.length > 0 ? ` (alias: ${spec.aliases.map((alias) => `/${alias}`).join(\", \")})` : \"\";\n const usage = optionText ? `/${spec.name} ${optionText}` : `/${spec.name}`;\n lines.push(`${usage} - ${spec.description}${aliasText}`);\n }\n return lines.join(\"\\n\");\n };\n\n private getOrCreateCommandSession = async (sessionId: string) => {\n const sessionManager = this.sessionManager;\n if (!sessionManager) {\n throw new Error(\"Session management is not available.\");\n }\n const existing = await sessionManager.getSessionRecord(sessionId);\n if (existing) {\n return existing;\n }\n await sessionManager.createSession({\n sessionId,\n sourceSessionMetadata: {},\n task: \"Session\",\n });\n const created = await sessionManager.getSessionRecord(sessionId);\n if (!created) {\n throw new Error(`Session was not created: ${sessionId}`);\n }\n return created;\n };\n\n private resolveSessionModel = (metadata: Record<string, unknown> | undefined): string => {\n const preferred =\n metadata && typeof metadata.preferred_model === \"string\" ? metadata.preferred_model.trim() : \"\";\n return preferred || this.config.agents.defaults.model;\n };\n\n private resolveSessionThinking = (metadata: Record<string, unknown> | undefined): string | null => {\n if (!metadata) {\n return null;\n }\n return parseThinkingLevel(metadata.preferred_thinking);\n };\n\n private parseTextArgs = (spec: CommandSpec, raw: string): Record<string, unknown> => {\n if (!spec.options || spec.options.length === 0 || !raw) {\n return {};\n }\n const tokens = raw.split(/\\s+/).filter(Boolean);\n const args: Record<string, unknown> = {};\n let cursor = 0;\n for (let i = 0; i < spec.options.length; i += 1) {\n if (cursor >= tokens.length) {\n break;\n }\n const option = spec.options[i];\n const isLastOption = i === spec.options.length - 1;\n const rawValue = isLastOption ? tokens.slice(cursor).join(\" \") : tokens[cursor];\n cursor += isLastOption ? tokens.length - cursor : 1;\n const parsed = this.parseTextOptionValue(option.type, rawValue);\n if (parsed !== undefined) {\n args[option.name] = parsed;\n }\n }\n return args;\n };\n\n private parseTextOptionValue = (\n type: CommandOptionType,\n raw: string,\n ): string | number | boolean | undefined => {\n const value = raw.trim();\n if (!value) {\n return undefined;\n }\n if (type === \"number\") {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n if (type === \"boolean\") {\n return [\"true\", \"1\", \"yes\", \"on\"].includes(value.toLowerCase());\n }\n return value;\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 tokenForExtension: (extensionId: string) => 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 tokenForExtension: (extensionId: string) => 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.tokenForExtension(manifest.id),\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 PACKAGED_EXTENSION_DIR_ENV = \"NEXTCLAW_PACKAGED_EXTENSION_DIR\";\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 resolvePackagedExtensionManifestRoots(\n explicitDir = process.env[PACKAGED_EXTENSION_DIR_ENV],\n): string[] {\n const configured = explicitDir?.trim();\n return configured ? [resolve(configured)] : [];\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 ...resolvePackagedExtensionManifestRoots(),\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 } from \"@nextclaw/core\";\nimport { CommandRegistry } from \"@kernel/services/command-registry.service.js\";\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 private readonly lifecycle = new ExtensionLifecycleService();\n private readonly extensionTokens = new Map<string, string>();\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 tokenForExtension: this.getExtensionProcessToken,\n });\n if (running.length > 0) {\n console.log(`✓ Extensions started: ${running.map((entry) => entry.manifest.id).join(\", \")}`);\n }\n };\n\n getExtensionProcessToken = (extensionId: string): string => {\n const id = readRequiredString(extensionId, \"extensionId\");\n const current = this.extensionTokens.get(id);\n if (current) {\n return current;\n }\n const token = randomUUID();\n this.extensionTokens.set(id, token);\n return token;\n };\n\n authenticateEventStreamCredential = (input: {\n extensionId: string | null;\n token: string | null;\n }): { extensionId: string } | null => {\n const extensionId = readString(input.extensionId);\n const token = readString(input.token);\n if (!extensionId || !token || token !== this.extensionTokens.get(extensionId)) {\n return null;\n }\n return { extensionId };\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(envelope, 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(envelope, 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(envelope, 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(envelope, 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(envelope, 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 = (envelope: IngressEnvelope<unknown>, context: IngressContext): void => {\n const extensionId = readString(envelope.extensionId);\n if (!extensionId || context.token !== this.extensionTokens.get(extensionId)) {\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} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { SessionManager } from \"@kernel/managers/session.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 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 authenticateEventStreamCredential = (input: {\n extensionId: string | null;\n token: string | null;\n }): { extensionId: string } | null =>\n this.runtime.authenticateEventStreamCredential(input);\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 normalizeProviderModelConfig,\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 providerId: string | null;\n providerName: string | null;\n provider: ProviderConfig | null;\n apiBase: string | null;\n modelConfig?: ProviderConfig[\"modelConfig\"];\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 const trimmed = typeof value === \"string\" ? value.trim() : \"\";\n return 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 model: route?.model ?? params.model,\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 model: route?.model ?? params.model,\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 providerId: input.providerName,\n provider: {\n enabled: true,\n providerType: input.providerName,\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 route = this.resolveProvider(effectiveModel);\n const { provider, name } = route;\n const providerSpec = name ? this.providerRegistry.findProviderByName(name) : undefined;\n const specModelConfig = normalizeProviderModelConfig(providerSpec?.modelConfig ?? {});\n const providerModelConfig = this.normalizeProviderModelConfigForRoute(\n provider?.modelConfig ?? {},\n route.providerId,\n name\n );\n return {\n model: route.model,\n providerId: route.providerId,\n providerName: name,\n provider,\n apiBase: provider?.apiBase ?? providerSpec?.defaultApiBase ?? null,\n modelConfig: { ...specModelConfig, ...providerModelConfig },\n };\n };\n\n private resolveProvider = (model: string): {\n provider: ProviderConfig | null;\n name: string | null;\n providerId: string | null;\n model: string;\n } => {\n const providers = this.config?.providers as Record<string, ProviderConfig> | undefined;\n if (!providers) {\n return { provider: null, name: null, providerId: null, model };\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, model);\n if (prefixed) {\n return prefixed;\n }\n }\n\n const keywordMatches = Object.entries(providers)\n .map(([providerId, provider]) => {\n const providerType = this.resolveProviderType(providerId, provider);\n const spec = providerType ? this.providerRegistry.findProviderByName(providerType) : undefined;\n return { name: providerType, providerId, provider, spec };\n })\n .filter((entry): entry is { name: string; providerId: string; provider: ProviderConfig; spec: NonNullable<ReturnType<ProviderRegistry[\"findProviderByName\"]>> } => Boolean(entry.name && entry.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 const providerId = match.providerId;\n return { provider: match.provider ?? null, name: match.name, providerId, model: this.rewriteModelForTemplate(model, providerId, match.name) };\n }\n if (keywordMatches.length > 1) {\n return { provider: null, name: null, providerId: null, model };\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 const providerType = this.resolveProviderType(name, provider);\n return { provider, name: providerType, providerId: name, model: this.rewriteModelForTemplate(model, name, providerType) };\n }\n const enabledCustom = enabledProviders.filter(([name]) => !builtinNames.has(name));\n if (enabledCustom.length === 1) {\n const [name, provider] = enabledCustom[0];\n const providerType = this.resolveProviderType(name, provider);\n return { provider, name: providerType, providerId: name, model: this.rewriteModelForTemplate(model, name, providerType) };\n }\n return { provider: null, name: null, providerId: null, model };\n };\n\n private matchPrefixedProvider = (\n providers: Record<string, ProviderConfig>,\n modelPrefix: string,\n model: string\n ): { provider: ProviderConfig | null; name: string | null; providerId: string | null; model: string } | null => {\n const customProvider = Object.entries(providers)\n .find(([name]) => name.toLowerCase() === modelPrefix);\n if (!customProvider) {\n return null;\n }\n const [providerId, provider] = customProvider;\n if (provider.enabled === false) {\n return { provider: null, name: null, providerId, model };\n }\n const providerType = this.resolveProviderType(providerId, provider);\n return {\n provider,\n name: providerType,\n providerId,\n model: this.rewriteModelForTemplate(model, providerId, providerType),\n };\n };\n\n private resolveProviderType = (providerId: string, provider: ProviderConfig): string | null => {\n const configuredType = typeof provider.providerType === \"string\" ? provider.providerType.trim() : \"\";\n if (configuredType && this.providerRegistry.findProviderByName(configuredType)) {\n return configuredType;\n }\n return this.providerRegistry.findProviderByName(providerId) ? providerId : null;\n };\n\n private rewriteModelForTemplate = (model: string, providerId: string, providerType: string | null): string => {\n const prefix = `${providerId}/`;\n if (!model.startsWith(prefix)) {\n return model;\n }\n const suffix = model.slice(prefix.length).trim();\n if (!suffix) {\n return model;\n }\n return providerType ? `${providerType}/${suffix}` : suffix;\n };\n\n private normalizeProviderModelConfigForRoute = (\n modelConfig: ProviderConfig[\"modelConfig\"],\n providerId: string | null,\n providerType: string | null,\n ): ProviderConfig[\"modelConfig\"] => {\n const normalized = normalizeProviderModelConfig(modelConfig ?? {});\n if (!providerId || !providerType) {\n return normalized;\n }\n const rewritten: ProviderConfig[\"modelConfig\"] = {};\n for (const [model, config] of Object.entries(normalized)) {\n rewritten[this.rewriteModelForTemplate(model, providerId, providerType)] = config;\n }\n return rewritten;\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?.modelConfig,\n }),\n });\n };\n\n private buildCacheKey = (route: ProviderRoute): string => {\n const routeProvider = route.provider;\n return [\n route.providerName ?? \"\",\n route.providerId ?? \"\",\n routeProvider?.apiKey ?? \"\",\n route.apiBase ?? \"\",\n routeProvider?.wireApi ?? \"\",\n headersFingerprint(routeProvider?.extraHeaders ?? null),\n ].join(\"||\");\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 { 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 = record.messages.reduceRight<string | undefined>(\n (timestamp, message) => timestamp ?? readMessageTimestamp(message),\n undefined);\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 message?.status === \"final\" ? toIsoString(message.timestamp, \"\") || undefined : 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 if (\n event.type === NcpEventType.MessageSent ||\n event.type === NcpEventType.MessageCompleted ||\n event.type === NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE\n ) {\n return event.payload.message;\n }\n return undefined;\n}\n","import { createHash } from \"node:crypto\";\nimport { BUILTIN_MAIN_AGENT_ID } from \"@nextclaw/core\";\n\nexport const AGENT_RUN_PEER_ID_METADATA_KEY = \"agent_peer_id\";\nexport const AGENT_RUN_PEER_SCOPE_METADATA_KEY = \"agent_peer_scope\";\n\nexport type AgentPeerSessionIdentity = {\n metadata: Record<string, unknown>;\n sessionId: string;\n};\n\nexport function createAgentPeerSessionIdentity(params: {\n agentId?: string;\n channel?: string;\n metadata?: Record<string, unknown>;\n peerId: string;\n}): AgentPeerSessionIdentity {\n const scope = resolveAgentPeerScope(params);\n return {\n metadata: {\n [AGENT_RUN_PEER_ID_METADATA_KEY]: params.peerId,\n [AGENT_RUN_PEER_SCOPE_METADATA_KEY]: scope,\n },\n sessionId: `agent-peer-${createHash(\"sha256\")\n .update(`${scope}\\0${params.peerId}`)\n .digest(\"hex\")\n .slice(0, 32)}`,\n };\n}\n\nfunction resolveAgentPeerScope(params: {\n agentId?: string;\n channel?: string;\n metadata?: Record<string, unknown>;\n}): string {\n const metadata = params.metadata ?? {};\n const explicitScope =\n readOptionalString(metadata[AGENT_RUN_PEER_SCOPE_METADATA_KEY]) ??\n readOptionalString(metadata.agentPeerScope);\n if (explicitScope) {\n return explicitScope;\n }\n const agentId = readOptionalString(params.agentId) ?? BUILTIN_MAIN_AGENT_ID;\n const channel =\n readOptionalString(params.channel) ??\n readOptionalString(metadata.channel) ??\n \"agent-run\";\n const accountId =\n readOptionalString(metadata.accountId) ??\n readOptionalString(metadata.account_id) ??\n \"default\";\n return `agent:${agentId}:${channel}:${accountId}`;\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","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 NcpEndpointEvent,\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 { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport { ContextWindowPreviewManager } from \"@kernel/features/context-compaction/index.js\";\nimport type { NcpAgentSessionJournalStore } from \"@kernel/stores/ncp-agent-session-journal.store.js\";\nimport type {\n AgentRunSession,\n CreateAgentRunSessionParams,\n} from \"@kernel/types/session.types.js\";\nimport type { ThinkingEffort } from \"@kernel/types/agent-run.types.js\";\nimport {\n createNcpAgentSessionSummary,\n type NcpAgentSessionJournalReplayEvent,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\nimport { createAgentPeerSessionIdentity } from \"@kernel/utils/agent-peer-session.utils.js\";\nimport {\n eventKeys,\n type EventBus,\n} 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 SessionManagerOptions = {\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 readOptionalMetadataString(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 ? readOptionalMetadataString(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 readOptionalMetadataString(metadata?.thinkingEffort) ?? null;\n}\n\nfunction readProjectRoot(metadata: Record<string, unknown> | undefined): string | undefined {\n return readOptionalMetadataString(metadata?.project_root) ?? readOptionalMetadataString(metadata?.projectRoot);\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 SessionManager implements NcpSessionApi {\n readonly cleanups: Array<() => void> = [];\n private readonly contextWindowPreview: ContextWindowPreviewManager;\n private started = false;\n\n constructor(private readonly options: SessionManagerOptions) {\n this.contextWindowPreview = new ContextWindowPreviewManager({\n configManager: options.configManager,\n });\n }\n\n start = (): void => {\n if (this.started) {\n return;\n }\n this.started = true;\n this.cleanups.push(this.options.eventBus.on(eventKeys.ncpEvent, async (event) => {\n const sessionId = readEventSessionId(event);\n if (!sessionId || !isDurableSessionEvent(event)) {\n return;\n }\n await this.appendSessionEvent({\n event,\n sessionId,\n });\n }));\n };\n\n dispose = (): void => {\n while (this.cleanups.length > 0) {\n this.cleanups.pop()?.();\n }\n this.started = false;\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);\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.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.createSummaryFromRecord(liveRecord, true)\n : await this.getSession(sessionId);\n return summary?.contextWindow ?? null;\n };\n\n getAgentRunSession = async (sessionId: string): Promise<AgentRunSession> => {\n const record = await this.getSessionRecord(sessionId);\n if (!record) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n const agentRuntimeId = readOptionalMetadataString(record.metadata?.agentRuntimeId) ??\n DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n const model = readOptionalMetadataString(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 createAgentRunSession = async (\n params: CreateAgentRunSessionParams,\n ): Promise<AgentRunSession> => {\n const {\n agentId,\n agentRuntimeId: requestedAgentRuntimeId,\n channel,\n metadata,\n model,\n peerId: rawPeerId,\n projectRoot,\n sessionId,\n task,\n thinkingEffort,\n } = params;\n const agentRuntimeId = requestedAgentRuntimeId ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n const peerId = readOptionalString(rawPeerId);\n const peerIdentity = peerId\n ? createAgentPeerSessionIdentity({ agentId, channel, metadata, peerId })\n : undefined;\n const requestedSessionId = readOptionalString(sessionId);\n const created = await this.createSession({\n sourceSessionMetadata: {},\n sessionId: requestedSessionId ?? peerIdentity?.sessionId,\n task: task ?? \"Session\",\n agentId,\n metadataOverrides: Object.assign(structuredClone(metadata ?? {}), peerIdentity?.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 getOrCreateAgentRunSession = async (\n params: CreateAgentRunSessionParams,\n ): Promise<AgentRunSession> => {\n if (!params.sessionId) {\n return await this.createAgentRunSession(params);\n }\n const existing = await this.getSessionRecord(params.sessionId);\n if (existing) {\n return await this.getAgentRunSession(params.sessionId);\n }\n return await this.createAgentRunSession(params);\n };\n\n patchSessionMetadata = async (\n sessionId: string,\n patch: Record<string, unknown>,\n ): Promise<void> => {\n const updated = await this.updateSessionMetadata(sessionId, patch);\n if (!updated) {\n throw new Error(`Session metadata was not updated: ${sessionId}`);\n }\n };\n\n clearSessionMessages = async (sessionId: string): Promise<number> => {\n const record = await this.getSessionRecord(sessionId);\n if (!record) {\n await this.createSession({\n sessionId,\n sourceSessionMetadata: {},\n task: \"Session\",\n });\n return 0;\n }\n const nextRecord: AgentSessionRecord = {\n ...record,\n messages: [],\n updatedAt: new Date().toISOString(),\n metadata: structuredClone(record.metadata ?? {}),\n };\n await this.options.journalStore.importSessionSnapshot(nextRecord);\n await this.publishSessionChange(record.sessionId);\n return record.messages.length;\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 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 type {\n NcpEndpointEvent,\n NcpMessage,\n NcpMessagePart,\n NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport type { AgentRunSendIngressPayload } from \"@nextclaw/shared\";\n\nexport type PanelAppErrorCode =\n | \"AGENT_OBJECT_REQUEST_FAILED\"\n | \"AGENT_OBJECT_RESULT_NOT_SUBMITTED\"\n | \"AGENT_OBJECT_RESULT_SCHEMA_INVALID\"\n | \"AGENT_OBJECT_RESULT_TIMEOUT\"\n | \"AUTHORIZATION_REQUIRED\"\n | \"PANEL_APP_AGENT_REQUEST_INVALID\"\n | \"PANEL_APP_ASSET_TOKEN_EXPIRED\"\n | \"PANEL_APP_ASSET_TOKEN_INVALID\"\n | \"PANEL_APP_BRIDGE_SESSION_NOT_FOUND\"\n | \"PANEL_APP_CAPABILITY_NOT_DECLARED\"\n | \"PANEL_APP_INVALID_ASSET_PATH\"\n | \"PANEL_APP_INVALID_ID\"\n | \"PANEL_APP_MANIFEST_INVALID\"\n | \"PANEL_APP_NOT_FOUND\"\n | \"PANEL_APP_READ_FAILED\";\n\nexport class PanelAppError extends Error {\n constructor(\n readonly code: PanelAppErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"PanelAppError\";\n }\n}\n\nexport function isPanelAppError(error: unknown): error is PanelAppError {\n return error instanceof PanelAppError;\n}\n\nexport const PANEL_APP_AGENT_CAPABILITIES = [\n \"agent:send\",\n \"agent:generateObject\",\n] as const;\n\nexport type PanelAppAgentCapability = typeof PANEL_APP_AGENT_CAPABILITIES[number];\n\nexport function isPanelAppAgentCapability(\n value: unknown,\n): value is PanelAppAgentCapability {\n return (PANEL_APP_AGENT_CAPABILITIES as readonly unknown[]).includes(value);\n}\n\nexport type PanelAppCapabilityGrantCaller = {\n surface: \"panel-app\";\n appId: string;\n};\n\nexport type PanelAppCapabilityGrant = {\n caller: PanelAppCapabilityGrantCaller;\n capability: PanelAppAgentCapability;\n grantedAt: string;\n};\n\nexport type PanelAppAgentSendPayload =\n | {\n sessionId?: string;\n peerId?: string;\n content: NcpMessagePart[];\n message?: never;\n metadata?: Record<string, unknown>;\n }\n | {\n sessionId?: string;\n peerId?: string;\n message: NcpMessage | (Omit<NcpMessage, \"sessionId\"> & { sessionId?: string });\n content?: never;\n metadata?: Record<string, unknown>;\n };\n\nexport type PanelAppAgentSendRequest = {\n payload: PanelAppAgentSendPayload;\n};\n\nexport type PanelAppAgentSendResult = NcpRunHandle;\n\nexport type PanelAppAgentRunClient = {\n send: (input: AgentRunSendIngressPayload) => Promise<NcpRunHandle>;\n sendAndStreamEvents: (\n input: AgentRunSendIngressPayload,\n ) => AsyncGenerator<NcpEndpointEvent>;\n};\n\nexport type PanelAppAgentGenerateObjectInput = {\n peerId: string;\n prompt: string;\n context?: unknown;\n schema: Record<string, unknown>;\n title?: string;\n timeoutMs?: number;\n};\n\nexport type PanelAppAgentGenerateObjectRequest = {\n input: PanelAppAgentGenerateObjectInput;\n};\n\nexport type PanelAppAgentGenerateObjectResult = {\n result: unknown;\n};\n","import { createHmac, randomBytes, timingSafeEqual } from \"node:crypto\";\nimport { PanelAppError } from \"@kernel/types/panel-app.types.js\";\n\nconst PANEL_APP_ASSET_TOKEN_TTL_MS = 2 * 60 * 60 * 1000;\n\nexport type PanelAppAssetTokenClaims = {\n panelAppId: string;\n sourceName: string;\n expiresAt: number;\n nonce: string;\n};\n\ntype PanelAppAssetTokenServiceParams = {\n now?: () => number;\n secret?: Buffer;\n ttlMs?: number;\n};\n\nexport class PanelAppAssetTokenService {\n private readonly now: () => number;\n private readonly secret: Buffer;\n private readonly ttlMs: number;\n\n constructor(params: PanelAppAssetTokenServiceParams = {}) {\n this.now = params.now ?? Date.now;\n this.secret = params.secret ?? randomBytes(32);\n this.ttlMs = params.ttlMs ?? PANEL_APP_ASSET_TOKEN_TTL_MS;\n }\n\n issue = (params: {\n panelAppId: string;\n sourceName: string;\n }): string => {\n const claims: PanelAppAssetTokenClaims = {\n panelAppId: params.panelAppId,\n sourceName: params.sourceName,\n expiresAt: this.now() + this.ttlMs,\n nonce: randomBytes(12).toString(\"base64url\"),\n };\n const payload = Buffer.from(JSON.stringify(claims), \"utf8\").toString(\"base64url\");\n return `${payload}.${this.sign(payload)}`;\n };\n\n verify = (token: string): PanelAppAssetTokenClaims => {\n const normalizedToken = token.trim();\n const [payload, signature, ...rest] = normalizedToken.split(\".\");\n if (!payload || !signature || rest.length > 0 || !this.matchesSignature(payload, signature)) {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_INVALID\",\n \"invalid panel app asset token\",\n );\n }\n const claims = this.parseClaims(payload);\n if (claims.expiresAt <= this.now()) {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_EXPIRED\",\n \"panel app asset token expired\",\n );\n }\n return claims;\n };\n\n private sign = (payload: string): string =>\n createHmac(\"sha256\", this.secret).update(payload).digest(\"base64url\");\n\n private matchesSignature = (payload: string, signature: string): boolean => {\n const expected = Buffer.from(this.sign(payload), \"utf8\");\n const actual = Buffer.from(signature, \"utf8\");\n return expected.length === actual.length && timingSafeEqual(expected, actual);\n };\n\n private parseClaims = (payload: string): PanelAppAssetTokenClaims => {\n try {\n const claims = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf8\")) as unknown;\n if (!isPanelAppAssetTokenClaims(claims)) {\n throw new Error(\"invalid panel app asset token claims\");\n }\n return claims;\n } catch {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_INVALID\",\n \"invalid panel app asset token\",\n );\n }\n };\n}\n\nfunction isPanelAppAssetTokenClaims(value: unknown): value is PanelAppAssetTokenClaims {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"panelAppId\" in value &&\n \"sourceName\" in value &&\n \"expiresAt\" in value &&\n \"nonce\" in value &&\n typeof value.panelAppId === \"string\" &&\n typeof value.sourceName === \"string\" &&\n typeof value.expiresAt === \"number\" &&\n typeof value.nonce === \"string\"\n );\n}\n","import { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\n\nconst PANEL_APP_STATE_FILE = \".panel-apps.state.json\";\nconst PANEL_APP_STATE_VERSION = 1;\n\nexport type PanelAppStateEntry = {\n favorite?: boolean;\n lastOpenedAt?: string;\n openCount?: number;\n};\n\nexport type PanelAppStateSnapshot = Record<string, PanelAppStateEntry>;\n\ntype PanelAppStateFile = {\n version: typeof PANEL_APP_STATE_VERSION;\n apps: PanelAppStateSnapshot;\n};\n\nexport type PanelAppPreferencesUpdate = {\n favorite?: boolean;\n};\n\nexport class PanelAppStateStore {\n constructor(private readonly panelsPath: string) {}\n\n load = async (): Promise<PanelAppStateSnapshot> => {\n try {\n const parsed = JSON.parse(await readFile(this.getStatePath(), \"utf8\")) as unknown;\n return this.normalizeStateFile(parsed).apps;\n } catch (error) {\n if (this.isMissingFileError(error) || error instanceof SyntaxError) {\n return {};\n }\n throw error;\n }\n };\n\n updatePreferences = async (\n id: string,\n preferences: PanelAppPreferencesUpdate,\n ): Promise<PanelAppStateEntry> => {\n const apps = await this.load();\n const current = apps[id] ?? {};\n const next = { ...current };\n if (typeof preferences.favorite === \"boolean\") {\n next.favorite = preferences.favorite;\n }\n apps[id] = next;\n await this.persist(apps);\n return next;\n };\n\n recordOpened = async (id: string, openedAt = new Date()): Promise<PanelAppStateEntry> => {\n const apps = await this.load();\n const current = apps[id] ?? {};\n const next = {\n ...current,\n lastOpenedAt: openedAt.toISOString(),\n openCount: Math.max(0, current.openCount ?? 0) + 1,\n };\n apps[id] = next;\n await this.persist(apps);\n return next;\n };\n\n deleteEntry = async (id: string): Promise<void> => {\n const apps = await this.load();\n if (!(id in apps)) {\n return;\n }\n delete apps[id];\n await this.persist(apps);\n };\n\n private persist = async (apps: PanelAppStateSnapshot): Promise<void> => {\n const statePath = this.getStatePath();\n const tempPath = `${statePath}.${randomUUID()}.tmp`;\n const stateFile: PanelAppStateFile = {\n version: PANEL_APP_STATE_VERSION,\n apps,\n };\n await mkdir(dirname(statePath), { recursive: true });\n try {\n await writeFile(tempPath, `${JSON.stringify(stateFile, null, 2)}\\n`, \"utf8\");\n await rename(tempPath, statePath);\n } catch (error) {\n await rm(tempPath, { force: true }).catch(() => undefined);\n throw error;\n }\n };\n\n private getStatePath = (): string => join(this.panelsPath, PANEL_APP_STATE_FILE);\n\n private normalizeStateFile = (value: unknown): PanelAppStateFile => {\n if (!this.isRecord(value) || !this.isRecord(value.apps)) {\n return { version: PANEL_APP_STATE_VERSION, apps: {} };\n }\n const apps = Object.fromEntries(\n Object.entries(value.apps).flatMap(([id, entry]) => {\n if (!this.isRecord(entry)) {\n return [];\n }\n return [[id, this.normalizeStateEntry(entry)]];\n }),\n );\n return { version: PANEL_APP_STATE_VERSION, apps };\n };\n\n private normalizeStateEntry = (entry: Record<string, unknown>): PanelAppStateEntry => {\n const normalized: PanelAppStateEntry = {};\n if (typeof entry.favorite === \"boolean\") {\n normalized.favorite = entry.favorite;\n }\n if (typeof entry.lastOpenedAt === \"string\") {\n normalized.lastOpenedAt = entry.lastOpenedAt;\n }\n if (typeof entry.openCount === \"number\") {\n normalized.openCount = entry.openCount;\n }\n return normalized;\n };\n\n private isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n private isMissingFileError = (error: unknown): boolean =>\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type {\n PanelAppCapabilityGrant,\n PanelAppCapabilityGrantCaller,\n PanelAppAgentCapability,\n} from \"@kernel/types/panel-app.types.js\";\n\ntype StoredPanelAppCapabilityGrant = {\n grantedAt: string;\n};\n\ntype PanelAppCapabilityGrantStoreData = {\n version: 1;\n grants: Record<string, {\n capabilities: Record<string, StoredPanelAppCapabilityGrant>;\n }>;\n};\n\nconst EMPTY_GRANTS: PanelAppCapabilityGrantStoreData = {\n version: 1,\n grants: {},\n};\n\nexport class PanelAppCapabilityGrantStore {\n constructor(private readonly filePath: string) {}\n\n isGranted = async (\n caller: PanelAppCapabilityGrantCaller,\n capability: PanelAppAgentCapability,\n ): Promise<boolean> => {\n const data = await this.load();\n return Boolean(data.grants[getCallerKey(caller)]?.capabilities[capability]);\n };\n\n grant = async (params: {\n caller: PanelAppCapabilityGrantCaller;\n capability: PanelAppAgentCapability;\n grantedAt: string;\n }): Promise<PanelAppCapabilityGrant> => {\n const { caller, capability, grantedAt } = params;\n const data = await this.load();\n const callerKey = getCallerKey(caller);\n const callerGrants = data.grants[callerKey] ?? { capabilities: {} };\n callerGrants.capabilities[capability] = {\n grantedAt,\n };\n data.grants[callerKey] = callerGrants;\n await this.save(data);\n return {\n caller,\n capability,\n grantedAt,\n };\n };\n\n deleteCaller = async (caller: PanelAppCapabilityGrantCaller): Promise<void> => {\n const data = await this.load();\n const callerKey = getCallerKey(caller);\n if (!(callerKey in data.grants)) {\n return;\n }\n delete data.grants[callerKey];\n await this.save(data);\n };\n\n private load = async (): Promise<PanelAppCapabilityGrantStoreData> => {\n try {\n return normalizeStoreData(JSON.parse(await readFile(this.filePath, \"utf8\")));\n } catch (error) {\n if (isMissingFileError(error)) {\n return structuredClone(EMPTY_GRANTS);\n }\n throw error;\n }\n };\n\n private save = async (data: PanelAppCapabilityGrantStoreData): Promise<void> => {\n await mkdir(dirname(this.filePath), { recursive: true });\n await writeFile(this.filePath, `${JSON.stringify(data, null, 2)}\\n`, \"utf8\");\n };\n}\n\nfunction normalizeStoreData(value: unknown): PanelAppCapabilityGrantStoreData {\n if (!isRecord(value) || value.version !== 1 || !isRecord(value.grants)) {\n return structuredClone(EMPTY_GRANTS);\n }\n const grants: PanelAppCapabilityGrantStoreData[\"grants\"] = {};\n for (const [callerKey, callerValue] of Object.entries(value.grants)) {\n if (!isRecord(callerValue) || !isRecord(callerValue.capabilities)) {\n continue;\n }\n const capabilities: Record<string, StoredPanelAppCapabilityGrant> = {};\n for (const [capability, grantValue] of Object.entries(callerValue.capabilities)) {\n if (isRecord(grantValue) && typeof grantValue.grantedAt === \"string\") {\n capabilities[capability] = { grantedAt: grantValue.grantedAt };\n }\n }\n grants[callerKey] = { capabilities };\n }\n return { version: 1, grants };\n}\n\nfunction getCallerKey(caller: PanelAppCapabilityGrantCaller): string {\n return `${caller.surface}:${caller.appId}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return Boolean(error) &&\n typeof error === \"object\" &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n","import {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpMessage,\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 { randomUUID } from \"node:crypto\";\nimport { extractTextFromNcpMessage } from \"@kernel/utils/ncp-message-bridge.utils.js\";\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 readEventCorrelationId(event: NcpEndpointEvent): string | undefined {\n if (!(\"payload\" in event)) {\n return undefined;\n }\n const correlationId =\n \"correlationId\" in event.payload ? event.payload.correlationId : 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 =\n \"sessionId\" in event.payload ? event.payload.sessionId : 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 (\n event.type === NcpEventType.MessageFailed ||\n event.type === NcpEventType.RunError ||\n event.type === NcpEventType.RunFinished\n );\n}\n\nfunction isRunEventMatch(params: {\n correlationId: string;\n event: NcpEndpointEvent;\n runId?: string;\n sessionId?: string;\n}): boolean {\n const { correlationId, event, runId, sessionId } = params;\n const eventCorrelationId = readEventCorrelationId(event);\n if (eventCorrelationId) {\n return eventCorrelationId === correlationId;\n }\n if (!sessionId || !runId) {\n return false;\n }\n return (\n readEventSessionId(event) === sessionId && readEventRunId(event) === runId\n );\n}\n\nclass AgentRunEventQueue<T> implements AsyncIterable<T> {\n private readonly values: T[] = [];\n private readonly waiters: Array<(result: IteratorResult<T>) => void> = [];\n private closed = false;\n\n push = (value: T): void => {\n if (this.closed) {\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 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.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 AgentRunEventQueue<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(\n eventKeys.ncpEvent,\n this.handleEvent,\n );\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* (\n this: AgentRunObserver,\n ): AsyncGenerator<NcpEndpointEvent> {\n for await (const event of this.queue) {\n yield event;\n }\n };\n\n waitForReply = async (\n options: AgentRunReplyOptions = {},\n ): 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(\n event.payload.error ?? options.runErrorMessage ?? \"NCP run failed.\",\n );\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 (\n this.disposed ||\n !isRunEventMatch({\n correlationId: this.options.correlationId,\n event,\n runId: this.runId,\n sessionId: this.sessionId,\n })\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<\n AgentRunSendIngressPayload,\n NcpRunHandle\n >(\n {\n type: ingressKeys.agentRun.send,\n payload: {\n ...input,\n correlationId,\n },\n },\n { source: \"agent-run-client\" },\n );\n };\n}\n","const PANEL_APP_BRIDGE_MARKER = \"nextclaw:panel-app-service-actions:request\";\n\nexport function injectPanelAppBridgeScript(html: string): string {\n if (html.includes(PANEL_APP_BRIDGE_MARKER)) {\n return html;\n }\n const script = `<script>${getPanelAppBridgeScript()}</script>`;\n const headMatch = /<head(?:\\s[^>]*)?>/i.exec(html);\n if (headMatch?.index !== undefined) {\n const insertAt = headMatch.index + headMatch[0].length;\n return `${html.slice(0, insertAt)}${script}${html.slice(insertAt)}`;\n }\n return `${script}${html}`;\n}\n\nexport function getPanelAppBridgeScript(): string {\n return `\n(() => {\n const requestType = \"nextclaw:panel-app-service-actions:request\";\n const responseType = \"nextclaw:panel-app-service-actions:response\";\n const pending = new Map();\n let counter = 0;\n\n function createRequestId() {\n counter += 1;\n return \"panel-bridge-\" + Date.now().toString(36) + \"-\" + counter.toString(36);\n }\n\n function request(method, payload) {\n const requestId = createRequestId();\n return new Promise((resolve, reject) => {\n pending.set(requestId, { method, resolve, reject });\n window.parent.postMessage({ type: requestType, requestId, method, payload }, \"*\");\n });\n }\n\n function unwrapServiceActionResult(result) {\n if (!result || typeof result !== \"object\") {\n return result;\n }\n if (Object.prototype.hasOwnProperty.call(result, \"structuredContent\") && result.structuredContent !== undefined) {\n return result.structuredContent;\n }\n const content = Array.isArray(result.content) ? result.content : undefined;\n if (content && content.length === 1 && content[0]?.type === \"text\" && typeof content[0].text === \"string\") {\n try {\n return JSON.parse(content[0].text);\n } catch {\n return content[0].text;\n }\n }\n return result;\n }\n\n function resolveBridgeData(entry, data) {\n if (entry.method === \"list\") {\n return Array.isArray(data.data?.actions) ? data.data.actions : [];\n }\n if (entry.method === \"invoke\") {\n return unwrapServiceActionResult(data.data?.result);\n }\n if (entry.method === \"agent.generateObject\") {\n return data.data?.result;\n }\n return data.data;\n }\n\n window.addEventListener(\"message\", (event) => {\n const data = event.data;\n if (!data || data.type !== responseType || typeof data.requestId !== \"string\") {\n return;\n }\n const entry = pending.get(data.requestId);\n if (!entry) {\n return;\n }\n pending.delete(data.requestId);\n if (data.ok) {\n entry.resolve(resolveBridgeData(entry, data));\n return;\n }\n const error = new Error(data.error?.message || \"NextClaw panel bridge request failed.\");\n error.code = data.error?.code;\n error.details = data.error?.details;\n entry.reject(error);\n });\n\n const existing = window.nextclaw && typeof window.nextclaw === \"object\" ? window.nextclaw : {};\n Object.defineProperty(window, \"nextclaw\", {\n configurable: true,\n value: {\n ...existing,\n serviceActions: {\n list: () => request(\"list\", {}),\n invoke: (actionId, input) => request(\"invoke\", { actionId, input }),\n requestGrant: (actionId) => request(\"requestGrant\", { actionId }),\n revokeGrant: (actionId) => request(\"revokeGrant\", { actionId })\n },\n agent: {\n send: (input) => request(\"agent.send\", { request: input }),\n generateObject: (input) => request(\"agent.generateObject\", { input })\n }\n }\n });\n})();\n`.trim();\n}\n","export type PanelAppManifest = {\n id?: string;\n title?: string;\n description?: string;\n icon?: string;\n entry?: string;\n capabilities: string[];\n serviceActions: string[];\n};\n\nconst PANEL_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nexport function parsePanelAppManifest(html: string): PanelAppManifest {\n const fields = {\n ...readHtmlTitle(html),\n ...readStandardIcon(html),\n ...readPanelAppMeta(html),\n };\n return {\n ...fields,\n capabilities: readPanelAppCapabilities(html),\n serviceActions: readPanelAppServiceActions(html),\n };\n}\n\nexport function parsePanelAppFolderManifest(raw: string): PanelAppManifest & {\n title: string;\n entry: string;\n} {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new Error(\n `panel-app.json is not valid JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n if (!isRecord(parsed)) {\n throw new Error(\"panel-app.json must contain an object.\");\n }\n const id = readOptionalString(parsed, \"id\");\n if (id && !PANEL_APP_ID_PATTERN.test(id)) {\n throw new Error(\"panel app id must be kebab-case.\");\n }\n return {\n id,\n title: readRequiredString(parsed, \"title\"),\n description: readOptionalString(parsed, \"description\"),\n icon: readOptionalString(parsed, \"icon\"),\n entry: readRequiredString(parsed, \"entry\"),\n capabilities: readStringArray(parsed.capabilities, \"capabilities\"),\n serviceActions: readStringArray(parsed.actions, \"actions\"),\n };\n}\n\nfunction readPanelAppMeta(html: string): Partial<PanelAppManifest> {\n return {\n ...readPanelAppMetaField(html, \"title\"),\n ...readPanelAppMetaField(html, \"description\"),\n ...readPanelAppMetaField(html, \"icon\"),\n };\n}\n\nfunction readPanelAppMetaField(\n html: string,\n field: keyof Pick<PanelAppManifest, \"description\" | \"icon\" | \"title\">,\n): Partial<PanelAppManifest> {\n const content = readMetaContent(html, `nextclaw-panel-${field}`, field === \"icon\" ? \"attribute\" : \"text\");\n const manifest: Partial<PanelAppManifest> = {};\n if (content) {\n manifest[field] = content;\n }\n return manifest;\n}\n\nfunction readHtmlTitle(html: string): Partial<PanelAppManifest> {\n const match = html.match(/<title[^>]*>([\\s\\S]*?)<\\/title>/i);\n const title = normalizeTextValue(match?.[1]);\n return title ? { title } : {};\n}\n\nfunction readStandardIcon(html: string): Partial<PanelAppManifest> {\n const icon = readLinkHref(html, (relTokens) => relTokens.includes(\"icon\"));\n const appleTouchIcon = readLinkHref(html, (relTokens) =>\n relTokens.some((token) => token === \"apple-touch-icon\" || token === \"apple-touch-icon-precomposed\")\n );\n const href = normalizeIconHref(icon ?? appleTouchIcon);\n return href ? { icon: href } : {};\n}\n\nfunction readMetaContent(html: string, name: string, valueKind: \"attribute\" | \"text\"): string | undefined {\n const metaTags = html.matchAll(/<meta\\s+([^>]*?)>/gi);\n for (const tag of metaTags) {\n const attributes = tag[1] ?? \"\";\n if (readHtmlAttribute(attributes, \"name\") === name) {\n const content = readHtmlAttribute(attributes, \"content\");\n return valueKind === \"attribute\"\n ? normalizeAttributeValue(content)\n : normalizeTextValue(content);\n }\n }\n return undefined;\n}\n\nfunction readLinkHref(html: string, matchesRel: (relTokens: string[]) => boolean): string | undefined {\n const linkTags = html.matchAll(/<link\\s+([^>]*?)>/gi);\n for (const tag of linkTags) {\n const attributes = tag[1] ?? \"\";\n const relTokens = (readHtmlAttribute(attributes, \"rel\") ?? \"\")\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean);\n if (matchesRel(relTokens)) {\n return normalizeAttributeValue(readHtmlAttribute(attributes, \"href\"));\n }\n }\n return undefined;\n}\n\nfunction readHtmlAttribute(attributes: string, attribute: string): string | undefined {\n const match = attributes.match(new RegExp(`(?:^|\\\\s)${attribute}\\\\s*=\\\\s*([\"'])(.*?)\\\\1`, \"i\"));\n return match?.[2] ? decodeHtmlAttribute(match[2]) : undefined;\n}\n\nfunction readPanelAppServiceActions(html: string): string[] {\n const content = readMetaContent(html, \"nextclaw-panel-actions\", \"attribute\");\n return parseTokenList(content);\n}\n\nfunction readPanelAppCapabilities(html: string): string[] {\n const content = readMetaContent(html, \"nextclaw-panel-capabilities\", \"attribute\");\n return parseTokenList(content);\n}\n\nfunction parseTokenList(content: string | undefined): string[] {\n if (!content) {\n return [];\n }\n return [...new Set(\n content\n .split(/[,\\s]+/)\n .map((entry) => entry.trim())\n .filter(Boolean),\n )];\n}\n\nfunction readRequiredString(record: Record<string, unknown>, key: string): string {\n const value = readOptionalString(record, key);\n if (!value) {\n throw new Error(`panel app ${key} is required.`);\n }\n return value;\n}\n\nfunction readOptionalString(\n record: Record<string, unknown>,\n key: string,\n): string | undefined {\n return typeof record[key] === \"string\" && record[key].trim()\n ? record[key].trim()\n : undefined;\n}\n\nfunction readStringArray(value: unknown, key: string): string[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n throw new Error(`panel app ${key} must be a string array.`);\n }\n return [...new Set(value.map((entry) => entry.trim()).filter(Boolean))];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction normalizeTextValue(value: string | undefined): string | undefined {\n const normalized = decodeHtmlAttribute(value ?? \"\").replace(/\\s+/g, \" \").trim();\n return normalized || undefined;\n}\n\nfunction normalizeAttributeValue(value: string | undefined): string | undefined {\n const normalized = decodeHtmlAttribute(value ?? \"\").trim();\n return normalized || undefined;\n}\n\nfunction normalizeIconHref(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n if (\n value.startsWith(\"data:image/\") ||\n value.startsWith(\"http://\") ||\n value.startsWith(\"https://\") ||\n value.startsWith(\"/\")\n ) {\n return value;\n }\n return undefined;\n}\n\nfunction decodeHtmlAttribute(value: string): string {\n return value\n .replace(/"/g, \"\\\"\")\n .replace(/"/g, \"\\\"\")\n .replace(/'/g, \"'\")\n .replace(/'/g, \"'\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/&/g, \"&\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport { extname, isAbsolute, join, normalize, relative, resolve } from \"node:path\";\nimport type { Dirent, Stats } from \"node:fs\";\nimport { PanelAppError } from \"@kernel/types/panel-app.types.js\";\nimport {\n parsePanelAppFolderManifest,\n type PanelAppManifest,\n} from \"@kernel/utils/panel-app-manifest.utils.js\";\n\nexport const PANEL_APP_FILE_SUFFIX = \".panel.html\";\nexport const PANEL_APP_DIR_SUFFIX = \".panel\";\nexport const PANEL_APP_FOLDER_MANIFEST_FILE_NAME = \"panel-app.json\";\n\nexport type PanelAppSourceKind = \"single-file\" | \"folder\";\n\nexport type PanelAppSource = {\n kind: PanelAppSourceKind;\n sourceName: string;\n sourcePath: string;\n entryPath: string;\n manifest?: PanelAppManifest;\n sourceStat: Stats;\n};\n\nexport type PanelAppAssetContentType =\n | \"application/javascript; charset=utf-8\"\n | \"application/json; charset=utf-8\"\n | \"application/octet-stream\"\n | \"image/png\"\n | \"image/svg+xml; charset=utf-8\"\n | \"image/webp\"\n | \"text/css; charset=utf-8\"\n | \"text/plain; charset=utf-8\";\n\nexport type PanelAppAsset = {\n content: Buffer;\n contentType: PanelAppAssetContentType;\n};\n\nexport function isPanelAppSourceEntry(entry: Dirent): boolean {\n return (\n (entry.isFile() && isPanelAppFileName(entry.name)) ||\n (entry.isDirectory() && isPanelAppDirName(entry.name))\n );\n}\n\nexport function isPanelAppFileName(fileName: string): boolean {\n return hasSafeBaseName(fileName) && fileName.endsWith(PANEL_APP_FILE_SUFFIX);\n}\n\nexport function isPanelAppDirName(dirName: string): boolean {\n return hasSafeBaseName(dirName) && dirName.endsWith(PANEL_APP_DIR_SUFFIX);\n}\n\nexport function toPanelAppTitle(sourceName: string): string {\n return (\n sourceName\n .replace(new RegExp(`${escapeRegExp(PANEL_APP_FILE_SUFFIX)}$`), \"\")\n .replace(new RegExp(`${escapeRegExp(PANEL_APP_DIR_SUFFIX)}$`), \"\")\n .replace(/[-_]+/g, \" \")\n .trim() || sourceName\n );\n}\n\nexport function encodePanelAppId(sourceName: string): string {\n return Buffer.from(sourceName, \"utf8\").toString(\"base64url\");\n}\n\nexport function decodePanelAppId(id: string): string {\n const normalizedId = id.trim();\n if (!normalizedId) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ID\", \"panel app id is required\");\n }\n let sourceName = \"\";\n try {\n sourceName = Buffer.from(normalizedId, \"base64url\").toString(\"utf8\");\n } catch {\n throw new PanelAppError(\"PANEL_APP_INVALID_ID\", \"invalid panel app id\");\n }\n if (\n encodePanelAppId(sourceName) !== normalizedId ||\n (!isPanelAppFileName(sourceName) && !isPanelAppDirName(sourceName))\n ) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ID\", \"invalid panel app id\");\n }\n return sourceName;\n}\n\nexport async function readPanelAppFolderManifest(\n dirPath: string,\n dirName: string,\n): Promise<PanelAppManifest & { id: string; title: string; entry: string }> {\n const raw = await readFile(join(dirPath, PANEL_APP_FOLDER_MANIFEST_FILE_NAME), \"utf8\");\n const manifest = parsePanelAppFolderManifest(raw);\n const expectedId = dirName.slice(0, -PANEL_APP_DIR_SUFFIX.length);\n if (manifest.id && manifest.id !== expectedId) {\n throw new PanelAppError(\n \"PANEL_APP_MANIFEST_INVALID\",\n \"panel app manifest id must match the directory name\",\n );\n }\n return { ...manifest, id: expectedId };\n}\n\nexport function resolvePanelAppRelativePath(rootPath: string, relativePath: string): string {\n if (!relativePath.trim() || relativePath.includes(\"\\0\") || isAbsolute(relativePath)) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n const normalizedPath = normalize(relativePath);\n if (normalizedPath === \".\" || normalizedPath.startsWith(\"..\")) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n const resolvedPath = resolve(rootPath, normalizedPath);\n const resolvedRoot = resolve(rootPath);\n const pathFromRoot = relative(resolvedRoot, resolvedPath);\n if (pathFromRoot.startsWith(\"..\") || isAbsolute(pathFromRoot)) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n return resolvedPath;\n}\n\nexport function resolvePanelAppAssetContentType(path: string): PanelAppAssetContentType {\n switch (extname(path).toLowerCase()) {\n case \".css\":\n return \"text/css; charset=utf-8\";\n case \".js\":\n case \".mjs\":\n return \"application/javascript; charset=utf-8\";\n case \".json\":\n return \"application/json; charset=utf-8\";\n case \".png\":\n return \"image/png\";\n case \".svg\":\n return \"image/svg+xml; charset=utf-8\";\n case \".webp\":\n return \"image/webp\";\n case \".txt\":\n return \"text/plain; charset=utf-8\";\n default:\n return \"application/octet-stream\";\n }\n}\n\nexport function resolvePanelAppIconUrl(\n id: string,\n icon: string | undefined,\n): string | undefined {\n if (!icon) {\n return undefined;\n }\n if (\n icon.startsWith(\"data:image/\") ||\n icon.startsWith(\"http://\") ||\n icon.startsWith(\"https://\") ||\n icon.startsWith(\"/\") ||\n isLikelyTextIcon(icon)\n ) {\n return icon;\n }\n return `/api/panel-apps/${encodeURIComponent(id)}/assets/${encodePanelAppAssetPath(icon)}`;\n}\n\nexport function injectPanelAppAssetBase(html: string, baseHref: string): string {\n const base = `<base href=\"${baseHref}\">`;\n if (/<base\\b/i.test(html)) {\n return html;\n }\n if (/<head[^>]*>/i.test(html)) {\n return html.replace(/<head[^>]*>/i, (head) => `${head}${base}`);\n }\n return `${base}${html}`;\n}\n\nfunction encodePanelAppAssetPath(path: string): string {\n return path\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n\nfunction hasSafeBaseName(name: string): boolean {\n return !name.includes(\"/\") && !name.includes(\"\\\\\") && !name.includes(\"\\0\");\n}\n\nfunction isLikelyTextIcon(icon: string): boolean {\n return !icon.includes(\"/\") && !icon.includes(\".\") && icon.length <= 4;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { PanelAppError, isPanelAppError } from \"@kernel/types/panel-app.types.js\";\nimport {\n decodePanelAppId,\n isPanelAppDirName,\n isPanelAppFileName,\n isPanelAppSourceEntry,\n readPanelAppFolderManifest,\n resolvePanelAppAssetContentType,\n resolvePanelAppRelativePath,\n type PanelAppAsset,\n type PanelAppSource,\n} from \"@kernel/utils/panel-app-source.utils.js\";\n\nexport class PanelAppSourceService {\n listSources = async (panelsPath: string): Promise<PanelAppSource[]> => {\n try {\n const entries = await readdir(panelsPath, { withFileTypes: true });\n const sources: PanelAppSource[] = [];\n for (const entry of entries.filter(isPanelAppSourceEntry)) {\n try {\n sources.push(await this.readSource(panelsPath, entry.name));\n } catch (error) {\n if (!isPanelAppError(error) || error.code !== \"PANEL_APP_NOT_FOUND\") {\n throw error;\n }\n }\n }\n return sources;\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n return [];\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n resolveSource = async (\n panelsPath: string,\n id: string,\n ): Promise<PanelAppSource> => {\n const sourceName = decodePanelAppId(id);\n try {\n return await this.readSource(panelsPath, sourceName);\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n getAsset = async (\n panelsPath: string,\n id: string,\n assetPath: string,\n ): Promise<PanelAppAsset> => {\n const source = await this.resolveSource(panelsPath, id);\n if (source.kind !== \"folder\") {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app asset not found\");\n }\n const filePath = resolvePanelAppRelativePath(source.sourcePath, assetPath);\n try {\n const fileStat = await stat(filePath);\n if (!fileStat.isFile()) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app asset not found\");\n }\n return {\n content: await readFile(filePath),\n contentType: resolvePanelAppAssetContentType(filePath),\n };\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app asset not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n private readSource = async (\n panelsPath: string,\n sourceName: string,\n ): Promise<PanelAppSource> => {\n const sourcePath = join(panelsPath, sourceName);\n const sourceStat = await stat(sourcePath);\n if (sourceStat.isFile() && isPanelAppFileName(sourceName)) {\n return {\n kind: \"single-file\",\n sourceName,\n sourcePath,\n entryPath: sourcePath,\n sourceStat,\n };\n }\n if (sourceStat.isDirectory() && isPanelAppDirName(sourceName)) {\n return await this.readFolderSource(sourcePath, sourceName, sourceStat);\n }\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n };\n\n private readFolderSource = async (\n sourcePath: string,\n sourceName: string,\n sourceStat: PanelAppSource[\"sourceStat\"],\n ): Promise<PanelAppSource> => {\n try {\n const manifest = await readPanelAppFolderManifest(sourcePath, sourceName);\n const entryPath = resolvePanelAppRelativePath(sourcePath, manifest.entry);\n const entryStat = await stat(entryPath);\n if (!entryStat.isFile()) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app entry not found\");\n }\n return {\n kind: \"folder\",\n sourceName,\n sourcePath,\n entryPath,\n manifest,\n sourceStat,\n };\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_MANIFEST_INVALID\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\"\n );\n}\n","import type { Stats } from \"node:fs\";\n\nexport type PanelAppActivityRecord = {\n createdAt: string;\n lastOpenedAt?: string;\n updatedAt: string;\n};\n\nexport function resolvePanelAppCreatedAt(fileStat: Stats): string {\n return fileStat.birthtimeMs > 0 ? fileStat.birthtime.toISOString() : fileStat.mtime.toISOString();\n}\n\nexport function resolvePanelAppActivityMs(entry: PanelAppActivityRecord): number {\n return Math.max(\n new Date(entry.lastOpenedAt ?? 0).getTime(),\n new Date(entry.createdAt).getTime(),\n new Date(entry.updatedAt).getTime(),\n );\n}\n","import { validateToolArgs } from \"@nextclaw/ncp-agent-runtime\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport const STRUCTURED_RESULT_TOOL_NAME = \"nextclaw_submit_result\";\n\nexport type StructuredResultContract = {\n requestId: string;\n schema: Record<string, unknown>;\n toolName: typeof STRUCTURED_RESULT_TOOL_NAME;\n};\n\nexport class StructuredResultSubmitTool implements NcpTool {\n readonly name = STRUCTURED_RESULT_TOOL_NAME;\n readonly description = \"Submit the structured object result for this request.\";\n\n constructor(private readonly contract: StructuredResultContract) {}\n\n get parameters(): Record<string, unknown> {\n return this.contract.schema;\n }\n\n validateArgs = (args: Record<string, unknown>): string[] =>\n validateToolArgs(args, this.contract.schema);\n\n execute = async (args: Record<string, unknown>): Promise<unknown> => args;\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpOutboundMessageDraft,\n} from \"@nextclaw/ncp\";\nimport type { AgentRunSendIngressPayload } from \"@nextclaw/shared\";\nimport {\n STRUCTURED_RESULT_TOOL_NAME,\n} from \"@kernel/tools/structured-result.tools.js\";\nimport {\n PanelAppError,\n type PanelAppAgentGenerateObjectInput,\n type PanelAppAgentRunClient,\n type PanelAppAgentSendPayload,\n} from \"@kernel/types/panel-app.types.js\";\n\nconst PANEL_APP_AGENT_DEFAULT_TIMEOUT_MS = 60_000;\nconst PANEL_APP_AGENT_MAX_TIMEOUT_MS = 120_000;\nconst PANEL_APP_AGENT_MAX_PROMPT_CHARS = 20_000;\nconst PANEL_APP_AGENT_MAX_CONTEXT_CHARS = 80_000;\n\ntype PanelAppAgentBridgeSession = {\n panelAppId: string;\n};\n\nexport type NormalizedPanelAppGenerateObjectInput =\n Required<Pick<PanelAppAgentGenerateObjectInput, \"peerId\" | \"prompt\" | \"schema\" | \"timeoutMs\">> &\n Pick<PanelAppAgentGenerateObjectInput, \"context\" | \"title\">;\n\nexport function normalizePanelAppGenerateObjectInput(\n input: PanelAppAgentGenerateObjectInput,\n): NormalizedPanelAppGenerateObjectInput {\n const peerId = input.peerId.trim();\n const prompt = input.prompt.trim();\n if (!peerId || !prompt || !isRecord(input.schema)) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"invalid generateObject request\");\n }\n if (prompt.length > PANEL_APP_AGENT_MAX_PROMPT_CHARS) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"generateObject prompt is too large\");\n }\n const contextText = stringifyJsonValue(input.context ?? null);\n if (contextText.length > PANEL_APP_AGENT_MAX_CONTEXT_CHARS) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"generateObject context is too large\");\n }\n return {\n context: input.context,\n peerId,\n prompt,\n schema: input.schema,\n timeoutMs: normalizeTimeoutMs(input.timeoutMs),\n title: input.title?.trim() || undefined,\n };\n}\n\nexport function createPanelAppGenerateObjectMessage(params: {\n bridgeSession: PanelAppAgentBridgeSession;\n request: NormalizedPanelAppGenerateObjectInput;\n requestId: string;\n}): NcpOutboundMessageDraft {\n const { bridgeSession, request, requestId } = params;\n return {\n id: `panel-app-agent-message-${randomUUID()}`,\n metadata: {\n ...createPanelAppAgentMetadata(bridgeSession),\n panel_app_peer_id: request.peerId,\n structured_result: {\n request_id: requestId,\n schema: structuredClone(request.schema),\n tool_name: STRUCTURED_RESULT_TOOL_NAME,\n },\n },\n parts: [{\n type: \"text\",\n text: buildGenerateObjectPrompt(bridgeSession, request),\n }],\n role: \"user\",\n status: \"final\",\n timestamp: new Date().toISOString(),\n };\n}\n\nexport async function waitForPanelAppStructuredResult(\n agentRunClient: PanelAppAgentRunClient,\n params: {\n payload: AgentRunSendIngressPayload;\n timeoutMs: number;\n },\n): Promise<unknown> {\n const iterator = agentRunClient\n .sendAndStreamEvents(params.payload)\n [Symbol.asyncIterator]();\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => reject(new PanelAppError(\n \"AGENT_OBJECT_RESULT_TIMEOUT\",\n \"agent object result timed out\",\n )), params.timeoutMs);\n });\n let resultToolCallId: string | null = null;\n try {\n while (true) {\n const next = await Promise.race([iterator.next(), timeout]);\n if (next.done) {\n break;\n }\n const result = readStructuredResultEvent(next.value, resultToolCallId);\n if (result.matchedToolCallId) {\n resultToolCallId = result.matchedToolCallId;\n }\n if (result.submitted) {\n return result.content;\n }\n throwIfTerminalError(next.value);\n }\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n await iterator.return?.(undefined);\n }\n throw new PanelAppError(\n \"AGENT_OBJECT_RESULT_NOT_SUBMITTED\",\n \"agent did not submit a structured object result\",\n );\n}\n\nexport function withPanelAppAgentMetadata(\n payload: PanelAppAgentSendPayload,\n bridgeSession: PanelAppAgentBridgeSession,\n): AgentRunSendIngressPayload {\n const panelAppMetadata = createPanelAppAgentMetadata(bridgeSession);\n const peerId = readOptionalPeerId(payload.peerId);\n const sessionId = readOptionalSessionId(payload.sessionId);\n if (peerId && sessionId) {\n throw new PanelAppError(\n \"PANEL_APP_AGENT_REQUEST_INVALID\",\n \"agent send request cannot include both sessionId and peerId\",\n );\n }\n const metadata: Record<string, unknown> = {\n ...(payload.metadata ?? {}),\n ...panelAppMetadata,\n };\n if (peerId) {\n metadata.panel_app_peer_id = peerId;\n }\n if (Array.isArray(payload.content)) {\n return {\n content: structuredClone(payload.content),\n metadata,\n peerId,\n sessionId,\n };\n }\n if (!payload.message) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"agent send request is required\");\n }\n return {\n message: {\n ...structuredClone(payload.message),\n metadata: {\n ...(payload.message.metadata ?? {}),\n ...panelAppMetadata,\n },\n },\n metadata,\n peerId,\n sessionId,\n };\n}\n\nexport function createPanelAppAgentMetadata(\n bridgeSession: PanelAppAgentBridgeSession,\n): Record<string, unknown> {\n return {\n agent_peer_scope: `panel-app:${bridgeSession.panelAppId}`,\n panel_app_bridge_request_id: randomUUID(),\n panel_app_id: bridgeSession.panelAppId,\n source_kind: \"panel_app\",\n };\n}\n\nfunction normalizeTimeoutMs(timeoutMs: number | undefined): number {\n if (!Number.isFinite(timeoutMs) || typeof timeoutMs !== \"number\") {\n return PANEL_APP_AGENT_DEFAULT_TIMEOUT_MS;\n }\n return Math.min(\n PANEL_APP_AGENT_MAX_TIMEOUT_MS,\n Math.max(1000, Math.trunc(timeoutMs)),\n );\n}\n\nfunction readOptionalPeerId(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const peerId = value.trim();\n if (!peerId) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"agent peerId cannot be empty\");\n }\n return peerId;\n}\n\nfunction readOptionalSessionId(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const sessionId = value.trim();\n if (!sessionId) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"agent sessionId cannot be empty\");\n }\n return sessionId;\n}\n\nfunction buildGenerateObjectPrompt(\n bridgeSession: PanelAppAgentBridgeSession,\n request: NormalizedPanelAppGenerateObjectInput,\n): string {\n return [\n \"Panel App generateObject request\",\n \"\",\n `Panel App ID: ${bridgeSession.panelAppId}`,\n `Peer ID: ${request.peerId}`,\n \"\",\n \"Context JSON:\",\n stringifyJsonValue(request.context ?? null),\n \"\",\n \"Task:\",\n request.prompt,\n \"\",\n \"Result contract:\",\n `Call the ${STRUCTURED_RESULT_TOOL_NAME} tool exactly once with an object matching the provided schema.`,\n \"Do not use natural language as the result.\",\n ].join(\"\\n\");\n}\n\nfunction readStructuredResultEvent(\n event: NcpEndpointEvent,\n resultToolCallId: string | null,\n): {\n matchedToolCallId?: string;\n submitted: boolean;\n content?: unknown;\n} {\n if (\n event.type === NcpEventType.MessageToolCallStart &&\n event.payload.toolName === STRUCTURED_RESULT_TOOL_NAME\n ) {\n return { matchedToolCallId: event.payload.toolCallId, submitted: false };\n }\n if (\n event.type !== NcpEventType.MessageToolCallResult ||\n event.payload.toolCallId !== resultToolCallId\n ) {\n return { submitted: false };\n }\n assertToolResultContent(event.payload.content);\n return { content: event.payload.content, submitted: true };\n}\n\nfunction assertToolResultContent(content: unknown): void {\n if (!isRecord(content) || content.ok !== false || !isRecord(content.error)) {\n return;\n }\n const code = content.error.code;\n if (code === \"invalid_tool_arguments\") {\n throw new PanelAppError(\n \"AGENT_OBJECT_RESULT_SCHEMA_INVALID\",\n \"agent object result did not match the schema\",\n );\n }\n throw new PanelAppError(\n \"AGENT_OBJECT_REQUEST_FAILED\",\n typeof content.error.message === \"string\"\n ? content.error.message\n : \"agent object request failed\",\n );\n}\n\nfunction throwIfTerminalError(event: NcpEndpointEvent): void {\n if (event.type === NcpEventType.MessageFailed) {\n throw new PanelAppError(\"AGENT_OBJECT_REQUEST_FAILED\", event.payload.error.message);\n }\n if (event.type === NcpEventType.RunError) {\n throw new PanelAppError(\n \"AGENT_OBJECT_REQUEST_FAILED\",\n event.payload.error ?? \"agent object request failed\",\n );\n }\n if (event.type === NcpEventType.RunFinished) {\n throw new PanelAppError(\n \"AGENT_OBJECT_RESULT_NOT_SUBMITTED\",\n \"agent did not submit a structured object result\",\n );\n }\n}\n\nfunction stringifyJsonValue(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"value is not JSON serializable\");\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { randomUUID } from \"node:crypto\";\nimport { readFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n DEFAULT_PANELS_DIR,\n getWorkspacePathFromConfig,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { PanelAppAssetTokenService } from \"@kernel/services/panel-app-asset-token.service.js\";\nimport { PanelAppStateStore } from \"@kernel/stores/panel-app-state.store.js\";\nimport type { PanelAppPreferencesUpdate, PanelAppStateEntry } from \"@kernel/stores/panel-app-state.store.js\";\nimport { PanelAppCapabilityGrantStore } from \"@kernel/stores/panel-app-capability-grant.store.js\";\nimport type { ServiceActionCaller } from \"@kernel/types/service-app.types.js\";\nimport type {\n PanelAppAgentCapability,\n PanelAppAgentGenerateObjectInput,\n PanelAppAgentGenerateObjectResult,\n PanelAppAgentRunClient,\n PanelAppAgentSendPayload,\n PanelAppAgentSendResult,\n PanelAppCapabilityGrant,\n} from \"@kernel/types/panel-app.types.js\";\nimport {\n isPanelAppAgentCapability,\n isPanelAppError,\n PANEL_APP_AGENT_CAPABILITIES,\n PanelAppError,\n} from \"@kernel/types/panel-app.types.js\";\nimport { AgentRunClient } from \"@kernel/services/agent-run-client.service.js\";\nimport {\n getPanelAppBridgeScript,\n injectPanelAppBridgeScript,\n} from \"@kernel/utils/panel-app-bridge.utils.js\";\nimport { parsePanelAppManifest } from \"@kernel/utils/panel-app-manifest.utils.js\";\nimport {\n encodePanelAppId,\n injectPanelAppAssetBase,\n resolvePanelAppIconUrl,\n toPanelAppTitle,\n type PanelAppAsset,\n type PanelAppSource,\n} from \"@kernel/utils/panel-app-source.utils.js\";\nimport { PanelAppSourceService } from \"@kernel/services/panel-app-source.service.js\";\nimport {\n resolvePanelAppActivityMs,\n resolvePanelAppCreatedAt,\n} from \"@kernel/utils/panel-app-time.utils.js\";\nimport {\n createPanelAppAgentMetadata,\n createPanelAppGenerateObjectMessage,\n normalizePanelAppGenerateObjectInput,\n waitForPanelAppStructuredResult,\n withPanelAppAgentMetadata,\n} from \"@kernel/utils/panel-app-agent.utils.js\";\nimport type {\n EventBus,\n Ingress,\n} from \"@nextclaw/shared\";\n\nexport type { PanelAppPreferencesUpdate } from \"@kernel/stores/panel-app-state.store.js\";\n\nconst PANEL_APP_CONTENT_BASE_PATH = \"/api/panel-apps\";\nconst PANEL_APP_TOKENIZED_ASSET_BASE_PATH = \"/api/panel-app-assets\";\nconst PANEL_APP_CONTENT_TYPE = \"text/html; charset=utf-8\" as const;\nconst PANEL_APP_CAPABILITY_GRANTS_FILE_NAME = \".panel-app-capability-grants.json\";\n\nexport type PanelAppEntry = {\n id: string;\n fileName: string;\n kind: \"single-file\" | \"folder\";\n title: string;\n description?: string;\n icon?: string;\n contentPath: string;\n createdAt: string;\n updatedAt: string;\n sizeBytes: number;\n favorite: boolean;\n lastOpenedAt?: string;\n openCount: number;\n};\n\nexport type PanelAppList = {\n workspacePath: string;\n panelsPath: string;\n entries: PanelAppEntry[];\n};\n\nexport type PanelAppContent = {\n id: string;\n fileName: string;\n html: string;\n contentType: typeof PANEL_APP_CONTENT_TYPE;\n capabilities: string[];\n serviceActions: string[];\n};\n\nexport type PanelAppDeleteResult = {\n deleted: true;\n fileName: string;\n id: string;\n};\n\nexport type PanelAppBridgeSession = {\n id: string;\n token: string;\n panelAppId: string;\n tabId: string;\n caller: ServiceActionCaller;\n declaredCapabilities: string[];\n declaredActions: string[];\n createdAt: string;\n expiresAt: string;\n};\n\nexport class PanelAppManager {\n private readonly bridgeSessions = new Map<string, PanelAppBridgeSession>();\n private readonly agentRunClient: PanelAppAgentRunClient | null;\n private readonly assetTokenService = new PanelAppAssetTokenService();\n private readonly sourceService = new PanelAppSourceService();\n\n constructor(private readonly params: {\n agentRunClient?: PanelAppAgentRunClient;\n configManager: ConfigManager;\n eventBus?: EventBus;\n ingress?: Ingress;\n }) {\n this.agentRunClient = params.agentRunClient ??\n (params.eventBus && params.ingress\n ? new AgentRunClient({ eventBus: params.eventBus, ingress: params.ingress })\n : null);\n }\n\n listPanelApps = async (): Promise<PanelAppList> => {\n const workspacePath = this.getWorkspacePath();\n const panelsPath = this.getPanelsPath(workspacePath);\n const sources = await this.sourceService.listSources(panelsPath);\n const appState = await this.createStateStore(panelsPath).load();\n const entries = await Promise.all(\n sources.map((source) =>\n this.buildPanelAppEntry(\n source,\n appState[encodePanelAppId(source.sourceName)] ?? {},\n ),\n ),\n );\n\n return {\n workspacePath,\n panelsPath,\n entries: entries.sort(this.comparePanelApps),\n };\n };\n\n getPanelAppContent = async (id: string): Promise<PanelAppContent> => {\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n\n try {\n const source = await this.sourceService.resolveSource(panelsPath, id);\n const html = await readFile(source.entryPath, \"utf8\");\n const manifest = source.manifest ?? parsePanelAppManifest(html);\n const sourceId = encodePanelAppId(source.sourceName);\n const htmlWithBase = source.kind === \"folder\"\n ? injectPanelAppAssetBase(html, this.createAssetBaseHref(source))\n : html;\n return {\n id: sourceId,\n fileName: source.sourceName,\n html: injectPanelAppBridgeScript(htmlWithBase),\n capabilities: manifest.capabilities,\n contentType: PANEL_APP_CONTENT_TYPE,\n serviceActions: manifest.serviceActions,\n };\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (this.isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n getPanelAppAsset = async (id: string, assetPath: string): Promise<PanelAppAsset> => {\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n return await this.sourceService.getAsset(panelsPath, id, assetPath);\n };\n\n getPanelAppAssetByToken = async (\n token: string,\n assetPath: string,\n ): Promise<PanelAppAsset> => {\n const claims = this.assetTokenService.verify(token);\n if (encodePanelAppId(claims.sourceName) !== claims.panelAppId) {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_INVALID\",\n \"invalid panel app asset token\",\n );\n }\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n return await this.sourceService.getAsset(panelsPath, claims.panelAppId, assetPath);\n };\n\n getPanelAppBridgeScript = (): string => getPanelAppBridgeScript();\n\n createPanelAppBridgeSession = async (params: {\n id: string;\n tabId: string;\n }): Promise<PanelAppBridgeSession> => {\n const content = await this.getPanelAppContent(params.id);\n const now = new Date();\n const session: PanelAppBridgeSession = {\n id: randomUUID(),\n token: randomUUID(),\n panelAppId: content.id,\n tabId: params.tabId,\n caller: {\n surface: \"panel-app\",\n appId: content.id,\n },\n declaredCapabilities: content.capabilities,\n declaredActions: content.serviceActions,\n createdAt: now.toISOString(),\n expiresAt: new Date(now.getTime() + 60 * 60 * 1000).toISOString(),\n };\n this.bridgeSessions.set(session.token, session);\n return session;\n };\n\n resolvePanelAppBridgeSession = (token: string): PanelAppBridgeSession => {\n this.deleteExpiredBridgeSessions();\n const session = this.bridgeSessions.get(token.trim());\n if (!session) {\n throw new PanelAppError(\n \"PANEL_APP_BRIDGE_SESSION_NOT_FOUND\",\n \"panel app bridge session not found\",\n );\n }\n return session;\n };\n\n deletePanelAppBridgeSession = (token: string): void => {\n this.bridgeSessions.delete(token.trim());\n };\n\n sendAgentMessage = async (\n bridgeSessionToken: string,\n payload: PanelAppAgentSendPayload,\n ): Promise<PanelAppAgentSendResult> => {\n const bridgeSession = this.resolvePanelAppBridgeSession(bridgeSessionToken);\n await this.assertAgentCapabilityGranted(bridgeSession, \"agent:send\");\n return await this.requireAgentRunClient().send(\n withPanelAppAgentMetadata(payload, bridgeSession),\n );\n };\n\n generateAgentObject = async (\n bridgeSessionToken: string,\n input: PanelAppAgentGenerateObjectInput,\n ): Promise<PanelAppAgentGenerateObjectResult> => {\n const bridgeSession = this.resolvePanelAppBridgeSession(bridgeSessionToken);\n await this.assertAgentCapabilityGranted(bridgeSession, \"agent:generateObject\");\n const request = normalizePanelAppGenerateObjectInput(input);\n const requestId = randomUUID();\n const message = createPanelAppGenerateObjectMessage({\n bridgeSession,\n request,\n requestId,\n });\n const result = await waitForPanelAppStructuredResult(this.requireAgentRunClient(), {\n payload: {\n message,\n metadata: {\n ...createPanelAppAgentMetadata(bridgeSession),\n panel_app_peer_id: request.peerId,\n },\n peerId: request.peerId,\n },\n timeoutMs: request.timeoutMs,\n });\n return { result };\n };\n\n grantAgentCapability = async (\n bridgeSessionToken: string,\n capability: PanelAppAgentCapability,\n ): Promise<PanelAppCapabilityGrant> => {\n const bridgeSession = this.resolvePanelAppBridgeSession(bridgeSessionToken);\n if (!isPanelAppAgentCapability(capability)) {\n throw new PanelAppError(\n \"PANEL_APP_AGENT_REQUEST_INVALID\",\n \"unknown panel app agent capability\",\n );\n }\n this.assertDeclaredCapability(bridgeSession, capability);\n return await this.createCapabilityGrantStore().grant({\n caller: bridgeSession.caller,\n capability,\n grantedAt: new Date().toISOString(),\n });\n };\n\n updatePanelAppPreferences = async (\n id: string,\n preferences: PanelAppPreferencesUpdate,\n ): Promise<PanelAppEntry> => {\n const fileName = await this.resolvePanelAppFileName(id);\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n const state = await this.createStateStore(panelsPath).updatePreferences(\n encodePanelAppId(fileName),\n preferences,\n );\n return await this.buildPanelAppEntry(\n await this.sourceService.resolveSource(panelsPath, encodePanelAppId(fileName)),\n state,\n );\n };\n\n recordPanelAppOpened = async (id: string): Promise<PanelAppEntry> => {\n const fileName = await this.resolvePanelAppFileName(id);\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n const state = await this.createStateStore(panelsPath).recordOpened(\n encodePanelAppId(fileName),\n );\n return await this.buildPanelAppEntry(\n await this.sourceService.resolveSource(panelsPath, encodePanelAppId(fileName)),\n state,\n );\n };\n\n deletePanelApp = async (id: string): Promise<PanelAppDeleteResult> => {\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n const source = await this.sourceService.resolveSource(panelsPath, id);\n const panelAppId = encodePanelAppId(source.sourceName);\n await rm(source.sourcePath, { recursive: source.kind === \"folder\" });\n await this.createStateStore(panelsPath).deleteEntry(panelAppId);\n await this.createCapabilityGrantStore().deleteCaller({\n surface: \"panel-app\",\n appId: panelAppId,\n });\n this.deleteBridgeSessionsByPanelAppId(panelAppId);\n return { deleted: true, fileName: source.sourceName, id: panelAppId };\n };\n\n private assertAgentCapabilityGranted = async (\n bridgeSession: PanelAppBridgeSession,\n capability: PanelAppAgentCapability,\n ): Promise<void> => {\n this.assertDeclaredCapability(bridgeSession, capability);\n const granted = await this.createCapabilityGrantStore().isGranted(\n bridgeSession.caller,\n capability,\n );\n if (!granted) {\n throw new PanelAppError(\n \"AUTHORIZATION_REQUIRED\",\n `This panel app needs permission to use ${capability}.`,\n );\n }\n };\n\n private assertDeclaredCapability = (\n bridgeSession: PanelAppBridgeSession,\n capability: PanelAppAgentCapability,\n ): void => {\n if (!bridgeSession.declaredCapabilities.includes(capability)) {\n throw new PanelAppError(\n \"PANEL_APP_CAPABILITY_NOT_DECLARED\",\n this.describeMissingAgentCapability(bridgeSession.declaredCapabilities, capability),\n );\n }\n };\n\n private describeMissingAgentCapability = (\n declaredCapabilities: string[],\n capability: PanelAppAgentCapability,\n ): string => {\n const declared = declaredCapabilities.length > 0\n ? declaredCapabilities.join(\", \")\n : \"none\";\n const valid = PANEL_APP_AGENT_CAPABILITIES.join(\", \");\n const hint = declaredCapabilities.includes(capability.replace(\":\", \".\"))\n ? ` Use ${capability}, not ${capability.replace(\":\", \".\")}.`\n : \"\";\n return [\n `panel app did not declare ${capability}.`,\n `Declared: ${declared}.`,\n `Valid capabilities: ${valid}.`,\n `Declare it with nextclaw-panel-capabilities or panel-app.json capabilities.`,\n hint.trim(),\n ].filter(Boolean).join(\" \");\n };\n\n private requireAgentRunClient = (): PanelAppAgentRunClient => {\n if (!this.agentRunClient) {\n throw new PanelAppError(\n \"PANEL_APP_AGENT_REQUEST_INVALID\",\n \"panel app agent client is not configured\",\n );\n }\n return this.agentRunClient;\n };\n\n private getWorkspacePath = (): string =>\n getWorkspacePathFromConfig(this.params.configManager.config);\n\n private getPanelsPath = (workspacePath: string): string =>\n join(workspacePath, DEFAULT_PANELS_DIR);\n\n private createAssetBaseHref = (source: PanelAppSource): string => {\n const token = this.assetTokenService.issue({\n panelAppId: encodePanelAppId(source.sourceName),\n sourceName: source.sourceName,\n });\n return `${PANEL_APP_TOKENIZED_ASSET_BASE_PATH}/${encodeURIComponent(token)}/`;\n };\n\n private createStateStore = (panelsPath: string): PanelAppStateStore =>\n new PanelAppStateStore(panelsPath);\n\n private createCapabilityGrantStore = (): PanelAppCapabilityGrantStore =>\n new PanelAppCapabilityGrantStore(\n join(this.getPanelsPath(this.getWorkspacePath()), PANEL_APP_CAPABILITY_GRANTS_FILE_NAME),\n );\n\n private buildPanelAppEntry = async (\n source: PanelAppSource,\n state: PanelAppStateEntry,\n ): Promise<PanelAppEntry> => {\n const manifest = source.manifest ?? parsePanelAppManifest(await readFile(source.entryPath, \"utf8\"));\n const id = encodePanelAppId(source.sourceName);\n const createdAt = resolvePanelAppCreatedAt(source.sourceStat);\n const updatedAt = source.sourceStat.mtime.toISOString();\n const entry: PanelAppEntry = {\n id,\n fileName: source.sourceName,\n kind: source.kind,\n title: manifest.title ?? toPanelAppTitle(source.sourceName),\n contentPath: `${PANEL_APP_CONTENT_BASE_PATH}/${encodeURIComponent(id)}/content`,\n createdAt,\n updatedAt,\n sizeBytes: source.sourceStat.size,\n favorite: state.favorite ?? false,\n openCount: state.openCount ?? 0,\n };\n if (manifest.description) {\n entry.description = manifest.description;\n }\n if (manifest.icon) {\n entry.icon = source.kind === \"folder\"\n ? resolvePanelAppIconUrl(id, manifest.icon)\n : manifest.icon;\n }\n if (state.lastOpenedAt) {\n entry.lastOpenedAt = state.lastOpenedAt;\n }\n return entry;\n };\n\n private resolvePanelAppFileName = async (id: string): Promise<string> => {\n const source = await this.sourceService.resolveSource(\n this.getPanelsPath(this.getWorkspacePath()),\n id,\n );\n return source.sourceName;\n };\n\n private comparePanelApps = (left: PanelAppEntry, right: PanelAppEntry): number =>\n resolvePanelAppActivityMs(right) - resolvePanelAppActivityMs(left) ||\n Number(right.favorite) - Number(left.favorite) ||\n left.title.localeCompare(right.title);\n\n private deleteExpiredBridgeSessions = (): void => {\n const now = Date.now();\n for (const [token, session] of this.bridgeSessions) {\n if (new Date(session.expiresAt).getTime() <= now) {\n this.bridgeSessions.delete(token);\n }\n }\n };\n\n private deleteBridgeSessionsByPanelAppId = (panelAppId: string): void => {\n for (const [token, session] of this.bridgeSessions) {\n if (session.panelAppId === panelAppId) {\n this.bridgeSessions.delete(token);\n }\n }\n };\n\n private isMissingFileError = (error: unknown): boolean =>\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n","import type {\n ServiceActionCaller,\n ServiceActionGrantState,\n ServiceActionRisk,\n} from \"@kernel/types/service-app.types.js\";\n\nexport const DEFAULT_SERVICE_ACTION_RISK: ServiceActionRisk = \"dangerous\";\n\nexport function buildServiceActionId(appId: string, actionName: string): string {\n return `${appId}.${actionName}`;\n}\n\nexport function getServiceActionName(actionId: string, appId: string): string {\n const prefix = `${appId}.`;\n if (!actionId.startsWith(prefix)) {\n throw new Error(\"service action does not belong to service app.\");\n }\n const name = actionId.slice(prefix.length).trim();\n if (!name) {\n throw new Error(\"service action name is required.\");\n }\n return name;\n}\n\nexport function getServiceActionCallerKey(caller: ServiceActionCaller): string {\n return `${caller.surface}:${caller.appId}`;\n}\n\nexport function parseServiceActionCallerKey(key: string): ServiceActionCaller | null {\n const [surface, appId, ...rest] = key.split(\":\");\n if (surface !== \"panel-app\" || !appId || rest.length > 0) {\n return null;\n }\n return { surface, appId };\n}\n\nexport function resolveServiceActionGrantState({\n actionId,\n declaredActions,\n granted,\n}: {\n actionId: string;\n declaredActions?: readonly string[];\n granted: boolean;\n}): ServiceActionGrantState {\n if (declaredActions && !declaredActions.includes(actionId)) {\n return \"not-declared\";\n }\n return granted ? \"granted\" : \"not-granted\";\n}\n","import type { Config } from \"@nextclaw/core\";\nimport { McpServerLifecycleManager } from \"@nextclaw/mcp\";\nimport type { McpServerRecord, McpToolCatalogEntry } from \"@nextclaw/mcp\";\nimport type {\n ServiceAction,\n ServiceAppManifest,\n ServiceAppRecord,\n ServiceAppRuntimeStatus,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n buildServiceActionId,\n DEFAULT_SERVICE_ACTION_RISK,\n} from \"@kernel/utils/service-action.utils.js\";\n\ntype RuntimeState = {\n status: ServiceAppRuntimeStatus;\n lastError?: string;\n lastStartedAt?: string;\n lastReadyAt?: string;\n lastFailedAt?: string;\n};\n\nexport class McpServiceAppRuntimeService {\n private readonly lifecycleManager: McpServerLifecycleManager;\n private readonly states = new Map<string, RuntimeState>();\n\n constructor(private readonly params: { getConfig: () => Config }) {\n this.lifecycleManager = new McpServerLifecycleManager({\n getConfig: params.getConfig,\n });\n }\n\n getStatus = (appId: string): RuntimeState => {\n return this.states.get(appId) ?? { status: \"idle\" };\n };\n\n listActions = async ({\n app,\n manifest,\n }: {\n app: ServiceAppRecord;\n manifest: ServiceAppManifest;\n }): Promise<ServiceAction[]> => {\n if (!app.enabled) {\n return [];\n }\n const lastStartedAt = new Date().toISOString();\n this.states.set(app.id, { status: \"starting\", lastStartedAt });\n try {\n const state = await this.lifecycleManager.warmServer(\n this.toMcpServerRecord(app, manifest),\n );\n this.states.set(app.id, {\n status: \"running\",\n lastStartedAt,\n lastReadyAt: state.lastReadyAt,\n });\n return state.tools.map((tool) => this.toServiceAction(manifest, tool));\n } catch (error) {\n const lastError = error instanceof Error ? error.message : String(error);\n this.states.set(app.id, {\n status: \"failed\",\n lastError,\n lastStartedAt,\n lastFailedAt: new Date().toISOString(),\n });\n return [];\n }\n };\n\n invokeAction = async ({\n app,\n manifest,\n actionName,\n input,\n }: {\n app: ServiceAppRecord;\n manifest: ServiceAppManifest;\n actionName: string;\n input: Record<string, unknown>;\n }): Promise<unknown> => {\n const lastStartedAt = new Date().toISOString();\n this.states.set(app.id, { status: \"starting\", lastStartedAt });\n try {\n const result = await this.lifecycleManager.callTool(\n this.toMcpServerRecord(app, manifest),\n actionName,\n input,\n );\n this.states.set(app.id, {\n status: \"running\",\n lastStartedAt,\n lastReadyAt: new Date().toISOString(),\n });\n return result;\n } catch (error) {\n const lastError = error instanceof Error ? error.message : String(error);\n this.states.set(app.id, {\n status: \"failed\",\n lastError,\n lastStartedAt,\n lastFailedAt: new Date().toISOString(),\n });\n throw error;\n }\n };\n\n restart = async (appId: string): Promise<void> => {\n await this.lifecycleManager.closeServer(appId);\n this.states.set(appId, { status: \"idle\" });\n };\n\n dispose = async (): Promise<void> => {\n await this.lifecycleManager.closeAll();\n this.states.clear();\n };\n\n private toMcpServerRecord = (\n app: ServiceAppRecord,\n manifest: ServiceAppManifest,\n ): McpServerRecord => ({\n name: app.id,\n definition: {\n enabled: manifest.enabled,\n transport: {\n type: \"stdio\",\n command: manifest.command,\n args: manifest.args,\n cwd: app.dirPath,\n env: {},\n stderr: \"pipe\",\n },\n scope: {\n allAgents: false,\n agents: [],\n },\n policy: {\n trust: \"explicit\",\n start: \"eager\",\n },\n },\n });\n\n private toServiceAction = (\n manifest: ServiceAppManifest,\n tool: McpToolCatalogEntry,\n ): ServiceAction => {\n const actionId = buildServiceActionId(manifest.id, tool.toolName);\n const manifestAction = manifest.actions[tool.toolName];\n const risk = manifestAction?.risk ?? DEFAULT_SERVICE_ACTION_RISK;\n return {\n id: actionId,\n appId: manifest.id,\n name: tool.toolName,\n title: manifestAction?.title ?? tool.toolName,\n description: manifestAction?.description ?? tool.description,\n inputSchema: tool.parameters,\n risk,\n };\n };\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type {\n ServiceActionCaller,\n ServiceActionGrant,\n ServiceActionRisk,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n getServiceActionCallerKey,\n parseServiceActionCallerKey,\n} from \"@kernel/utils/service-action.utils.js\";\n\ntype StoredServiceActionGrant = {\n grantedAt: string;\n risk: ServiceActionRisk;\n};\n\ntype ServiceActionGrantStoreData = {\n version: 1;\n grants: Record<string, {\n actions: Record<string, StoredServiceActionGrant>;\n }>;\n};\n\nconst EMPTY_GRANTS: ServiceActionGrantStoreData = {\n version: 1,\n grants: {},\n};\n\nexport class ServiceActionGrantStore {\n constructor(private readonly storePath: string) {}\n\n isGranted = async (\n caller: ServiceActionCaller,\n actionId: string,\n ): Promise<boolean> => {\n const data = await this.load();\n return Boolean(data.grants[getServiceActionCallerKey(caller)]?.actions[actionId]);\n };\n\n grant = async ({\n actionId,\n caller,\n grantedAt,\n risk,\n }: {\n caller: ServiceActionCaller;\n actionId: string;\n risk: ServiceActionRisk;\n grantedAt: string;\n }): Promise<ServiceActionGrant> => {\n const data = await this.load();\n const callerKey = getServiceActionCallerKey(caller);\n const callerGrants = data.grants[callerKey] ?? { actions: {} };\n callerGrants.actions[actionId] = {\n grantedAt,\n risk,\n };\n data.grants[callerKey] = callerGrants;\n await this.save(data);\n return {\n caller,\n actionId,\n risk,\n grantedAt,\n };\n };\n\n list = async (): Promise<ServiceActionGrant[]> => {\n const data = await this.load();\n return Object.entries(data.grants).flatMap(([callerKey, callerGrants]) => {\n const caller = parseServiceActionCallerKey(callerKey);\n if (!caller) {\n return [];\n }\n return Object.entries(callerGrants.actions).map(([actionId, grant]) => ({\n caller,\n actionId,\n risk: grant.risk,\n grantedAt: grant.grantedAt,\n }));\n }).sort((left, right) =>\n new Date(right.grantedAt).getTime() - new Date(left.grantedAt).getTime()\n );\n };\n\n revoke = async (\n caller: ServiceActionCaller,\n actionId: string,\n ): Promise<void> => {\n const data = await this.load();\n const callerKey = getServiceActionCallerKey(caller);\n const callerGrants = data.grants[callerKey];\n if (!callerGrants) {\n return;\n }\n delete callerGrants.actions[actionId];\n if (Object.keys(callerGrants.actions).length === 0) {\n delete data.grants[callerKey];\n }\n await this.save(data);\n };\n\n revokeActionsByPrefix = async (actionIdPrefix: string): Promise<void> => {\n const data = await this.load();\n let changed = false;\n for (const [callerKey, callerGrants] of Object.entries(data.grants)) {\n for (const actionId of Object.keys(callerGrants.actions)) {\n if (actionId.startsWith(actionIdPrefix)) {\n delete callerGrants.actions[actionId];\n changed = true;\n }\n }\n if (Object.keys(callerGrants.actions).length === 0) {\n delete data.grants[callerKey];\n }\n }\n if (changed) {\n await this.save(data);\n }\n };\n\n private load = async (): Promise<ServiceActionGrantStoreData> => {\n try {\n return normalizeStoreData(JSON.parse(await readFile(this.storePath, \"utf8\")));\n } catch (error) {\n if (isMissingFileError(error)) {\n return structuredClone(EMPTY_GRANTS);\n }\n throw error;\n }\n };\n\n private save = async (data: ServiceActionGrantStoreData): Promise<void> => {\n await mkdir(dirname(this.storePath), { recursive: true });\n await writeFile(this.storePath, `${JSON.stringify(data, null, 2)}\\n`, \"utf8\");\n };\n}\n\nfunction normalizeStoreData(value: unknown): ServiceActionGrantStoreData {\n if (!isRecord(value) || value.version !== 1 || !isRecord(value.grants)) {\n return structuredClone(EMPTY_GRANTS);\n }\n const grants: ServiceActionGrantStoreData[\"grants\"] = {};\n for (const [callerKey, callerValue] of Object.entries(value.grants)) {\n if (!isRecord(callerValue) || !isRecord(callerValue.actions)) {\n continue;\n }\n const actions: Record<string, StoredServiceActionGrant> = {};\n for (const [actionId, actionValue] of Object.entries(callerValue.actions)) {\n if (\n isRecord(actionValue) &&\n typeof actionValue.grantedAt === \"string\" &&\n isServiceActionRisk(actionValue.risk)\n ) {\n actions[actionId] = {\n grantedAt: actionValue.grantedAt,\n risk: actionValue.risk,\n };\n }\n }\n grants[callerKey] = { actions };\n }\n return { version: 1, grants };\n}\n\nfunction isServiceActionRisk(value: unknown): value is ServiceActionRisk {\n return (\n value === \"read\" ||\n value === \"write\" ||\n value === \"external\" ||\n value === \"dangerous\"\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 isMissingFileError(error: unknown): boolean {\n return isRecord(error) && error.code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n ServiceActionRisk,\n ServiceAppManifest,\n ServiceAppManifestAction,\n} from \"@kernel/types/service-app.types.js\";\n\nconst SERVICE_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst SERVICE_ACTION_RISKS = new Set<ServiceActionRisk>([\n \"read\",\n \"write\",\n \"external\",\n \"dangerous\",\n]);\n\nexport const SERVICE_APP_MANIFEST_FILE_NAME = \"service-app.json\";\n\nexport function getServiceAppManifestPath(dirPath: string): string {\n return join(dirPath, SERVICE_APP_MANIFEST_FILE_NAME);\n}\n\nexport async function readServiceAppManifest(\n dirPath: string,\n): Promise<ServiceAppManifest> {\n return parseServiceAppManifest(\n await readFile(getServiceAppManifestPath(dirPath), \"utf8\"),\n );\n}\n\nexport function parseServiceAppManifest(raw: string): ServiceAppManifest {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new Error(\n `service-app.json is not valid JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n\n if (!isRecord(parsed)) {\n throw new Error(\"service-app.json must contain an object.\");\n }\n\n const id = readRequiredString(parsed, \"id\");\n if (!SERVICE_APP_ID_PATTERN.test(id)) {\n throw new Error(\"service app id must be kebab-case.\");\n }\n\n const protocol = readOptionalString(parsed, \"protocol\") ?? \"mcp\";\n if (protocol !== \"mcp\") {\n throw new Error(\"service app protocol must be mcp.\");\n }\n\n return {\n id,\n title: readRequiredString(parsed, \"title\"),\n description: readOptionalString(parsed, \"description\"),\n enabled: readOptionalBoolean(parsed, \"enabled\") ?? true,\n protocol,\n command: readRequiredString(parsed, \"command\"),\n args: readStringArray(parsed.args, \"args\"),\n actions: readManifestActions(parsed.actions),\n };\n}\n\nfunction readManifestActions(value: unknown): Record<string, ServiceAppManifestAction> {\n if (value === undefined) {\n throw new Error(\"service app actions are required.\");\n }\n if (!isRecord(value)) {\n throw new Error(\"service app actions must be an object.\");\n }\n if (Object.keys(value).length === 0) {\n throw new Error(\"service app actions cannot be empty.\");\n }\n\n const actions: Record<string, ServiceAppManifestAction> = {};\n for (const [name, action] of Object.entries(value)) {\n if (!name.trim()) {\n throw new Error(\"service app action name cannot be empty.\");\n }\n if (!isRecord(action)) {\n throw new Error(`service app action ${name} must be an object.`);\n }\n const risk = readOptionalString(action, \"risk\");\n if (risk !== undefined && !SERVICE_ACTION_RISKS.has(risk as ServiceActionRisk)) {\n throw new Error(`service app action ${name} has invalid risk.`);\n }\n const inputSchema = action.inputSchema;\n if (inputSchema !== undefined && !isRecord(inputSchema)) {\n throw new Error(`service app action ${name} inputSchema must be an object.`);\n }\n actions[name] = {\n risk: risk as ServiceActionRisk | undefined,\n title: readOptionalString(action, \"title\"),\n description: readOptionalString(action, \"description\"),\n inputSchema,\n };\n }\n return actions;\n}\n\nfunction readRequiredString(record: Record<string, unknown>, key: string): string {\n const value = readOptionalString(record, key);\n if (!value) {\n throw new Error(`service app ${key} is required.`);\n }\n return value;\n}\n\nfunction readOptionalString(\n record: Record<string, unknown>,\n key: string,\n): string | undefined {\n return typeof record[key] === \"string\" && record[key].trim()\n ? record[key].trim()\n : undefined;\n}\n\nfunction readOptionalBoolean(\n record: Record<string, unknown>,\n key: string,\n): boolean | undefined {\n if (record[key] === undefined) {\n return undefined;\n }\n if (typeof record[key] !== \"boolean\") {\n throw new Error(`service app ${key} must be boolean.`);\n }\n return record[key];\n}\n\nfunction readStringArray(value: unknown, key: string): string[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n throw new Error(`service app ${key} must be a string array.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n","import type {\n ServiceAction,\n ServiceAppManifest,\n ServiceAppRecord,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n buildServiceActionId,\n DEFAULT_SERVICE_ACTION_RISK,\n} from \"@kernel/utils/service-action.utils.js\";\n\nexport function listServiceAppManifestActions(\n record: ServiceAppRecord,\n manifest: ServiceAppManifest,\n): ServiceAction[] {\n if (!record.enabled) {\n return [];\n }\n return Object.entries(manifest.actions)\n .map(([name, action]) => ({\n id: buildServiceActionId(record.id, name),\n appId: record.id,\n name,\n title: action.title ?? name,\n description: action.description,\n inputSchema: action.inputSchema,\n risk: action.risk ?? DEFAULT_SERVICE_ACTION_RISK,\n }))\n .sort((left, right) => left.id.localeCompare(right.id));\n}\n\nexport function mergeServiceAppRuntimeActions({\n record,\n manifest,\n runtimeActions,\n}: {\n record: ServiceAppRecord;\n manifest: ServiceAppManifest;\n runtimeActions: ServiceAction[];\n}): ServiceAction[] {\n const runtimeByName = new Map(runtimeActions.map((action) => [action.name, action]));\n const declared = listServiceAppManifestActions(record, manifest).map((action) => {\n const runtimeAction = runtimeByName.get(action.name);\n return {\n ...action,\n description: runtimeAction?.description ?? action.description,\n inputSchema: runtimeAction?.inputSchema ?? action.inputSchema,\n runtimeState: runtimeAction ? \"matched\" as const : \"missing\" as const,\n };\n });\n const undeclared = runtimeActions\n .filter((action) => !Object.hasOwn(manifest.actions, action.name))\n .map((action) => ({\n ...action,\n risk: DEFAULT_SERVICE_ACTION_RISK,\n runtimeState: \"undeclared\" as const,\n }));\n return [...declared, ...undeclared].sort((left, right) => left.id.localeCompare(right.id));\n}\n","import { readdir, rm, stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\nimport {\n DEFAULT_SERVICE_APPS_DIR,\n getWorkspacePathFromConfig,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { McpServiceAppRuntimeService } from \"@kernel/services/mcp-service-app-runtime.service.js\";\nimport { ServiceActionGrantStore } from \"@kernel/stores/service-action-grant.store.js\";\nimport type {\n ServiceAction,\n ServiceActionCaller,\n ServiceActionGrant,\n ServiceActionGrantRequest,\n ServiceActionInvokeRequest,\n ServiceActionInvokeResult,\n ServiceAppManifest,\n ServiceAppRecord,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n getServiceAppManifestPath,\n readServiceAppManifest,\n} from \"@kernel/utils/service-app-manifest.utils.js\";\nimport {\n getServiceActionName,\n resolveServiceActionGrantState,\n} from \"@kernel/utils/service-action.utils.js\";\nimport {\n listServiceAppManifestActions,\n mergeServiceAppRuntimeActions,\n} from \"@kernel/utils/service-app-runtime-action.utils.js\";\n\nconst SERVICE_ACTION_GRANTS_FILE_NAME = \".service-action-grants.json\";\n\nexport type ServiceAppList = {\n workspacePath: string;\n serviceAppsPath: string;\n entries: ServiceAppRecord[];\n};\n\nexport type ServiceAppDeleteResult = {\n deleted: true;\n id: string;\n};\n\nexport type ServiceAppErrorCode =\n | \"AUTHORIZATION_REQUIRED\"\n | \"SERVICE_APP_ACTION_NOT_DECLARED\"\n | \"SERVICE_APP_ACTION_NOT_FOUND\"\n | \"SERVICE_APP_INVALID_ACTION\"\n | \"SERVICE_APP_INVALID_CALLER\"\n | \"SERVICE_APP_INVALID_MANIFEST\"\n | \"SERVICE_APP_NOT_FOUND\"\n | \"SERVICE_APP_READ_FAILED\"\n | \"SERVICE_APP_RUNTIME_FAILED\";\n\nexport class ServiceAppError extends Error {\n constructor(\n readonly code: ServiceAppErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ServiceAppError\";\n }\n}\n\nexport function isServiceAppError(error: unknown): error is ServiceAppError {\n return error instanceof ServiceAppError;\n}\n\nexport class ServiceAppManager {\n private readonly runtimeService: ServiceAppRuntime;\n\n constructor(private readonly params: {\n configManager: ConfigManager;\n runtimeService?: ServiceAppRuntime;\n }) {\n this.runtimeService = params.runtimeService ?? new McpServiceAppRuntimeService({\n getConfig: () => params.configManager.config,\n });\n }\n\n listServiceApps = async (): Promise<ServiceAppList> => {\n const workspacePath = this.getWorkspacePath();\n const serviceAppsPath = this.getServiceAppsPath(workspacePath);\n const dirNames = await this.listServiceAppDirNames(serviceAppsPath);\n const entries = await Promise.all(\n dirNames.map((dirName) => this.buildServiceAppRecord(serviceAppsPath, dirName)),\n );\n return {\n workspacePath,\n serviceAppsPath,\n entries: entries\n .filter((entry): entry is ServiceAppRecord => Boolean(entry))\n .sort((left, right) => left.title.localeCompare(right.title)),\n };\n };\n\n getServiceApp = async (appId: string): Promise<ServiceAppRecord> => {\n const { record } = await this.requireServiceApp(appId);\n return record;\n };\n\n listServiceActions = async (params: {\n caller?: ServiceActionCaller;\n appId?: string;\n declaredActions?: readonly string[];\n } = {}): Promise<ServiceAction[]> => {\n const manifests = params.appId\n ? [await this.requireServiceApp(params.appId)]\n : await this.listValidServiceApps();\n const actions = manifests.flatMap(({ manifest, record }) =>\n this.listManifestActions(record, manifest),\n );\n return await Promise.all(\n actions.map(async (action) => await this.withGrantState(action, params)),\n );\n };\n\n discoverServiceAppActions = async (appId: string): Promise<ServiceAction[]> => {\n const { manifest, record } = await this.requireServiceApp(appId);\n const runtimeActions = await this.runtimeService.listActions({ app: record, manifest });\n return mergeServiceAppRuntimeActions({ record, manifest, runtimeActions });\n };\n\n invokeServiceAction = async (\n actionId: string,\n request: ServiceActionInvokeRequest,\n ): Promise<ServiceActionInvokeResult> => {\n this.assertCaller(request.caller);\n this.assertDeclaredAction(actionId, request.declaredActions);\n const { manifest, record } = await this.requireServiceAppForAction(actionId);\n const actionName = getServiceActionName(actionId, record.id);\n if (!Object.hasOwn(manifest.actions, actionName)) {\n throw new ServiceAppError(\"SERVICE_APP_ACTION_NOT_FOUND\", \"service action not found\");\n }\n if (!await this.createGrantStore().isGranted(request.caller, actionId)) {\n throw new ServiceAppError(\n \"AUTHORIZATION_REQUIRED\",\n `This panel app needs permission to call ${actionId}.`,\n );\n }\n const result = await this.runtimeService.invokeAction({\n app: record,\n manifest,\n actionName,\n input: request.input ?? {},\n });\n return { actionId, result };\n };\n\n grantServiceAction = async (\n actionId: string,\n request: ServiceActionGrantRequest,\n ): Promise<ServiceActionGrant> => {\n const [grant] = await this.grantServiceActions([actionId], request);\n if (!grant) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_ACTION\", \"service action id is invalid\");\n }\n return grant;\n };\n\n grantServiceActions = async (\n actionIds: readonly string[],\n request: ServiceActionGrantRequest,\n ): Promise<ServiceActionGrant[]> => {\n this.assertCaller(request.caller);\n const normalizedActionIds = this.normalizeActionIds(actionIds);\n if (normalizedActionIds.length === 0) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_ACTION\", \"service action id is invalid\");\n }\n const actions: ServiceAction[] = [];\n for (const actionId of normalizedActionIds) {\n this.assertDeclaredAction(actionId, request.declaredActions);\n actions.push(await this.requireServiceAction(actionId));\n }\n const grantedAt = new Date().toISOString();\n const grantStore = this.createGrantStore();\n const grants: ServiceActionGrant[] = [];\n for (const action of actions) {\n grants.push(await grantStore.grant({\n caller: request.caller,\n actionId: action.id,\n risk: action.risk,\n grantedAt,\n }));\n }\n return grants;\n };\n\n listServiceActionGrants = async (): Promise<ServiceActionGrant[]> => {\n return await this.createGrantStore().list();\n };\n\n revokeServiceAction = async (\n caller: ServiceActionCaller,\n actionId: string,\n ): Promise<void> => {\n this.assertCaller(caller);\n await this.createGrantStore().revoke(caller, actionId);\n };\n\n restartServiceApp = async (appId: string): Promise<ServiceAppRecord> => {\n const { record } = await this.requireServiceApp(appId);\n await this.runtimeService.restart(record.id);\n return await this.getServiceApp(appId);\n };\n\n deleteServiceApp = async (appId: string): Promise<ServiceAppDeleteResult> => {\n const { record } = await this.requireServiceApp(appId);\n await this.runtimeService.restart(record.id);\n await rm(record.dirPath, { recursive: true });\n await this.createGrantStore().revokeActionsByPrefix(`${record.id}.`);\n return {\n deleted: true,\n id: record.id,\n };\n };\n\n dispose = async (): Promise<void> => {\n await this.runtimeService.dispose();\n };\n\n private withGrantState = async (\n action: ServiceAction,\n params: {\n caller?: ServiceActionCaller;\n declaredActions?: readonly string[];\n },\n ): Promise<ServiceAction> => {\n if (!params.caller) {\n return action;\n }\n const granted = await this.createGrantStore().isGranted(params.caller, action.id);\n return {\n ...action,\n grantState: resolveServiceActionGrantState({\n actionId: action.id,\n declaredActions: params.declaredActions,\n granted,\n }),\n };\n };\n\n private requireServiceAction = async (actionId: string): Promise<ServiceAction> => {\n const { manifest, record } = await this.requireServiceAppForAction(actionId);\n const action = this.listManifestActions(record, manifest)\n .find((entry) => entry.id === actionId);\n if (!action) {\n throw new ServiceAppError(\"SERVICE_APP_ACTION_NOT_FOUND\", \"service action not found\");\n }\n return action;\n };\n\n private requireServiceAppForAction = async (\n actionId: string,\n ): Promise<{ manifest: ServiceAppManifest; record: ServiceAppRecord }> => {\n const appId = actionId.split(\".\")[0]?.trim();\n if (!appId) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_ACTION\", \"service action id is invalid\");\n }\n return await this.requireServiceApp(appId);\n };\n\n private listManifestActions = (\n record: ServiceAppRecord,\n manifest: ServiceAppManifest,\n ): ServiceAction[] => listServiceAppManifestActions(record, manifest);\n\n private requireServiceApp = async (\n appId: string,\n ): Promise<{ manifest: ServiceAppManifest; record: ServiceAppRecord }> => {\n const serviceAppsPath = this.getServiceAppsPath(this.getWorkspacePath());\n const dirPath = join(serviceAppsPath, appId);\n try {\n const dirStat = await stat(dirPath);\n if (!dirStat.isDirectory()) {\n throw new ServiceAppError(\"SERVICE_APP_NOT_FOUND\", \"service app not found\");\n }\n const manifest = await readServiceAppManifest(dirPath);\n if (manifest.id !== appId) {\n throw new ServiceAppError(\n \"SERVICE_APP_INVALID_MANIFEST\",\n \"service app manifest id must match directory name\",\n );\n }\n return {\n manifest,\n record: this.toServiceAppRecord(dirPath, manifest),\n };\n } catch (error) {\n if (isServiceAppError(error)) {\n throw error;\n }\n if (this.isMissingFileError(error)) {\n throw new ServiceAppError(\"SERVICE_APP_NOT_FOUND\", \"service app not found\");\n }\n throw new ServiceAppError(\n \"SERVICE_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n private listValidServiceApps = async (): Promise<Array<{\n manifest: ServiceAppManifest;\n record: ServiceAppRecord;\n }>> => {\n const workspacePath = this.getWorkspacePath();\n const serviceAppsPath = this.getServiceAppsPath(workspacePath);\n const dirNames = await this.listServiceAppDirNames(serviceAppsPath);\n const entries = await Promise.all(\n dirNames.map(async (dirName) => {\n const dirPath = join(serviceAppsPath, dirName);\n try {\n const manifest = await readServiceAppManifest(dirPath);\n return {\n manifest,\n record: this.toServiceAppRecord(dirPath, manifest),\n };\n } catch {\n return null;\n }\n }),\n );\n return entries.filter((entry): entry is NonNullable<typeof entry> => Boolean(entry));\n };\n\n private buildServiceAppRecord = async (\n serviceAppsPath: string,\n dirName: string,\n ): Promise<ServiceAppRecord | null> => {\n const dirPath = join(serviceAppsPath, dirName);\n try {\n const manifest = await readServiceAppManifest(dirPath);\n return this.toServiceAppRecord(dirPath, manifest);\n } catch (error) {\n if (this.isMissingFileError(error)) {\n return null;\n }\n return {\n id: dirName,\n title: toTitle(dirName),\n dirPath,\n manifestPath: getServiceAppManifestPath(dirPath),\n cwd: dirPath,\n enabled: false,\n protocol: \"mcp\",\n status: \"failed\",\n lastError: error instanceof Error ? error.message : String(error),\n };\n }\n };\n\n private toServiceAppRecord = (\n dirPath: string,\n manifest: ServiceAppManifest,\n ): ServiceAppRecord => {\n const runtimeStatus = this.runtimeService.getStatus(manifest.id);\n const record: ServiceAppRecord = {\n id: manifest.id,\n title: manifest.title,\n dirPath,\n manifestPath: getServiceAppManifestPath(dirPath),\n command: manifest.command,\n args: manifest.args,\n cwd: dirPath,\n enabled: manifest.enabled,\n protocol: manifest.protocol,\n status: manifest.enabled ? runtimeStatus.status : \"stopped\",\n };\n if (manifest.description) {\n record.description = manifest.description;\n }\n if (runtimeStatus.lastError) {\n record.lastError = runtimeStatus.lastError;\n }\n if (runtimeStatus.lastStartedAt) {\n record.lastStartedAt = runtimeStatus.lastStartedAt;\n }\n if (runtimeStatus.lastReadyAt) {\n record.lastReadyAt = runtimeStatus.lastReadyAt;\n }\n if (runtimeStatus.lastFailedAt) {\n record.lastFailedAt = runtimeStatus.lastFailedAt;\n }\n return record;\n };\n\n private assertCaller = (caller: ServiceActionCaller): void => {\n if (caller.surface !== \"panel-app\" || !caller.appId.trim()) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_CALLER\", \"service action caller is invalid\");\n }\n };\n\n private assertDeclaredAction = (\n actionId: string,\n declaredActions: readonly string[],\n ): void => {\n if (!declaredActions.includes(actionId)) {\n throw new ServiceAppError(\n \"SERVICE_APP_ACTION_NOT_DECLARED\",\n \"panel app did not declare this service action\",\n );\n }\n };\n\n private normalizeActionIds = (actionIds: readonly string[]): string[] =>\n Array.from(new Set(\n actionIds\n .map((actionId) => actionId.trim())\n .filter((actionId) => actionId.length > 0),\n ));\n\n private getWorkspacePath = (): string =>\n getWorkspacePathFromConfig(this.params.configManager.config);\n\n private getServiceAppsPath = (workspacePath: string): string =>\n join(workspacePath, DEFAULT_SERVICE_APPS_DIR);\n\n private createGrantStore = (): ServiceActionGrantStore =>\n new ServiceActionGrantStore(\n join(this.getServiceAppsPath(this.getWorkspacePath()), SERVICE_ACTION_GRANTS_FILE_NAME),\n );\n\n private listServiceAppDirNames = async (\n serviceAppsPath: string,\n ): Promise<string[]> => {\n try {\n const entries = await readdir(serviceAppsPath, { withFileTypes: true });\n return entries\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith(\".\"))\n .map((entry) => entry.name);\n } catch (error) {\n if (this.isMissingFileError(error)) {\n return [];\n }\n throw new ServiceAppError(\n \"SERVICE_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n private isMissingFileError = (error: unknown): boolean =>\n Boolean(error) &&\n typeof error === \"object\" &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n\ntype ServiceAppRuntime = Pick<\n McpServiceAppRuntimeService,\n \"dispose\" | \"getStatus\" | \"invokeAction\" | \"listActions\" | \"restart\"\n>;\n\nfunction toTitle(value: string): string {\n return basename(value).replace(/[-_]+/g, \" \").trim() || value;\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n NcpEventType,\n type NcpAgentConversationStateManager,\n type NcpEndpointEvent,\n type NcpMessage,\n} from \"@nextclaw/ncp\";\nimport {\n eventKeys,\n type EventBus,\n} from \"@nextclaw/shared\";\nimport { DefaultNcpAgentConversationStateManager } from \"@nextclaw/ncp-toolkit\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.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 SessionRunEventPublishMeta = {\n emittedAt?: string;\n source: string;\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 eventBus?: EventBus,\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 applyAndPublishEvents = async (\n events: readonly NcpEndpointEvent[],\n meta: SessionRunEventPublishMeta,\n ): Promise<void> => {\n await this.applyEvents(events);\n for (const event of events) {\n this.eventBus?.emit(eventKeys.ncpEvent, event, {\n emittedAt: meta.emittedAt ?? new Date().toISOString(),\n source: meta.source,\n });\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 isRunning = (): boolean => this.activeRunId !== null;\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(\n private readonly sessionManager: SessionManager,\n private readonly eventBus?: EventBus,\n ) {}\n\n getSessionRun = (sessionId: string): SessionRun | null =>\n this.runs.get(sessionId) ?? null;\n\n isSessionRunning = (sessionId: string): boolean => this.runs.get(sessionId.trim())?.isRunning() ?? false;\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.sessionManager.listSessionMessages(sessionId);\n const seed = {\n messages,\n sessionId,\n };\n const run = new SessionRun(seed, this.eventBus);\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 { 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 type { NcpTool } from \"@nextclaw/ncp\";\nimport type {\n Config,\n SearchConfig,\n} from \"@nextclaw/core\";\nimport type {\n AgentRunRequest,\n ToolProvider,\n} from \"@kernel/types/agent-run.types.js\";\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 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 const seen = new Set<string>();\n for (const provider of [...this.providers]) {\n for (const tool of await provider.provide(request)) {\n if (seen.has(tool.name)) {\n continue;\n }\n seen.add(tool.name);\n tools.push(tool);\n }\n }\n return tools;\n };\n\n dispose = (): void => {\n this.providers.clear();\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 { 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 { SessionManager } from \"@kernel/managers/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 sessionManager: SessionManager;\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.sessionManager.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.sessionManager.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.sessionManager.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 { 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 {\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 { 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 { 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-provider.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 { 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 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/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/managers/agent-runtime.manager.js\";\nimport type { AgentRunSession } from \"@kernel/types/session.types.js\";\nimport type { AgentRunSpec } from \"@kernel/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 { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport { BuiltinNarpRuntimeProviderService } 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 { AgentRunMessageProjector } from \"@kernel/services/agent-run-message-projector.service.js\";\nimport { AgentRunModelInputBudgeter } from \"@kernel/services/agent-run-model-input-budgeter.service.js\";\nimport { AgentRunModelInputBuilder } from \"@kernel/services/agent-run-model-input-builder.service.js\";\nimport { NcpAgentRuntimeWrapper } from \"@kernel/services/ncp-agent-runtime-wrapper.service.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(private readonly kernel: NextclawKernel) {\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.kernel.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.kernel.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.kernel.sessionManager.getAgentRunSession(sessionRun.sessionId);\n return await this.kernel.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.kernel.agentRuntimeManager.register({\n kind: provider.kind,\n label: provider.label,\n defaultReuseScope: \"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 { AgentRunSession } from \"@kernel/types/session.types.js\";\nimport type { AgentRunRequest } from \"@kernel/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 type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type {\n AgentRunRequest,\n ContextBlock,\n ContextProvider,\n} from \"@kernel/types/agent-run.types.js\";\nimport { buildAgentRunRequestMetadata } from \"@kernel/utils/agent-run-request-metadata.utils.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(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly ContextBlock[]> => {\n const session = request.sessionId\n ? await this.kernel.sessionManager.getAgentRunSession(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 tools = await this.kernel.toolProviderManager.buildTools(request);\n\n return [\n this.buildSystemContextBlock({\n availableTools: buildToolCatalogEntries(\n tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n })),\n ),\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 { 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(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.unregister) {\n return;\n }\n this.unregister = this.kernel.contextProviderManager.register(\n new KernelContextProvider(this.kernel),\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 {\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(private readonly kernel: NextclawKernel) {\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.kernel.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(`[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.kernel.sessionRunManager.getSessionRun(sessionId);\n if (!sessionRun) {\n return;\n }\n const session = await this.kernel.sessionManager.getAgentRunSession(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: \"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 { 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 { SessionManager } from \"@kernel/managers/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 SessionManager,\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.sessionManager;\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 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.sessionManager.getSessionRecord(projection.sessionId);\n const nextMetadata = writeSessionActivityPreviewMetadata(session?.metadata, projection);\n if (!nextMetadata) {\n return;\n }\n await this.kernel.sessionManager.updateSessionMetadata(projection.sessionId, nextMetadata);\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { createAssetTools } from \"@kernel/features/native-runtime/index.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class AssetToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (_request: AgentRunRequest): Promise<readonly NcpTool[]> =>\n createAssetTools({ assetStore: this.kernel.assetStore });\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest } from \"@kernel/types/agent-run.types.js\";\nimport { buildAgentRunRequestMetadata } from \"@kernel/utils/agent-run-request-metadata.utils.js\";\nimport { resolveNextclawNcpRunContext } from \"@kernel/features/native-runtime/index.js\";\n\nexport type ToolProviderResolvedRunContext = Awaited<\n ReturnType<typeof resolveToolProviderRunContext>\n>;\n\nexport async function resolveToolProviderRunContext(params: {\n kernel: NextclawKernel;\n request: AgentRunRequest;\n}) {\n const { kernel, request } = params;\n const session = request.sessionId\n ? await kernel.sessionManager.getAgentRunSession(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: kernel.configManager,\n sessionId,\n requestMetadata,\n sessionMetadata: session?.metadata ?? requestMetadata,\n storedAgentId: request.agentId ?? session?.agentId,\n });\n return {\n requestMetadata,\n runContext,\n session,\n sessionId,\n toolRunContext: runContext.toolRunContext,\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport {\n EditFileTool,\n ExecTool,\n GatewayTool,\n ListDirTool,\n MemoryGetTool,\n MemorySearchTool,\n ReadFileTool,\n WebFetchTool,\n WebSearchTool,\n WriteFileTool,\n} from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class CoreToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n const {\n channel,\n chatId,\n execTimeoutSeconds,\n restrictToWorkspace,\n searchConfig,\n sessionId,\n workspace,\n } = toolRunContext;\n const allowedDir = restrictToWorkspace ? workspace : undefined;\n const execTool = new ExecTool({\n restrictToWorkspace,\n timeout: execTimeoutSeconds,\n workingDir: workspace,\n });\n execTool.setContext({ channel, chatId, sessionKey: sessionId });\n const gatewayTool = new GatewayTool(this.kernel.getGatewayController());\n gatewayTool.setContext({ sessionKey: sessionId });\n return [\n new ReadFileTool(allowedDir),\n new WriteFileTool(allowedDir),\n new EditFileTool(allowedDir),\n new ListDirTool(allowedDir),\n execTool,\n new WebSearchTool(searchConfig),\n new WebFetchTool(),\n new MemorySearchTool(workspace),\n new MemoryGetTool(workspace),\n gatewayTool,\n ];\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class McpToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n return this.kernel.mcpManager.listToolsForRun({ agentId: toolRunContext.agentId });\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport { normalizeString } from \"@kernel/utils/ncp-message-bridge.utils.js\";\nimport { CronTool, MessageTool } from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\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 MessagingToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n const { channel, chatId, metadata } = toolRunContext;\n const accountId = readMetadataAccountId(metadata);\n const messageTool = new MessageTool(\n async (message) => {\n const delivered = await this.kernel.channels.deliver(message);\n if (!delivered) {\n throw new Error(`channel \"${message.channel}\" is not available`);\n }\n },\n { resolveChannels: this.resolveMessageChannels },\n );\n messageTool.setContext(channel, chatId, accountId ?? null);\n const cronTool = new CronTool(this.kernel.automation);\n return [messageTool, 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","import { normalizeToolParams } from \"@nextclaw/core\";\nimport type { NcpMessage, NcpSessionSummary, NcpTool } from \"@nextclaw/ncp\";\nimport type { SessionManager } from \"@kernel/managers/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 implements NcpTool {\n readonly name = \"sessions_list\";\n readonly description = \"List available sessions with timestamps.\";\n readonly parameters = {\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 constructor(private readonly sessions: SessionManager) {}\n\n execute = async (args: unknown): Promise<string> => {\n const params = normalizeToolParams(args);\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 implements NcpTool {\n readonly name = \"sessions_history\";\n readonly description = \"Fetch recent messages from a session\";\n readonly parameters = {\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 constructor(private readonly sessions: SessionManager) {}\n\n execute = async (args: unknown): Promise<string> => {\n const params = normalizeToolParams(args);\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 {\n normalizeToolParams,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\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 implements NcpTool {\n readonly name = \"sessions_request\";\n readonly description =\n \"Send one task to another session. Use notify to control whether this session should continue after the target session finishes.\";\n readonly parameters = {\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 private sourceSessionId = \"\";\n private handoffDepth = 0;\n\n constructor(private readonly manager: SessionRequestManager) {}\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 (args: unknown, context?: ToolExecutionContext): Promise<unknown> => {\n const params = normalizeToolParams(args);\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\n return this.manager.requestSession({\n sourceSessionId: this.sourceSessionId,\n sourceToolCallId: context?.toolCallId,\n updateToolCallResult: context?.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 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 normalizeToolParams,\n type SessionRequestNotifyMode,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\nimport type { SessionManager } from \"@kernel/managers/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 implements NcpTool {\n readonly name = \"sessions_spawn\";\n readonly description =\n \"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 readonly parameters = {\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 private sourceSessionId = \"\";\n private sourceSessionMetadata: Record<string, unknown> = {};\n private handoffDepth = 0;\n\n constructor(\n private readonly sessionManager: SessionManager,\n private readonly sessionRequestManager: SessionRequestManager,\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 (args: unknown, context?: ToolExecutionContext): Promise<unknown> => {\n const params = normalizeToolParams(args);\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\n if (notify) {\n return this.sessionRequestManager.spawnSessionAndRequest({\n sourceSessionId: this.sourceSessionId,\n sourceToolCallId: context?.toolCallId,\n updateToolCallResult: context?.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,\n notify,\n });\n }\n\n const session = await this.sessionManager.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,\n });\n\n return {\n kind: \"nextclaw.session\",\n sessionId: session.sessionId,\n agentId: session.agentId,\n 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 { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport { SessionsHistoryTool, SessionsListTool } from \"@kernel/tools/session-history.tools.js\";\nimport { SessionRequestTool } from \"@kernel/tools/session-request.tools.js\";\nimport { SessionSearchTool } from \"@kernel/tools/session-search.tools.js\";\nimport { SessionSpawnTool } from \"@kernel/tools/session-spawn.tools.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class SessionToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n const { handoffDepth, metadata, sessionId } = toolRunContext;\n const sessionsSpawnTool = new SessionSpawnTool(\n this.kernel.sessionManager,\n this.kernel.sessionRequests,\n );\n sessionsSpawnTool.setContext({\n sourceSessionId: sessionId,\n sourceSessionMetadata: metadata,\n handoffDepth,\n });\n\n const sessionsRequestTool = new SessionRequestTool(this.kernel.sessionRequests);\n sessionsRequestTool.setContext({\n sourceSessionId: sessionId,\n handoffDepth,\n });\n const tools: NcpTool[] = [\n sessionsSpawnTool,\n sessionsRequestTool,\n new SessionsListTool(this.kernel.sessionManager),\n new SessionsHistoryTool(this.kernel.sessionManager),\n ];\n if (!this.kernel.sessionSearch.isReady()) {\n return tools;\n }\n tools.push(\n new SessionSearchTool(\n { search: this.kernel.sessionSearch.search },\n { currentSessionId: sessionId },\n ),\n );\n return tools;\n };\n}\n","import type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport {\n STRUCTURED_RESULT_TOOL_NAME,\n StructuredResultSubmitTool,\n type StructuredResultContract,\n} from \"@kernel/tools/structured-result.tools.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\ntype StructuredResultMetadata = {\n request_id?: unknown;\n schema?: unknown;\n tool_name?: unknown;\n};\n\nexport class StructuredResultToolProvider implements ToolProvider {\n provide = (request: AgentRunRequest): readonly NcpTool[] => {\n const contract = readStructuredResultContract(request.message.metadata);\n return contract ? [new StructuredResultSubmitTool(contract)] : [];\n };\n}\n\nfunction readStructuredResultContract(\n metadata: Record<string, unknown> | undefined,\n): StructuredResultContract | null {\n const value = metadata?.structured_result;\n if (!isRecord(value)) {\n return null;\n }\n const candidate = value as StructuredResultMetadata;\n if (\n candidate.tool_name !== STRUCTURED_RESULT_TOOL_NAME ||\n typeof candidate.request_id !== \"string\" ||\n !isRecord(candidate.schema)\n ) {\n return null;\n }\n return {\n requestId: candidate.request_id,\n schema: candidate.schema,\n toolName: STRUCTURED_RESULT_TOOL_NAME,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { AssetToolProvider } from \"./providers/asset-tool.provider.js\";\nimport { CoreToolProvider } from \"./providers/core-tool.provider.js\";\nimport { McpToolProvider } from \"./providers/mcp-tool.provider.js\";\nimport { MessagingToolProvider } from \"./providers/messaging-tool.provider.js\";\nimport { SessionToolProvider } from \"./providers/session-tool.provider.js\";\nimport { StructuredResultToolProvider } from \"./providers/structured-result-tool.provider.js\";\n\nexport class ToolProviderContribution implements KernelContribution {\n private readonly cleanups: Array<() => void> = [];\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.cleanups.length > 0) {\n return;\n }\n\n for (const provider of this.createToolProviders()) {\n this.cleanups.push(this.kernel.toolProviderManager.register(provider));\n }\n };\n\n dispose = (): void => {\n while (this.cleanups.length > 0) {\n this.cleanups.pop()?.();\n }\n };\n\n private createToolProviders = (): ToolProvider[] => [\n new StructuredResultToolProvider(),\n new CoreToolProvider(this.kernel),\n new MessagingToolProvider(this.kernel),\n new SessionToolProvider(this.kernel),\n new AssetToolProvider(this.kernel),\n new McpToolProvider(this.kernel),\n ];\n}\n","import { AgentManager } from \"@kernel/managers/agent.manager.js\";\nimport { AgentRunContextCompactionManager } from \"@kernel/managers/agent-run-context-compaction.manager.js\";\nimport { AgentRunRequestManager } from \"@kernel/managers/agent-run-request.manager.js\";\nimport { AgentRuntimeManager } from \"@kernel/managers/agent-runtime.manager.js\";\nimport { AccessManager } from \"@kernel/managers/access.manager.js\";\nimport { AutomationManager } from \"@kernel/managers/automation.manager.js\";\nimport { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { ContextProviderManager } from \"@kernel/managers/context-provider.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 { SessionManager } from \"@kernel/managers/session.manager.js\";\nimport { PanelAppManager } from \"@kernel/managers/panel-app.manager.js\";\nimport { ServiceAppManager } from \"@kernel/managers/service-app.manager.js\";\nimport { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport { SkillManager } from \"@kernel/managers/skill.manager.js\";\nimport { ToolProviderManager } from \"@kernel/managers/tool-provider.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 { AgentRunRuntimeContribution } from \"@kernel/contributions/agent-run-runtime/index.js\";\nimport { ContextProviderContribution } from \"@kernel/contributions/context-provider/index.js\";\nimport { ContextWindowContribution } from \"@kernel/contributions/context-window/index.js\";\nimport { LearningLoopContribution } from \"@kernel/contributions/learning-loop/index.js\";\nimport { SessionActivityPreviewContribution } from \"@kernel/contributions/session-activity-preview/index.js\";\nimport { ToolProviderContribution } from \"@kernel/contributions/tool-provider/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 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(\n options: NextclawKernelOptions,\n): 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<TGatewayInput, TUiInput, TStartInput> = {\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<TGatewayInput, TUiInput, TStartInput> {\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 accessManager: AccessManager;\n readonly agents: AgentManager;\n readonly control: NextclawKernelControlManager<unknown, unknown, unknown>;\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 sessionManager: SessionManager;\n readonly panelAppManager: PanelAppManager;\n readonly serviceAppManager: ServiceAppManager;\n readonly extensions: ExtensionManager;\n readonly agentRuntimeManager = new AgentRuntimeManager();\n readonly contextCompactionManager: AgentRunContextCompactionManager;\n readonly contextProviderManager = new ContextProviderManager();\n readonly sessionRunManager: SessionRunManager;\n readonly toolProviderManager = new ToolProviderManager();\n readonly agentRunRequestManager: AgentRunRequestManager;\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.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.channels = new ChannelManager({\n bus: this.messageBus,\n });\n this.configManager = new ConfigManager({\n configPath: options.configPath,\n channels: this.channels,\n providerManager: this.llmProviders,\n });\n this.accessManager = new AccessManager({\n configManager: this.configManager,\n homeDir: options.homeDir,\n });\n this.sessionManager = new SessionManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n journalStore: this.ncpAgentSessionJournalStore,\n sessionSearch: this.sessionSearch,\n });\n this.panelAppManager = new PanelAppManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n ingress: this.ingress,\n });\n this.serviceAppManager = new ServiceAppManager({\n configManager: this.configManager,\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.sessionManager,\n });\n this.skills = new SkillManager({\n workspace: getWorkspacePath(\n this.configManager.config.agents.defaults.workspace,\n ),\n });\n this.mcpManager = new McpManager(this.configManager.loadConfig);\n this.configManager.installRuntimeHooks({\n resolveChannelConfig: this.extensions.toConfigView,\n getExtensionChannels: () =>\n this.extensions.getExtensionRegistry().channels,\n reloadMcp: async ({ config }) =>\n await this.mcpManager.applyConfig(config),\n });\n this.sessionRequests = new SessionRequestManager({\n sessionManager: this.sessionManager,\n dispatcher: createAgentRuntimeSessionRequestDispatcher({\n eventBus: this.eventBus,\n ingress: this.ingress,\n }),\n });\n this.contextCompactionManager = new AgentRunContextCompactionManager(\n this.configManager,\n this.llmProviders,\n this.sessionManager,\n );\n this.sessionRunManager = new SessionRunManager(\n this.sessionManager,\n this.eventBus,\n );\n this.agentRunRequestManager = new AgentRunRequestManager(\n this.agentRuntimeManager,\n this.configManager,\n this.contextProviderManager,\n this.eventBus,\n this.ingress,\n this.sessionManager,\n this.sessionRunManager,\n this.toolProviderManager,\n );\n this.contributions = [\n new ToolProviderContribution(this),\n new SessionActivityPreviewContribution(this),\n new LearningLoopContribution(this),\n new ContextProviderContribution(this),\n new AgentRunRuntimeContribution(this),\n new ContextWindowContribution(this),\n ];\n }\n\n listSessionTypes = (params?: AgentRuntimeSessionTypeDescribeParams) =>\n this.agentRuntimeManager.listSessionTypes(params);\n\n isSessionRunning = (sessionId: string): boolean =>\n this.sessionRunManager.isSessionRunning(sessionId);\n\n provideGatewayController = (gatewayController: GatewayController): void => {\n this.gatewayController = gatewayController;\n };\n\n getGatewayController = (): GatewayController | undefined =>\n this.gatewayController;\n\n start = async (): Promise<void> => {\n void this.sessionSearch.start();\n this.mcpManager.start();\n this.sessionManager.start();\n for (const contribution of this.contributions) {\n contribution.start();\n }\n this.agentRunRequestManager.start();\n };\n\n dispose = async (): Promise<void> => {\n this.agentRunRequestManager.dispose();\n for (const contribution of [...this.contributions].reverse()) {\n await contribution.dispose();\n }\n this.toolProviderManager.dispose();\n this.contextProviderManager.dispose();\n await this.agentRuntimeManager.dispose();\n this.sessionRunManager.dispose();\n this.sessionManager.dispose();\n await this.mcpManager.dispose();\n await this.serviceAppManager.dispose();\n await this.sessionSearch.dispose();\n };\n}\n","import type { InboundAttachment } from \"@nextclaw/core\";\nimport type { NcpMessagePart } from \"@nextclaw/ncp\";\nimport type { AgentRunSendIngressPayload } from \"@nextclaw/shared\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\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\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","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 type { AgentRunClient } from \"@kernel/services/agent-run-client.service.js\";\nimport {\n buildAgentRunSendPayload,\n type AssetApi,\n} from \"@kernel/utils/agent-run-send-payload.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 createAssistantStreamDeltaControlMessage,\n createAssistantStreamResetControlMessage,\n createTypingStopControlMessage,\n type ChannelManager,\n type Config,\n type InboundMessage,\n type MessageBus,\n} from \"@nextclaw/core\";\nimport { CommandRegistry } from \"@kernel/services/command-registry.service.js\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.js\";\nimport { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport {\n dispatchChannelReplyRoute,\n resolveChannelReplyRoute,\n} from \"@kernel/features/ncp-dispatch/utils/channel-reply.utils.js\";\nimport {\n buildRunMetadata,\n} from \"@kernel/utils/agent-run-metadata.utils.js\";\nimport {\n buildAgentRunSendPayload,\n type AssetApi,\n} from \"@kernel/utils/agent-run-send-payload.utils.js\";\nimport type {\n AgentRunClient,\n AgentRunReply,\n} from \"@kernel/services/agent-run-client.service.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 =\n error instanceof Error\n ? error.message || error.name\n : 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 (\n await this.dispatchChannelReplyRouteMaybe(message, route, runMetadata)\n ) {\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(\n 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 {\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 );\n await this.publishChannelReply(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(\n this.runtime.configManager.loadConfig(),\n ).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 publishChannelReply = async (\n message: InboundMessage,\n route: GatewayRoute,\n result: AgentRunReply,\n ): Promise<void> => {\n if (message.channel === \"system\") {\n this.runtime.appEventBus?.emit(\n eventKeys.sessionUpdated,\n { sessionKey: route.sessionKey },\n {\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n },\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 parseAgentScopedSessionKey,\n type Config,\n type InboundAttachment,\n type InboundMessage,\n} from \"@nextclaw/core\";\nimport { CommandRegistry } from \"@kernel/services/command-registry.service.js\";\nimport type { AgentRunClient } from \"@kernel/services/agent-run-client.service.js\";\nimport { buildRunMetadata } from \"@kernel/utils/agent-run-metadata.utils.js\";\nimport { buildAgentRunSendPayload } from \"@kernel/utils/agent-run-send-payload.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":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["normalizeString","readRequestedAgentId","normalizeString","readOptionalString","readString","readStringArray","readRecord","readString","readRecord","readRequiredString","isRecord","isRecord","readOptionalString","readOptionalString","readEventSessionId","EMPTY_GRANTS","normalizeStoreData","isMissingFileError","isRecord","EMPTY_GRANTS","normalizeStoreData","isMissingFileError","isRecord","isRecord","isRecord","readOptionalString","readRequiredString","readStringArray","readOptionalBoolean","isMissingFileError","isRecord","isRecord","readRequiredString","readOptionalString","readOptionalBoolean","readString","parseYaml","isRecord","isRecord","isRecord","readRecord","readString","fsConstants","readOptionalString","readString","isRecord","readOptionalString","normalizeString","readString","readRequiredString","readOptionalString","isRecord","normalizeString","readOptionalString","ChannelManager","normalizeOptionalString","normalizeOptionalString","normalizeString"],"sources":["../src/managers/agent.manager.ts","../src/utils/ncp-message-bridge.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/agent-run-context-compaction.manager.ts","../src/managers/agent-run-request.manager.ts","../src/configs/agent-runtime.config.ts","../src/managers/agent-runtime.manager.ts","../src/utils/access-token.utils.ts","../src/stores/access-session.store.ts","../src/utils/access-password.utils.ts","../src/managers/access.manager.ts","../src/managers/automation.manager.ts","../src/managers/config.manager.ts","../src/managers/context-provider.manager.ts","../src/services/command-registry.service.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/types/llm-usage.types.ts","../src/stores/llm-usage.store.ts","../src/managers/llm-usage.manager.ts","../src/managers/mcp.manager.ts","../src/utils/ncp-agent-session-journal.utils.ts","../src/utils/agent-peer-session.utils.ts","../src/managers/session.manager.ts","../src/types/panel-app.types.ts","../src/services/panel-app-asset-token.service.ts","../src/stores/panel-app-state.store.ts","../src/stores/panel-app-capability-grant.store.ts","../src/stores/panel-app-client-grant.store.ts","../src/services/agent-run-client.service.ts","../src/tools/structured-result.tools.ts","../src/utils/panel-app-agent.utils.ts","../src/services/panel-app-agent-bridge.service.ts","../src/utils/panel-app-bridge.utils.ts","../src/utils/panel-app-client-injection.utils.ts","../src/utils/panel-app-manifest.utils.ts","../src/utils/panel-app-source.utils.ts","../src/services/panel-app-source.service.ts","../src/utils/panel-app-time.utils.ts","../src/utils/panel-app-content-source.utils.ts","../src/managers/panel-app.manager.ts","../src/utils/service-action.utils.ts","../src/services/mcp-service-app-runtime.service.ts","../src/stores/service-action-grant.store.ts","../src/utils/service-app-manifest.utils.ts","../src/utils/service-app-runtime-action.utils.ts","../src/managers/service-app.manager.ts","../src/managers/session-run.manager.ts","../src/utils/skill-frontmatter.utils.ts","../src/managers/skill.manager.ts","../src/managers/tool-provider.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/features/native-runtime/services/provider-manager-ncp-llm-api.service.ts","../src/features/native-runtime/tools/ncp-asset.tools.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/runtime-registry/services/agent-runtime-registry.service.ts","../src/services/agent-run-message-projector.service.ts","../src/services/agent-run-model-input-budgeter.service.ts","../src/services/agent-run-model-input-builder.service.ts","../src/services/ncp-agent-runtime-wrapper.service.ts","../src/contributions/agent-run-runtime/index.ts","../src/utils/agent-run-request-metadata.utils.ts","../src/contributions/context-provider/providers/kernel-context.provider.ts","../src/contributions/context-provider/index.ts","../src/contributions/context-window/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/contributions/tool-provider/providers/asset-tool.provider.ts","../src/contributions/tool-provider/utils/tool-provider-run-context.utils.ts","../src/contributions/tool-provider/providers/core-tool.provider.ts","../src/contributions/tool-provider/providers/mcp-tool.provider.ts","../src/contributions/tool-provider/providers/messaging-tool.provider.ts","../src/tools/session-history.tools.ts","../src/tools/session-request.tools.ts","../src/tools/session-search.tools.ts","../src/tools/session-spawn.tools.ts","../src/contributions/tool-provider/providers/session-tool.provider.ts","../src/contributions/tool-provider/providers/structured-result-tool.provider.ts","../src/contributions/tool-provider/index.ts","../src/app/nextclaw-kernel.ts","../src/utils/agent-run-send-payload.utils.ts","../src/features/ncp-dispatch/utils/channel-reply.utils.ts","../src/utils/agent-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 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 { 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 { type NcpMessage } from \"@nextclaw/ncp\";\nimport { ContextCompactionPreflightService } 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","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 type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { LlmProviderRuntime } from \"@kernel/managers/llm-provider.manager.js\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.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 sessionManager: SessionManager,\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.sessionManager.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 { catchError, from, lastValueFrom, tap } from \"rxjs\";\nimport { resolveDefaultAgentProfileId } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { AgentRuntimeManager } from \"./agent-runtime.manager.js\";\nimport type { ContextProviderManager } from \"./context-provider.manager.js\";\nimport type { SessionRunManager } from \"./session-run.manager.js\";\nimport type { ToolProviderManager } from \"./tool-provider.manager.js\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.js\";\nimport type {\n AgentRunAbortRequest,\n AgentRunAccepted,\n AgentRunRequest,\n AgentRunSpec,\n} from \"@kernel/types/agent-run.types.js\";\n\nfunction toAgentRunRequest(\n envelope: AgentRunSendIngressPayload,\n): AgentRunRequest {\n const metadata = envelope.metadata ?? {};\n const peerId = readOptionalString(envelope.peerId);\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 const sessionId = readOptionalString(envelope.sessionId);\n if (sessionId && peerId) {\n throw new Error(\"agent-run.send cannot accept both sessionId and peerId.\");\n }\n return {\n ...requestMetadata,\n sessionId,\n peerId,\n message: {\n sessionId: 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 envelopeSessionId = readOptionalString(envelope.sessionId);\n const messageSessionId = readOptionalString(sourceMessage.sessionId);\n const sessionId = envelopeSessionId ?? messageSessionId;\n if (sessionId && peerId) {\n throw new Error(\"agent-run.send cannot accept both sessionId and peerId.\");\n }\n const message: NcpMessage = {\n ...sourceMessage,\n sessionId: 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,\n peerId,\n message,\n };\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 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(\n messages: readonly NcpMessage[],\n messageId?: string,\n): NcpMessage | null {\n return (\n [...messages]\n .reverse()\n .find(\n (message) =>\n message.role === \"assistant\" &&\n message.status === \"final\" &&\n (!messageId || message.id === messageId),\n ) ?? null\n );\n}\n\nfunction readMessageTask(message: NcpMessage): string {\n return (\n message.parts.flatMap((part) =>\n (part.type === \"text\" ||\n part.type === \"rich-text\" ||\n part.type === \"reasoning\") &&\n part.text.trim()\n ? [part.text.trim()]\n : [],\n )[0] ?? \"Session\"\n );\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 sessionManager: SessionManager,\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(\n ingressKeys.agentRun.send,\n this.handleSendRequest,\n ),\n this.ingress.addHandler(\n ingressKeys.agentRun.abort,\n this.handleAbortRequest,\n ),\n this.ingress.addHandler(\n ingressKeys.agentRun.sessionMessageRequest,\n this.handleSessionMessageRequest,\n ),\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(\n await this.send({\n sessionId: envelope.payload.sessionId,\n message: {\n ...envelope.payload.message,\n sessionId: envelope.payload.sessionId,\n },\n correlationId: envelope.payload.requestId,\n }),\n );\n };\n\n private send = async (\n request: AgentRunRequest,\n ): Promise<AgentRunAccepted> => {\n const session = await this.sessionManager.getOrCreateAgentRunSession({\n sessionId: request.sessionId,\n peerId: request.peerId,\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 let stopPublishingRunStatus = (): void => undefined;\n stopPublishingRunStatus = sessionRun.onStatusChange((status) => {\n this.eventBus.emit(eventKeys.sessionRunStatus, {\n sessionKey: sessionRun.sessionId,\n status,\n }, {\n emittedAt: new Date().toISOString(),\n source: \"agent-run-request\",\n });\n if (status === \"idle\") {\n stopPublishingRunStatus();\n }\n });\n this.cleanups.push(stopPublishingRunStatus);\n const activeRun = (() => {\n try {\n return sessionRun.beginRun();\n } catch (error) {\n stopPublishingRunStatus();\n throw error;\n }\n })();\n\n const model =\n request.model ?? session.model ?? this.configManager.getDefaultModel();\n const agentId =\n request.agentId ??\n session.agentId ??\n resolveDefaultAgentProfileId(this.configManager.loadConfig());\n const spec: AgentRunSpec = {\n runId: activeRun.runId,\n agentId,\n model,\n maxTokens:\n 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 =\n await this.contextProviderManager.buildContext(providerRequest);\n const tools = await this.toolProviderManager.buildTools(providerRequest);\n let messageCompletedSeen = false;\n lastValueFrom(\n from(\n runtime.run(spec, {\n contextBlocks,\n sessionRun,\n signal: activeRun.signal,\n tools,\n }),\n ).pipe(\n tap((event) => {\n const eventsToPublish: NcpEndpointEvent[] = [];\n if (event.type === NcpEventType.MessageCompleted) {\n messageCompletedSeen = true;\n }\n if (\n event.type === NcpEventType.RunFinished &&\n !messageCompletedSeen\n ) {\n const message = findCompletedAssistantMessage(\n sessionRun.getSnapshot().messages,\n event.payload.messageId,\n );\n if (!message) {\n throw new Error(\n `Run finished without a final assistant message for session \"${session.sessionId}\".`,\n );\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","export const DEFAULT_AGENT_RUNTIME_ENTRY_ID = \"native\";\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/types/agent-run.types.js\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport type { AgentRunSession } from \"@kernel/types/session.types.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 { createHash, randomBytes } from \"node:crypto\";\n\nexport function createAccessSessionToken(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\nexport function hashAccessSessionToken(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"hex\");\n}\n\n","import type {\n AccessPrincipal,\n AccessSessionRecord,\n AccessSessionState,\n} from \"@kernel/types/access.types.js\";\nimport { hashAccessSessionToken } from \"@kernel/utils/access-token.utils.js\";\nimport { existsSync, chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst ACCESS_SESSION_STATE_VERSION = 1;\nconst ACCESS_SESSION_STATE_KIND = \"nextclaw.access.sessions\";\n\nfunction createEmptyState(): AccessSessionState {\n return {\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: [],\n };\n}\n\nfunction isAccessPrincipal(value: unknown): value is AccessPrincipal {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const record = value as { id?: unknown; role?: unknown };\n return typeof record.id === \"string\" && record.id.trim().length > 0 && record.role === \"admin\";\n}\n\nfunction parseAccessSessionRecord(value: unknown): AccessSessionRecord | null {\n if (!value || typeof value !== \"object\") {\n return null;\n }\n const record = value as {\n tokenHash?: unknown;\n principal?: unknown;\n createdAt?: unknown;\n expiresAt?: unknown;\n };\n if (\n typeof record.tokenHash !== \"string\" ||\n !record.tokenHash.trim() ||\n !isAccessPrincipal(record.principal) ||\n typeof record.createdAt !== \"string\" ||\n typeof record.expiresAt !== \"string\"\n ) {\n return null;\n }\n return {\n tokenHash: record.tokenHash,\n principal: record.principal,\n createdAt: record.createdAt,\n expiresAt: record.expiresAt,\n };\n}\n\nfunction parseAccessSessionState(value: unknown): AccessSessionState {\n if (!value || typeof value !== \"object\") {\n return createEmptyState();\n }\n const record = value as { version?: unknown; sessions?: unknown };\n if (\n (record as { kind?: unknown }).kind !== ACCESS_SESSION_STATE_KIND ||\n record.version !== ACCESS_SESSION_STATE_VERSION ||\n !Array.isArray(record.sessions)\n ) {\n return createEmptyState();\n }\n return {\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: record.sessions\n .map(parseAccessSessionRecord)\n .filter((session): session is AccessSessionRecord => session !== null),\n };\n}\n\nfunction isSessionActive(session: AccessSessionRecord, nowMs: number): boolean {\n const expiresAtMs = Date.parse(session.expiresAt);\n return Number.isFinite(expiresAtMs) && expiresAtMs > nowMs;\n}\n\nexport class AccessSessionStore {\n constructor(private readonly storePath: string) {}\n\n findPrincipalByToken = (token: string | null | undefined, now: Date): AccessPrincipal | null => {\n const normalizedToken = token?.trim();\n if (!normalizedToken) {\n return null;\n }\n const tokenHash = hashAccessSessionToken(normalizedToken);\n const nowMs = now.getTime();\n const session = this.readState().sessions.find(\n (entry) => entry.tokenHash === tokenHash && isSessionActive(entry, nowMs),\n );\n return session?.principal ?? null;\n };\n\n saveSession = (session: AccessSessionRecord, now: Date): void => {\n const activeSessions = this.readState().sessions.filter(\n (entry) => entry.tokenHash !== session.tokenHash && isSessionActive(entry, now.getTime()),\n );\n this.writeState({\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: [...activeSessions, session],\n });\n };\n\n deleteToken = (token: string | null | undefined): void => {\n const normalizedToken = token?.trim();\n if (!normalizedToken) {\n return;\n }\n const tokenHash = hashAccessSessionToken(normalizedToken);\n this.writeState({\n kind: ACCESS_SESSION_STATE_KIND,\n version: ACCESS_SESSION_STATE_VERSION,\n sessions: this.readState().sessions.filter((session) => session.tokenHash !== tokenHash),\n });\n };\n\n clear = (): void => {\n this.writeState(createEmptyState());\n };\n\n private readState = (): AccessSessionState => {\n if (!existsSync(this.storePath)) {\n return createEmptyState();\n }\n try {\n return parseAccessSessionState(JSON.parse(readFileSync(this.storePath, \"utf-8\")));\n } catch {\n return createEmptyState();\n }\n };\n\n private writeState = (state: AccessSessionState): void => {\n mkdirSync(dirname(this.storePath), { recursive: true });\n const temporaryPath = `${this.storePath}.${process.pid}.tmp`;\n writeFileSync(temporaryPath, JSON.stringify(state, null, 2), { mode: 0o600 });\n renameSync(temporaryPath, this.storePath);\n chmodSync(this.storePath, 0o600);\n };\n}\n","import { randomBytes, scryptSync, timingSafeEqual } from \"node:crypto\";\n\nexport function createAccessPasswordRecord(password: string): { passwordHash: string; passwordSalt: string } {\n const passwordSalt = randomBytes(16).toString(\"hex\");\n return {\n passwordHash: scryptAccessPassword(password, passwordSalt),\n passwordSalt,\n };\n}\n\nexport function verifyAccessPassword(password: string, expectedHash: string, salt: string): boolean {\n const actualHashBuffer = Buffer.from(scryptAccessPassword(password, salt), \"hex\");\n const expectedHashBuffer = Buffer.from(expectedHash, \"hex\");\n if (actualHashBuffer.length !== expectedHashBuffer.length) {\n return false;\n }\n return timingSafeEqual(actualHashBuffer, expectedHashBuffer);\n}\n\nfunction scryptAccessPassword(password: string, salt: string): string {\n return scryptSync(password, salt, 64).toString(\"hex\");\n}\n\n","import { ConfigSchema, getConfigPath, getDataDir, loadConfig, saveConfig, type Config } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { AccessSessionStore } from \"@kernel/stores/access-session.store.js\";\nimport type {\n AccessLoginResult,\n AccessPasswordStatus,\n AccessPrincipal,\n AccessSessionRecord,\n} from \"@kernel/types/access.types.js\";\nimport { createAccessPasswordRecord, verifyAccessPassword } from \"@kernel/utils/access-password.utils.js\";\nimport { createAccessSessionToken, hashAccessSessionToken } from \"@kernel/utils/access-token.utils.js\";\nimport { dirname, resolve } from \"node:path\";\n\nconst PASSWORD_MIN_LENGTH = 8;\nconst DEFAULT_ACCESS_SESSION_TTL_MS = 30 * 24 * 60 * 60 * 1000;\n\ntype AccessAuthConfig = Config[\"ui\"][\"auth\"];\n\nexport type AccessManagerOptions = {\n configManager?: ConfigManager;\n configPath?: string;\n homeDir?: string;\n sessionStorePath?: string;\n sessionTtlMs?: number;\n now?: () => Date;\n};\n\nfunction normalizeUsername(value: string): string {\n return value.trim();\n}\n\nfunction validateUsernameAndPassword(username: string, password: string): void {\n if (!username) {\n throw new Error(\"Username is required.\");\n }\n if (password.trim().length < PASSWORD_MIN_LENGTH) {\n throw new Error(`Password must be at least ${PASSWORD_MIN_LENGTH} characters.`);\n }\n}\n\nfunction resolveAccessSessionStorePath(options: AccessManagerOptions): string {\n const { configPath, homeDir, sessionStorePath } = options;\n if (sessionStorePath?.trim()) {\n return sessionStorePath.trim();\n }\n if (homeDir?.trim()) {\n return resolve(homeDir.trim(), \"access\", \"access-sessions.json\");\n }\n if (configPath?.trim()) {\n return resolve(dirname(configPath.trim()), \"access\", \"access-sessions.json\");\n }\n return resolve(getDataDir(), \"access\", \"access-sessions.json\");\n}\n\nexport class AccessManager {\n readonly sessions: AccessSessionStore;\n private readonly configPath: string;\n private readonly sessionTtlMs: number;\n private readonly now: () => Date;\n\n constructor(private readonly options: AccessManagerOptions = {}) {\n this.configPath = options.configManager?.configPath ?? options.configPath ?? getConfigPath();\n this.sessions = new AccessSessionStore(resolveAccessSessionStorePath({\n ...options,\n configPath: this.configPath,\n }));\n this.sessionTtlMs = Math.max(1, Math.trunc(options.sessionTtlMs ?? DEFAULT_ACCESS_SESSION_TTL_MS));\n this.now = options.now ?? (() => new Date());\n }\n\n isPasswordProtectionEnabled = (): boolean => {\n const auth = this.readAuthConfig();\n return Boolean(auth.enabled && this.isConfigured(auth));\n };\n\n authenticateSession = (token: string | null | undefined): AccessPrincipal | null => {\n const auth = this.readAuthConfig();\n if (!auth.enabled || !this.isConfigured(auth)) {\n return { id: \"admin\", role: \"admin\" };\n }\n return this.sessions.findPrincipalByToken(token, this.now());\n };\n\n getPasswordAuthStatus = (token: string | null | undefined): AccessPasswordStatus => {\n const auth = this.readAuthConfig();\n const configured = this.isConfigured(auth);\n const enabled = Boolean(auth.enabled && configured);\n const username = configured ? normalizeUsername(auth.username) : undefined;\n return {\n enabled,\n configured,\n authenticated: enabled ? this.sessions.findPrincipalByToken(token, this.now()) !== null : false,\n username,\n };\n };\n\n setupPasswordAdmin = async (input: { username: string; password: string }): Promise<AccessLoginResult> => {\n const config = this.loadCurrentConfig();\n const currentAuth = config.ui.auth;\n if (this.isConfigured(currentAuth)) {\n throw new Error(\"UI authentication is already configured.\");\n }\n\n const username = normalizeUsername(input.username);\n validateUsernameAndPassword(username, input.password);\n\n const nextPassword = createAccessPasswordRecord(input.password);\n config.ui.auth = {\n enabled: true,\n username,\n passwordHash: nextPassword.passwordHash,\n passwordSalt: nextPassword.passwordSalt,\n };\n await this.saveCurrentConfig(config, \"setup password access\");\n\n this.sessions.clear();\n return this.createLoginResult(username, true);\n };\n\n loginWithPassword = (input: { username: string; password: string }): AccessLoginResult => {\n const auth = this.readAuthConfig();\n if (!auth.enabled || !this.isConfigured(auth)) {\n throw new Error(\"UI authentication is not enabled.\");\n }\n\n const username = normalizeUsername(input.username);\n if (username !== normalizeUsername(auth.username) || !verifyAccessPassword(input.password, auth.passwordHash, auth.passwordSalt)) {\n throw new Error(\"Invalid username or password.\");\n }\n\n return this.createLoginResult(username, true);\n };\n\n logout = (token: string | null | undefined): void => {\n this.sessions.deleteToken(token);\n };\n\n updatePassword = async (input: { token: string | null | undefined; password: string }): Promise<AccessLoginResult> => {\n const config = this.loadCurrentConfig();\n const auth = config.ui.auth;\n if (!this.isConfigured(auth)) {\n throw new Error(\"UI authentication is not configured.\");\n }\n if (auth.enabled && this.sessions.findPrincipalByToken(input.token, this.now()) === null) {\n throw new Error(\"Authentication required.\");\n }\n\n const username = normalizeUsername(auth.username);\n validateUsernameAndPassword(username, input.password);\n\n const nextPassword = createAccessPasswordRecord(input.password);\n config.ui.auth = {\n enabled: auth.enabled,\n username: auth.username,\n passwordHash: nextPassword.passwordHash,\n passwordSalt: nextPassword.passwordSalt,\n };\n await this.saveCurrentConfig(config, \"update password access\");\n\n this.sessions.clear();\n if (!auth.enabled) {\n return {\n status: {\n enabled: false,\n configured: true,\n authenticated: false,\n username,\n },\n };\n }\n\n return this.createLoginResult(username, true);\n };\n\n setPasswordAuthEnabled = async (input: {\n token: string | null | undefined;\n enabled: boolean;\n }): Promise<AccessLoginResult> => {\n const config = this.loadCurrentConfig();\n const auth = config.ui.auth;\n const configured = this.isConfigured(auth);\n const currentlyEnabled = Boolean(auth.enabled && configured);\n\n if (currentlyEnabled && this.sessions.findPrincipalByToken(input.token, this.now()) === null) {\n throw new Error(\"Authentication required.\");\n }\n\n if (input.enabled && !configured) {\n throw new Error(\"UI authentication must be configured before it can be enabled.\");\n }\n\n config.ui.auth = {\n enabled: Boolean(input.enabled),\n username: auth.username,\n passwordHash: auth.passwordHash,\n passwordSalt: auth.passwordSalt,\n };\n await this.saveCurrentConfig(config, \"update password access enabled\");\n\n if (!input.enabled) {\n this.sessions.clear();\n return {\n status: {\n enabled: false,\n configured,\n authenticated: false,\n username: configured ? normalizeUsername(auth.username) : undefined,\n },\n };\n }\n\n return this.createLoginResult(normalizeUsername(auth.username), true);\n };\n\n createTrustedSession = (): AccessLoginResult | null => {\n const auth = this.readAuthConfig();\n if (!auth.enabled || !this.isConfigured(auth)) {\n return null;\n }\n return this.createLoginResult(normalizeUsername(auth.username), true);\n };\n\n private loadCurrentConfig = (): Config => {\n return this.options.configManager?.loadConfig() ?? loadConfig(this.configPath);\n };\n\n private saveCurrentConfig = async (config: Config, note: string): Promise<void> => {\n const parsed = ConfigSchema.parse(config);\n if (this.options.configManager) {\n await this.options.configManager.applyConfig(parsed, note);\n return;\n }\n saveConfig(parsed, this.configPath);\n };\n\n private readAuthConfig = (): AccessAuthConfig => {\n return this.loadCurrentConfig().ui.auth;\n };\n\n private isConfigured = (auth: AccessAuthConfig): boolean => {\n return Boolean(\n normalizeUsername(auth.username).length > 0 &&\n auth.passwordHash.trim().length > 0 &&\n auth.passwordSalt.trim().length > 0\n );\n };\n\n private createLoginResult = (username: string, authenticated: boolean): AccessLoginResult => {\n const session = this.createSession(username);\n return {\n status: {\n enabled: true,\n configured: true,\n authenticated,\n username,\n },\n token: session.token,\n expiresAt: session.record.expiresAt,\n };\n };\n\n private createSession = (username: string): { token: string; record: AccessSessionRecord } => {\n const token = createAccessSessionToken();\n const now = this.now();\n const expiresAt = new Date(now.getTime() + this.sessionTtlMs).toISOString();\n const record: AccessSessionRecord = {\n tokenHash: hashAccessSessionToken(token),\n principal: {\n id: username,\n role: \"admin\",\n },\n createdAt: now.toISOString(),\n expiresAt,\n };\n this.sessions.saveSession(record, now);\n return { token, record };\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 applyConfig = async (nextConfig: Config, note?: string): Promise<ConfigMutationResult> =>\n this.applyConfigChange({ nextConfig, note });\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 type {\n AgentRunRequest,\n ContextBlock,\n ContextProvider,\n} from \"@kernel/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 {\n CLEAR_THINKING_TOKENS,\n THINKING_LEVELS,\n parseThinkingLevel,\n type Config,\n} from \"@nextclaw/core\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.js\";\n\nexport type CommandOptionType = \"string\" | \"boolean\" | \"number\";\n\nexport type CommandOption = {\n name: string;\n description: string;\n type: CommandOptionType;\n required?: boolean;\n};\n\nexport type CommandExecutionContext = {\n channel: string;\n chatId: string;\n senderId: string;\n sessionKey?: string;\n};\n\nexport type CommandResult = {\n content: string;\n ephemeral?: boolean;\n};\n\nexport type ParsedTextCommand = {\n name: string;\n args: Record<string, unknown>;\n};\n\ntype CommandHandlerContext = CommandExecutionContext & {\n config: Config;\n sessionKey: string;\n};\n\ntype CommandSpec = {\n name: string;\n description: string;\n options?: CommandOption[];\n aliases?: string[];\n execute: (\n ctx: CommandHandlerContext,\n args: Record<string, unknown>,\n ) => Promise<CommandResult> | CommandResult;\n};\n\ntype SlashCommandSpec = {\n name: string;\n description: string;\n options?: CommandOption[];\n};\n\nconst DEFAULT_EPHEMERAL = true;\nconst CLEAR_MODEL_TOKENS = new Set([\"clear\", \"reset\", \"off\", \"none\"]);\n\nfunction normalizeCommandName(name: string): string {\n return name.trim().replace(/^\\//, \"\").toLowerCase();\n}\n\nfunction cloneSessionMetadata(metadata: Record<string, unknown> | undefined): Record<string, unknown> {\n return structuredClone(metadata ?? {});\n}\n\nexport class CommandRegistry {\n private readonly specs: CommandSpec[] = [];\n private readonly lookup = new Map<string, CommandSpec>();\n\n constructor(\n private readonly config: Config,\n private readonly sessionManager?: SessionManager,\n ) {\n this.registerDefaults();\n }\n\n listSlashCommands = (): SlashCommandSpec[] => {\n const commands: SlashCommandSpec[] = [];\n for (const spec of this.specs) {\n commands.push({\n description: spec.description,\n name: spec.name,\n options: spec.options,\n });\n for (const alias of spec.aliases ?? []) {\n commands.push({\n description: spec.description,\n name: alias,\n options: spec.options,\n });\n }\n }\n return commands;\n };\n\n execute = async (\n name: string,\n args: Record<string, unknown> | undefined,\n ctx: CommandExecutionContext,\n ): Promise<CommandResult> => {\n const trimmedName = normalizeCommandName(name);\n const spec = this.lookup.get(trimmedName);\n if (!spec) {\n return {\n content: `Unknown command: /${trimmedName}. Try /help for the command list.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const sessionKey = ctx.sessionKey ?? `${ctx.channel}:${ctx.chatId}`;\n return await spec.execute({\n ...ctx,\n config: this.config,\n sessionKey,\n }, args ?? {});\n };\n\n parseTextCommand = (input: string): ParsedTextCommand | null => {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) {\n return null;\n }\n const withoutSlash = trimmed.slice(1).trim();\n if (!withoutSlash) {\n return null;\n }\n const [nameToken, ...restTokens] = withoutSlash.split(/\\s+/);\n const name = normalizeCommandName(nameToken);\n if (!name) {\n return null;\n }\n const spec = this.lookup.get(name);\n const restText = restTokens.join(\" \").trim();\n return {\n args: spec ? this.parseTextArgs(spec, restText) : {},\n name,\n };\n };\n\n executeText = async (\n input: string,\n ctx: CommandExecutionContext,\n ): Promise<CommandResult | null> => {\n const parsed = this.parseTextCommand(input);\n if (!parsed) {\n return null;\n }\n return await this.execute(parsed.name, parsed.args, ctx);\n };\n\n private registerDefaults = (): void => {\n this.register({\n name: \"help\",\n description: \"Show available commands\",\n aliases: [\"commands\"],\n execute: () => ({\n content: this.buildHelpText(),\n ephemeral: DEFAULT_EPHEMERAL,\n }),\n });\n\n this.register({\n name: \"whoami\",\n description: \"Show your sender and session info\",\n aliases: [\"id\"],\n execute: (ctx) => ({\n content: [\n `Channel: ${ctx.channel}`,\n `Sender: ${ctx.senderId}`,\n `Chat: ${ctx.chatId}`,\n `Session: ${ctx.sessionKey}`,\n ].join(\"\\n\"),\n ephemeral: DEFAULT_EPHEMERAL,\n }),\n });\n\n this.register({\n name: \"status\",\n description: \"Show current session status\",\n execute: async (ctx) => {\n const session = await this.sessionManager?.getSessionRecord(ctx.sessionKey);\n const model = this.resolveSessionModel(session?.metadata);\n const thinking = this.resolveSessionThinking(session?.metadata);\n return {\n content: [\n `Session: ${ctx.sessionKey}`,\n `Model: ${model}`,\n `Thinking: ${thinking ? `${thinking} (session override)` : \"default\"}`,\n ].join(\"\\n\"),\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n\n this.register({\n name: \"reset\",\n description: \"Reset conversation history\",\n aliases: [\"new\"],\n execute: async (ctx) => {\n if (!this.sessionManager) {\n return { content: \"Session management is not available.\", ephemeral: DEFAULT_EPHEMERAL };\n }\n const totalCleared = await this.sessionManager.clearSessionMessages(ctx.sessionKey);\n return {\n content: `Conversation history cleared (${totalCleared} messages).`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n\n this.register({\n name: \"model\",\n description: \"Get or set the session model\",\n options: [{\n name: \"name\",\n description: \"Model name (or 'clear' to reset)\",\n type: \"string\",\n }],\n execute: async (ctx, args) => {\n if (!this.sessionManager) {\n return { content: \"Session management is not available.\", ephemeral: DEFAULT_EPHEMERAL };\n }\n const session = await this.getOrCreateCommandSession(ctx.sessionKey);\n const raw = typeof args.name === \"string\" ? args.name.trim() : \"\";\n if (!raw) {\n return {\n content: `Current model: ${this.resolveSessionModel(session.metadata)}`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const metadata = cloneSessionMetadata(session.metadata);\n if (CLEAR_MODEL_TOKENS.has(raw.toLowerCase())) {\n delete metadata.preferred_model;\n delete metadata.model;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: `Model override cleared. Current model: ${this.resolveSessionModel(metadata)}`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n metadata.preferred_model = raw;\n metadata.model = raw;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: `Model set to ${raw}.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n\n this.register({\n name: \"thinking\",\n description: \"Get or set the session thinking effort\",\n aliases: [\"effort\"],\n options: [{\n name: \"level\",\n description: `Thinking level (${THINKING_LEVELS.join(\"|\")} or clear/reset/default)`,\n type: \"string\",\n }],\n execute: async (ctx, args) => {\n if (!this.sessionManager) {\n return { content: \"Session management is not available.\", ephemeral: DEFAULT_EPHEMERAL };\n }\n const session = await this.getOrCreateCommandSession(ctx.sessionKey);\n const raw = typeof args.level === \"string\" ? args.level.trim() : \"\";\n if (!raw) {\n const current = this.resolveSessionThinking(session.metadata);\n return {\n content: current\n ? `Current thinking effort: ${current} (session override)`\n : \"Current thinking effort: default\",\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const normalized = raw.toLowerCase();\n const metadata = cloneSessionMetadata(session.metadata);\n if (CLEAR_THINKING_TOKENS.has(normalized)) {\n delete metadata.preferred_thinking;\n delete metadata.thinking;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: \"Thinking override cleared. Current thinking effort: default\",\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n const level = parseThinkingLevel(normalized);\n if (!level) {\n return {\n content: `Invalid thinking level: ${raw}. Allowed: ${THINKING_LEVELS.join(\", \")}. Use clear/reset/default to remove override.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n }\n metadata.preferred_thinking = level;\n metadata.thinking = level;\n await this.sessionManager.setSessionMetadata(session.sessionId, metadata);\n return {\n content: `Thinking effort set to ${level}.`,\n ephemeral: DEFAULT_EPHEMERAL,\n };\n },\n });\n };\n\n private register = (spec: CommandSpec): void => {\n const name = normalizeCommandName(spec.name);\n if (this.lookup.has(name)) {\n return;\n }\n const normalizedSpec: CommandSpec = { ...spec, name };\n this.specs.push(normalizedSpec);\n this.lookup.set(name, normalizedSpec);\n for (const alias of spec.aliases ?? []) {\n const normalized = normalizeCommandName(alias);\n if (!this.lookup.has(normalized)) {\n this.lookup.set(normalized, normalizedSpec);\n }\n }\n };\n\n private buildHelpText = (): string => {\n const lines = [\"Available commands:\"];\n const specs = [...this.specs].sort((a, b) => a.name.localeCompare(b.name));\n for (const spec of specs) {\n const optionText = (spec.options ?? [])\n .map((option) => `${option.required ? \"<\" : \"[\"}${option.name}${option.required ? \">\" : \"]\"}`)\n .join(\" \");\n const aliasText =\n spec.aliases && spec.aliases.length > 0 ? ` (alias: ${spec.aliases.map((alias) => `/${alias}`).join(\", \")})` : \"\";\n const usage = optionText ? `/${spec.name} ${optionText}` : `/${spec.name}`;\n lines.push(`${usage} - ${spec.description}${aliasText}`);\n }\n return lines.join(\"\\n\");\n };\n\n private getOrCreateCommandSession = async (sessionId: string) => {\n const sessionManager = this.sessionManager;\n if (!sessionManager) {\n throw new Error(\"Session management is not available.\");\n }\n const existing = await sessionManager.getSessionRecord(sessionId);\n if (existing) {\n return existing;\n }\n await sessionManager.createSession({\n sessionId,\n sourceSessionMetadata: {},\n task: \"Session\",\n });\n const created = await sessionManager.getSessionRecord(sessionId);\n if (!created) {\n throw new Error(`Session was not created: ${sessionId}`);\n }\n return created;\n };\n\n private resolveSessionModel = (metadata: Record<string, unknown> | undefined): string => {\n const preferred =\n metadata && typeof metadata.preferred_model === \"string\" ? metadata.preferred_model.trim() : \"\";\n return preferred || this.config.agents.defaults.model;\n };\n\n private resolveSessionThinking = (metadata: Record<string, unknown> | undefined): string | null => {\n if (!metadata) {\n return null;\n }\n return parseThinkingLevel(metadata.preferred_thinking);\n };\n\n private parseTextArgs = (spec: CommandSpec, raw: string): Record<string, unknown> => {\n if (!spec.options || spec.options.length === 0 || !raw) {\n return {};\n }\n const tokens = raw.split(/\\s+/).filter(Boolean);\n const args: Record<string, unknown> = {};\n let cursor = 0;\n for (let i = 0; i < spec.options.length; i += 1) {\n if (cursor >= tokens.length) {\n break;\n }\n const option = spec.options[i];\n const isLastOption = i === spec.options.length - 1;\n const rawValue = isLastOption ? tokens.slice(cursor).join(\" \") : tokens[cursor];\n cursor += isLastOption ? tokens.length - cursor : 1;\n const parsed = this.parseTextOptionValue(option.type, rawValue);\n if (parsed !== undefined) {\n args[option.name] = parsed;\n }\n }\n return args;\n };\n\n private parseTextOptionValue = (\n type: CommandOptionType,\n raw: string,\n ): string | number | boolean | undefined => {\n const value = raw.trim();\n if (!value) {\n return undefined;\n }\n if (type === \"number\") {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n if (type === \"boolean\") {\n return [\"true\", \"1\", \"yes\", \"on\"].includes(value.toLowerCase());\n }\n return value;\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 tokenForExtension: (extensionId: string) => 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 tokenForExtension: (extensionId: string) => 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.tokenForExtension(manifest.id),\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 PACKAGED_EXTENSION_DIR_ENV = \"NEXTCLAW_PACKAGED_EXTENSION_DIR\";\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 resolvePackagedExtensionManifestRoots(\n explicitDir = process.env[PACKAGED_EXTENSION_DIR_ENV],\n): string[] {\n const configured = explicitDir?.trim();\n return configured ? [resolve(configured)] : [];\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 ...resolvePackagedExtensionManifestRoots(),\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 } from \"@nextclaw/core\";\nimport { CommandRegistry } from \"@kernel/services/command-registry.service.js\";\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 private readonly lifecycle = new ExtensionLifecycleService();\n private readonly extensionTokens = new Map<string, string>();\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 tokenForExtension: this.getExtensionProcessToken,\n });\n if (running.length > 0) {\n console.log(`✓ Extensions started: ${running.map((entry) => entry.manifest.id).join(\", \")}`);\n }\n };\n\n getExtensionProcessToken = (extensionId: string): string => {\n const id = readRequiredString(extensionId, \"extensionId\");\n const current = this.extensionTokens.get(id);\n if (current) {\n return current;\n }\n const token = randomUUID();\n this.extensionTokens.set(id, token);\n return token;\n };\n\n authenticateEventStreamCredential = (input: {\n extensionId: string | null;\n token: string | null;\n }): { extensionId: string } | null => {\n const extensionId = readString(input.extensionId);\n const token = readString(input.token);\n if (!extensionId || !token || token !== this.extensionTokens.get(extensionId)) {\n return null;\n }\n return { extensionId };\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(envelope, 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(envelope, 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(envelope, 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(envelope, 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(envelope, 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 = (envelope: IngressEnvelope<unknown>, context: IngressContext): void => {\n const extensionId = readString(envelope.extensionId);\n if (!extensionId || context.token !== this.extensionTokens.get(extensionId)) {\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} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport type { SessionManager } from \"@kernel/managers/session.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 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 authenticateEventStreamCredential = (input: {\n extensionId: string | null;\n token: string | null;\n }): { extensionId: string } | null =>\n this.runtime.authenticateEventStreamCredential(input);\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 normalizeProviderModelConfig,\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 providerId: string | null;\n providerName: string | null;\n provider: ProviderConfig | null;\n apiBase: string | null;\n modelConfig?: ProviderConfig[\"modelConfig\"];\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 const trimmed = typeof value === \"string\" ? value.trim() : \"\";\n return 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 model: route?.model ?? params.model,\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 model: route?.model ?? params.model,\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 providerId: input.providerName,\n provider: {\n enabled: true,\n providerType: input.providerName,\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 route = this.resolveProvider(effectiveModel);\n const { provider, name } = route;\n const providerSpec = name ? this.providerRegistry.findProviderByName(name) : undefined;\n const specModelConfig = normalizeProviderModelConfig(providerSpec?.modelConfig ?? {});\n const providerModelConfig = this.normalizeProviderModelConfigForRoute(\n provider?.modelConfig ?? {},\n route.providerId,\n name\n );\n return {\n model: route.model,\n providerId: route.providerId,\n providerName: name,\n provider,\n apiBase: provider?.apiBase ?? providerSpec?.defaultApiBase ?? null,\n modelConfig: { ...specModelConfig, ...providerModelConfig },\n };\n };\n\n private resolveProvider = (model: string): {\n provider: ProviderConfig | null;\n name: string | null;\n providerId: string | null;\n model: string;\n } => {\n const providers = this.config?.providers as Record<string, ProviderConfig> | undefined;\n if (!providers) {\n return { provider: null, name: null, providerId: null, model };\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, model);\n if (prefixed) {\n return prefixed;\n }\n }\n\n const keywordMatches = Object.entries(providers)\n .map(([providerId, provider]) => {\n const providerType = this.resolveProviderType(providerId, provider);\n const spec = providerType ? this.providerRegistry.findProviderByName(providerType) : undefined;\n return { name: providerType, providerId, provider, spec };\n })\n .filter((entry): entry is { name: string; providerId: string; provider: ProviderConfig; spec: NonNullable<ReturnType<ProviderRegistry[\"findProviderByName\"]>> } => Boolean(entry.name && entry.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 const providerId = match.providerId;\n return { provider: match.provider ?? null, name: match.name, providerId, model: this.rewriteModelForTemplate(model, providerId, match.name) };\n }\n if (keywordMatches.length > 1) {\n return { provider: null, name: null, providerId: null, model };\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 const providerType = this.resolveProviderType(name, provider);\n return { provider, name: providerType, providerId: name, model: this.rewriteModelForTemplate(model, name, providerType) };\n }\n const enabledCustom = enabledProviders.filter(([name]) => !builtinNames.has(name));\n if (enabledCustom.length === 1) {\n const [name, provider] = enabledCustom[0];\n const providerType = this.resolveProviderType(name, provider);\n return { provider, name: providerType, providerId: name, model: this.rewriteModelForTemplate(model, name, providerType) };\n }\n return { provider: null, name: null, providerId: null, model };\n };\n\n private matchPrefixedProvider = (\n providers: Record<string, ProviderConfig>,\n modelPrefix: string,\n model: string\n ): { provider: ProviderConfig | null; name: string | null; providerId: string | null; model: string } | null => {\n const customProvider = Object.entries(providers)\n .find(([name]) => name.toLowerCase() === modelPrefix);\n if (!customProvider) {\n return null;\n }\n const [providerId, provider] = customProvider;\n if (provider.enabled === false) {\n return { provider: null, name: null, providerId, model };\n }\n const providerType = this.resolveProviderType(providerId, provider);\n return {\n provider,\n name: providerType,\n providerId,\n model: this.rewriteModelForTemplate(model, providerId, providerType),\n };\n };\n\n private resolveProviderType = (providerId: string, provider: ProviderConfig): string | null => {\n const configuredType = typeof provider.providerType === \"string\" ? provider.providerType.trim() : \"\";\n if (configuredType && this.providerRegistry.findProviderByName(configuredType)) {\n return configuredType;\n }\n return this.providerRegistry.findProviderByName(providerId) ? providerId : null;\n };\n\n private rewriteModelForTemplate = (model: string, providerId: string, providerType: string | null): string => {\n const prefix = `${providerId}/`;\n if (!model.startsWith(prefix)) {\n return model;\n }\n const suffix = model.slice(prefix.length).trim();\n if (!suffix) {\n return model;\n }\n return providerType ? `${providerType}/${suffix}` : suffix;\n };\n\n private normalizeProviderModelConfigForRoute = (\n modelConfig: ProviderConfig[\"modelConfig\"],\n providerId: string | null,\n providerType: string | null,\n ): ProviderConfig[\"modelConfig\"] => {\n const normalized = normalizeProviderModelConfig(modelConfig ?? {});\n if (!providerId || !providerType) {\n return normalized;\n }\n const rewritten: ProviderConfig[\"modelConfig\"] = {};\n for (const [model, config] of Object.entries(normalized)) {\n rewritten[this.rewriteModelForTemplate(model, providerId, providerType)] = config;\n }\n return rewritten;\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?.modelConfig,\n }),\n });\n };\n\n private buildCacheKey = (route: ProviderRoute): string => {\n const routeProvider = route.provider;\n return [\n route.providerName ?? \"\",\n route.providerId ?? \"\",\n routeProvider?.apiKey ?? \"\",\n route.apiBase ?? \"\",\n routeProvider?.wireApi ?? \"\",\n headersFingerprint(routeProvider?.extraHeaders ?? null),\n ].join(\"||\");\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 { 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 = record.messages.reduceRight<string | undefined>(\n (timestamp, message) => timestamp ?? readMessageTimestamp(message),\n undefined);\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 message?.status === \"final\" ? toIsoString(message.timestamp, \"\") || undefined : 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 if (\n event.type === NcpEventType.MessageSent ||\n event.type === NcpEventType.MessageCompleted ||\n event.type === NCP_AGENT_SESSION_SNAPSHOT_MESSAGE_EVENT_TYPE\n ) {\n return event.payload.message;\n }\n return undefined;\n}\n","import { createHash } from \"node:crypto\";\nimport { BUILTIN_MAIN_AGENT_ID } from \"@nextclaw/core\";\n\nexport const AGENT_RUN_PEER_ID_METADATA_KEY = \"agent_peer_id\";\nexport const AGENT_RUN_PEER_SCOPE_METADATA_KEY = \"agent_peer_scope\";\n\nexport type AgentPeerSessionIdentity = {\n metadata: Record<string, unknown>;\n sessionId: string;\n};\n\nexport function createAgentPeerSessionIdentity(params: {\n agentId?: string;\n channel?: string;\n metadata?: Record<string, unknown>;\n peerId: string;\n}): AgentPeerSessionIdentity {\n const scope = resolveAgentPeerScope(params);\n return {\n metadata: {\n [AGENT_RUN_PEER_ID_METADATA_KEY]: params.peerId,\n [AGENT_RUN_PEER_SCOPE_METADATA_KEY]: scope,\n },\n sessionId: `agent-peer-${createHash(\"sha256\")\n .update(`${scope}\\0${params.peerId}`)\n .digest(\"hex\")\n .slice(0, 32)}`,\n };\n}\n\nfunction resolveAgentPeerScope(params: {\n agentId?: string;\n channel?: string;\n metadata?: Record<string, unknown>;\n}): string {\n const metadata = params.metadata ?? {};\n const explicitScope =\n readOptionalString(metadata[AGENT_RUN_PEER_SCOPE_METADATA_KEY]) ??\n readOptionalString(metadata.agentPeerScope);\n if (explicitScope) {\n return explicitScope;\n }\n const agentId = readOptionalString(params.agentId) ?? BUILTIN_MAIN_AGENT_ID;\n const channel =\n readOptionalString(params.channel) ??\n readOptionalString(metadata.channel) ??\n \"agent-run\";\n const accountId =\n readOptionalString(metadata.accountId) ??\n readOptionalString(metadata.account_id) ??\n \"default\";\n return `agent:${agentId}:${channel}:${accountId}`;\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","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 NcpEndpointEvent,\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 { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport { ContextWindowPreviewManager } from \"@kernel/features/context-compaction/index.js\";\nimport type { NcpAgentSessionJournalStore } from \"@kernel/stores/ncp-agent-session-journal.store.js\";\nimport type {\n AgentRunSession,\n CreateAgentRunSessionParams,\n} from \"@kernel/types/session.types.js\";\nimport type { ThinkingEffort } from \"@kernel/types/agent-run.types.js\";\nimport {\n createNcpAgentSessionSummary,\n type NcpAgentSessionJournalReplayEvent,\n} from \"@kernel/utils/ncp-agent-session-journal.utils.js\";\nimport { createAgentPeerSessionIdentity } from \"@kernel/utils/agent-peer-session.utils.js\";\nimport {\n eventKeys,\n type EventBus,\n} 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 SessionManagerOptions = {\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 readOptionalMetadataString(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 ? readOptionalMetadataString(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 readOptionalMetadataString(metadata?.thinkingEffort) ?? null;\n}\n\nfunction readProjectRoot(metadata: Record<string, unknown> | undefined): string | undefined {\n return readOptionalMetadataString(metadata?.project_root) ?? readOptionalMetadataString(metadata?.projectRoot);\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 SessionManager implements NcpSessionApi {\n readonly cleanups: Array<() => void> = [];\n private readonly contextWindowPreview: ContextWindowPreviewManager;\n private started = false;\n\n constructor(private readonly options: SessionManagerOptions) {\n this.contextWindowPreview = new ContextWindowPreviewManager({\n configManager: options.configManager,\n });\n }\n\n start = (): void => {\n if (this.started) {\n return;\n }\n this.started = true;\n this.cleanups.push(this.options.eventBus.on(eventKeys.ncpEvent, async (event) => {\n const sessionId = readEventSessionId(event);\n if (!sessionId || !isDurableSessionEvent(event)) {\n return;\n }\n await this.appendSessionEvent({\n event,\n sessionId,\n });\n }));\n };\n\n dispose = (): void => {\n while (this.cleanups.length > 0) {\n this.cleanups.pop()?.();\n }\n this.started = false;\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);\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.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.createSummaryFromRecord(liveRecord, true)\n : await this.getSession(sessionId);\n return summary?.contextWindow ?? null;\n };\n\n getAgentRunSession = async (sessionId: string): Promise<AgentRunSession> => {\n const record = await this.getSessionRecord(sessionId);\n if (!record) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n const agentRuntimeId = readOptionalMetadataString(record.metadata?.agentRuntimeId) ??\n DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n const model = readOptionalMetadataString(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 createAgentRunSession = async (\n params: CreateAgentRunSessionParams,\n ): Promise<AgentRunSession> => {\n const {\n agentId,\n agentRuntimeId: requestedAgentRuntimeId,\n channel,\n metadata,\n model,\n peerId: rawPeerId,\n projectRoot,\n sessionId,\n task,\n thinkingEffort,\n } = params;\n const agentRuntimeId = requestedAgentRuntimeId ?? DEFAULT_AGENT_RUNTIME_ENTRY_ID;\n const peerId = readOptionalString(rawPeerId);\n const peerIdentity = peerId\n ? createAgentPeerSessionIdentity({ agentId, channel, metadata, peerId })\n : undefined;\n const requestedSessionId = readOptionalString(sessionId);\n const created = await this.createSession({\n sourceSessionMetadata: {},\n sessionId: requestedSessionId ?? peerIdentity?.sessionId,\n task: task ?? \"Session\",\n agentId,\n metadataOverrides: Object.assign(structuredClone(metadata ?? {}), peerIdentity?.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 getOrCreateAgentRunSession = async (\n params: CreateAgentRunSessionParams,\n ): Promise<AgentRunSession> => {\n if (!params.sessionId) {\n return await this.createAgentRunSession(params);\n }\n const existing = await this.getSessionRecord(params.sessionId);\n if (existing) {\n return await this.getAgentRunSession(params.sessionId);\n }\n return await this.createAgentRunSession(params);\n };\n\n patchSessionMetadata = async (\n sessionId: string,\n patch: Record<string, unknown>,\n ): Promise<void> => {\n const updated = await this.updateSessionMetadata(sessionId, patch);\n if (!updated) {\n throw new Error(`Session metadata was not updated: ${sessionId}`);\n }\n };\n\n clearSessionMessages = async (sessionId: string): Promise<number> => {\n const record = await this.getSessionRecord(sessionId);\n if (!record) {\n await this.createSession({\n sessionId,\n sourceSessionMetadata: {},\n task: \"Session\",\n });\n return 0;\n }\n const nextRecord: AgentSessionRecord = {\n ...record,\n messages: [],\n updatedAt: new Date().toISOString(),\n metadata: structuredClone(record.metadata ?? {}),\n };\n await this.options.journalStore.importSessionSnapshot(nextRecord);\n await this.publishSessionChange(record.sessionId);\n return record.messages.length;\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 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 type {\n NcpEndpointEvent,\n NcpMessage,\n NcpMessagePart,\n NcpRunHandle,\n} from \"@nextclaw/ncp\";\nimport type { AgentRunSendIngressPayload } from \"@nextclaw/shared\";\n\nexport type PanelAppErrorCode =\n | \"AGENT_OBJECT_REQUEST_FAILED\"\n | \"AGENT_OBJECT_RESULT_NOT_SUBMITTED\"\n | \"AGENT_OBJECT_RESULT_SCHEMA_INVALID\"\n | \"AGENT_OBJECT_RESULT_TIMEOUT\"\n | \"AUTHORIZATION_REQUIRED\"\n | \"PANEL_APP_AGENT_REQUEST_INVALID\"\n | \"PANEL_APP_ASSET_TOKEN_EXPIRED\"\n | \"PANEL_APP_ASSET_TOKEN_INVALID\"\n | \"PANEL_APP_BRIDGE_SESSION_NOT_FOUND\"\n | \"PANEL_APP_CAPABILITY_NOT_DECLARED\"\n | \"PANEL_APP_CLIENT_NOT_DECLARED\"\n | \"PANEL_APP_INVALID_ASSET_PATH\"\n | \"PANEL_APP_INVALID_ID\"\n | \"PANEL_APP_MANIFEST_INVALID\"\n | \"PANEL_APP_NOT_FOUND\"\n | \"PANEL_APP_READ_FAILED\";\n\nexport class PanelAppError extends Error {\n constructor(\n readonly code: PanelAppErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"PanelAppError\";\n }\n}\n\nexport function isPanelAppError(error: unknown): error is PanelAppError {\n return error instanceof PanelAppError;\n}\n\nexport const PANEL_APP_AGENT_CAPABILITIES = [\n \"agent:send\",\n \"agent:generateObject\",\n] as const;\n\nexport type PanelAppAgentCapability = typeof PANEL_APP_AGENT_CAPABILITIES[number];\n\nexport function isPanelAppAgentCapability(\n value: unknown,\n): value is PanelAppAgentCapability {\n return (PANEL_APP_AGENT_CAPABILITIES as readonly unknown[]).includes(value);\n}\n\nexport type PanelAppCapabilityGrantCaller = {\n surface: \"panel-app\";\n appId: string;\n};\n\nexport type PanelAppCapabilityGrant = {\n caller: PanelAppCapabilityGrantCaller;\n capability: PanelAppAgentCapability;\n grantedAt: string;\n};\n\nexport type PanelAppAgentSendPayload =\n | {\n sessionId?: string;\n peerId?: string;\n content: NcpMessagePart[];\n message?: never;\n metadata?: Record<string, unknown>;\n }\n | {\n sessionId?: string;\n peerId?: string;\n message: NcpMessage | (Omit<NcpMessage, \"sessionId\"> & { sessionId?: string });\n content?: never;\n metadata?: Record<string, unknown>;\n };\n\nexport type PanelAppAgentSendRequest = {\n payload: PanelAppAgentSendPayload;\n};\n\nexport type PanelAppAgentSendResult = NcpRunHandle;\n\nexport type PanelAppAgentRunClient = {\n send: (input: AgentRunSendIngressPayload) => Promise<NcpRunHandle>;\n sendAndStreamEvents: (\n input: AgentRunSendIngressPayload,\n ) => AsyncGenerator<NcpEndpointEvent>;\n};\n\nexport type PanelAppAgentGenerateObjectInput = {\n peerId: string;\n prompt: string;\n context?: unknown;\n schema: Record<string, unknown>;\n title?: string;\n timeoutMs?: number;\n};\n\nexport type PanelAppAgentGenerateObjectRequest = {\n input: PanelAppAgentGenerateObjectInput;\n};\n\nexport type PanelAppAgentGenerateObjectResult = {\n result: unknown;\n};\n","import { createHmac, randomBytes, timingSafeEqual } from \"node:crypto\";\nimport { PanelAppError } from \"@kernel/types/panel-app.types.js\";\n\nconst PANEL_APP_ASSET_TOKEN_TTL_MS = 2 * 60 * 60 * 1000;\n\nexport type PanelAppAssetTokenClaims = {\n panelAppId: string;\n sourceName: string;\n expiresAt: number;\n nonce: string;\n};\n\ntype PanelAppAssetTokenServiceParams = {\n now?: () => number;\n secret?: Buffer;\n ttlMs?: number;\n};\n\nexport class PanelAppAssetTokenService {\n private readonly now: () => number;\n private readonly secret: Buffer;\n private readonly ttlMs: number;\n\n constructor(params: PanelAppAssetTokenServiceParams = {}) {\n this.now = params.now ?? Date.now;\n this.secret = params.secret ?? randomBytes(32);\n this.ttlMs = params.ttlMs ?? PANEL_APP_ASSET_TOKEN_TTL_MS;\n }\n\n issue = (params: {\n panelAppId: string;\n sourceName: string;\n }): string => {\n const claims: PanelAppAssetTokenClaims = {\n panelAppId: params.panelAppId,\n sourceName: params.sourceName,\n expiresAt: this.now() + this.ttlMs,\n nonce: randomBytes(12).toString(\"base64url\"),\n };\n const payload = Buffer.from(JSON.stringify(claims), \"utf8\").toString(\"base64url\");\n return `${payload}.${this.sign(payload)}`;\n };\n\n verify = (token: string): PanelAppAssetTokenClaims => {\n const normalizedToken = token.trim();\n const [payload, signature, ...rest] = normalizedToken.split(\".\");\n if (!payload || !signature || rest.length > 0 || !this.matchesSignature(payload, signature)) {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_INVALID\",\n \"invalid panel app asset token\",\n );\n }\n const claims = this.parseClaims(payload);\n if (claims.expiresAt <= this.now()) {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_EXPIRED\",\n \"panel app asset token expired\",\n );\n }\n return claims;\n };\n\n private sign = (payload: string): string =>\n createHmac(\"sha256\", this.secret).update(payload).digest(\"base64url\");\n\n private matchesSignature = (payload: string, signature: string): boolean => {\n const expected = Buffer.from(this.sign(payload), \"utf8\");\n const actual = Buffer.from(signature, \"utf8\");\n return expected.length === actual.length && timingSafeEqual(expected, actual);\n };\n\n private parseClaims = (payload: string): PanelAppAssetTokenClaims => {\n try {\n const claims = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf8\")) as unknown;\n if (!isPanelAppAssetTokenClaims(claims)) {\n throw new Error(\"invalid panel app asset token claims\");\n }\n return claims;\n } catch {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_INVALID\",\n \"invalid panel app asset token\",\n );\n }\n };\n}\n\nfunction isPanelAppAssetTokenClaims(value: unknown): value is PanelAppAssetTokenClaims {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"panelAppId\" in value &&\n \"sourceName\" in value &&\n \"expiresAt\" in value &&\n \"nonce\" in value &&\n typeof value.panelAppId === \"string\" &&\n typeof value.sourceName === \"string\" &&\n typeof value.expiresAt === \"number\" &&\n typeof value.nonce === \"string\"\n );\n}\n","import { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\n\nconst PANEL_APP_STATE_FILE = \".panel-apps.state.json\";\nconst PANEL_APP_STATE_VERSION = 1;\n\nexport type PanelAppStateEntry = {\n favorite?: boolean;\n lastOpenedAt?: string;\n openCount?: number;\n};\n\nexport type PanelAppStateSnapshot = Record<string, PanelAppStateEntry>;\n\ntype PanelAppStateFile = {\n version: typeof PANEL_APP_STATE_VERSION;\n apps: PanelAppStateSnapshot;\n};\n\nexport type PanelAppPreferencesUpdate = {\n favorite?: boolean;\n};\n\nexport class PanelAppStateStore {\n constructor(private readonly panelsPath: string) {}\n\n load = async (): Promise<PanelAppStateSnapshot> => {\n try {\n const parsed = JSON.parse(await readFile(this.getStatePath(), \"utf8\")) as unknown;\n return this.normalizeStateFile(parsed).apps;\n } catch (error) {\n if (this.isMissingFileError(error) || error instanceof SyntaxError) {\n return {};\n }\n throw error;\n }\n };\n\n updatePreferences = async (\n id: string,\n preferences: PanelAppPreferencesUpdate,\n ): Promise<PanelAppStateEntry> => {\n const apps = await this.load();\n const current = apps[id] ?? {};\n const next = { ...current };\n if (typeof preferences.favorite === \"boolean\") {\n next.favorite = preferences.favorite;\n }\n apps[id] = next;\n await this.persist(apps);\n return next;\n };\n\n recordOpened = async (id: string, openedAt = new Date()): Promise<PanelAppStateEntry> => {\n const apps = await this.load();\n const current = apps[id] ?? {};\n const next = {\n ...current,\n lastOpenedAt: openedAt.toISOString(),\n openCount: Math.max(0, current.openCount ?? 0) + 1,\n };\n apps[id] = next;\n await this.persist(apps);\n return next;\n };\n\n deleteEntry = async (id: string): Promise<void> => {\n const apps = await this.load();\n if (!(id in apps)) {\n return;\n }\n delete apps[id];\n await this.persist(apps);\n };\n\n private persist = async (apps: PanelAppStateSnapshot): Promise<void> => {\n const statePath = this.getStatePath();\n const tempPath = `${statePath}.${randomUUID()}.tmp`;\n const stateFile: PanelAppStateFile = {\n version: PANEL_APP_STATE_VERSION,\n apps,\n };\n await mkdir(dirname(statePath), { recursive: true });\n try {\n await writeFile(tempPath, `${JSON.stringify(stateFile, null, 2)}\\n`, \"utf8\");\n await rename(tempPath, statePath);\n } catch (error) {\n await rm(tempPath, { force: true }).catch(() => undefined);\n throw error;\n }\n };\n\n private getStatePath = (): string => join(this.panelsPath, PANEL_APP_STATE_FILE);\n\n private normalizeStateFile = (value: unknown): PanelAppStateFile => {\n if (!this.isRecord(value) || !this.isRecord(value.apps)) {\n return { version: PANEL_APP_STATE_VERSION, apps: {} };\n }\n const apps = Object.fromEntries(\n Object.entries(value.apps).flatMap(([id, entry]) => {\n if (!this.isRecord(entry)) {\n return [];\n }\n return [[id, this.normalizeStateEntry(entry)]];\n }),\n );\n return { version: PANEL_APP_STATE_VERSION, apps };\n };\n\n private normalizeStateEntry = (entry: Record<string, unknown>): PanelAppStateEntry => {\n const normalized: PanelAppStateEntry = {};\n if (typeof entry.favorite === \"boolean\") {\n normalized.favorite = entry.favorite;\n }\n if (typeof entry.lastOpenedAt === \"string\") {\n normalized.lastOpenedAt = entry.lastOpenedAt;\n }\n if (typeof entry.openCount === \"number\") {\n normalized.openCount = entry.openCount;\n }\n return normalized;\n };\n\n private isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n private isMissingFileError = (error: unknown): boolean =>\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type {\n PanelAppCapabilityGrant,\n PanelAppCapabilityGrantCaller,\n PanelAppAgentCapability,\n} from \"@kernel/types/panel-app.types.js\";\n\ntype StoredPanelAppCapabilityGrant = {\n grantedAt: string;\n};\n\ntype PanelAppCapabilityGrantStoreData = {\n version: 1;\n grants: Record<string, {\n capabilities: Record<string, StoredPanelAppCapabilityGrant>;\n }>;\n};\n\nconst EMPTY_GRANTS: PanelAppCapabilityGrantStoreData = {\n version: 1,\n grants: {},\n};\n\nexport class PanelAppCapabilityGrantStore {\n constructor(private readonly filePath: string) {}\n\n isGranted = async (\n caller: PanelAppCapabilityGrantCaller,\n capability: PanelAppAgentCapability,\n ): Promise<boolean> => {\n const data = await this.load();\n return Boolean(data.grants[getCallerKey(caller)]?.capabilities[capability]);\n };\n\n grant = async (params: {\n caller: PanelAppCapabilityGrantCaller;\n capability: PanelAppAgentCapability;\n grantedAt: string;\n }): Promise<PanelAppCapabilityGrant> => {\n const { caller, capability, grantedAt } = params;\n const data = await this.load();\n const callerKey = getCallerKey(caller);\n const callerGrants = data.grants[callerKey] ?? { capabilities: {} };\n callerGrants.capabilities[capability] = {\n grantedAt,\n };\n data.grants[callerKey] = callerGrants;\n await this.save(data);\n return {\n caller,\n capability,\n grantedAt,\n };\n };\n\n deleteCaller = async (caller: PanelAppCapabilityGrantCaller): Promise<void> => {\n const data = await this.load();\n const callerKey = getCallerKey(caller);\n if (!(callerKey in data.grants)) {\n return;\n }\n delete data.grants[callerKey];\n await this.save(data);\n };\n\n private load = async (): Promise<PanelAppCapabilityGrantStoreData> => {\n try {\n return normalizeStoreData(JSON.parse(await readFile(this.filePath, \"utf8\")));\n } catch (error) {\n if (isMissingFileError(error)) {\n return structuredClone(EMPTY_GRANTS);\n }\n throw error;\n }\n };\n\n private save = async (data: PanelAppCapabilityGrantStoreData): Promise<void> => {\n await mkdir(dirname(this.filePath), { recursive: true });\n await writeFile(this.filePath, `${JSON.stringify(data, null, 2)}\\n`, \"utf8\");\n };\n}\n\nfunction normalizeStoreData(value: unknown): PanelAppCapabilityGrantStoreData {\n if (!isRecord(value) || value.version !== 1 || !isRecord(value.grants)) {\n return structuredClone(EMPTY_GRANTS);\n }\n const grants: PanelAppCapabilityGrantStoreData[\"grants\"] = {};\n for (const [callerKey, callerValue] of Object.entries(value.grants)) {\n if (!isRecord(callerValue) || !isRecord(callerValue.capabilities)) {\n continue;\n }\n const capabilities: Record<string, StoredPanelAppCapabilityGrant> = {};\n for (const [capability, grantValue] of Object.entries(callerValue.capabilities)) {\n if (isRecord(grantValue) && typeof grantValue.grantedAt === \"string\") {\n capabilities[capability] = { grantedAt: grantValue.grantedAt };\n }\n }\n grants[callerKey] = { capabilities };\n }\n return { version: 1, grants };\n}\n\nfunction getCallerKey(caller: PanelAppCapabilityGrantCaller): string {\n return `${caller.surface}:${caller.appId}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return Boolean(error) &&\n typeof error === \"object\" &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\ntype StoredPanelAppClientGrant = {\n grantedAt: string;\n};\n\ntype PanelAppClientGrantStoreData = {\n version: 1;\n grants: Record<string, StoredPanelAppClientGrant>;\n};\n\nconst EMPTY_GRANTS: PanelAppClientGrantStoreData = {\n grants: {},\n version: 1,\n};\n\nexport type PanelAppClientGrant = {\n appId: string;\n grantedAt: string;\n};\n\nexport class PanelAppClientGrantStore {\n constructor(private readonly filePath: string) {}\n\n isGranted = async (appId: string): Promise<boolean> => {\n const data = await this.load();\n return Boolean(data.grants[appId]);\n };\n\n grant = async (params: PanelAppClientGrant): Promise<PanelAppClientGrant> => {\n const data = await this.load();\n data.grants[params.appId] = {\n grantedAt: params.grantedAt,\n };\n await this.save(data);\n return params;\n };\n\n revoke = async (appId: string): Promise<void> => {\n const data = await this.load();\n if (!data.grants[appId]) {\n return;\n }\n delete data.grants[appId];\n await this.save(data);\n };\n\n private load = async (): Promise<PanelAppClientGrantStoreData> => {\n try {\n return normalizeStoreData(JSON.parse(await readFile(this.filePath, \"utf8\")));\n } catch (error) {\n if (isMissingFileError(error)) {\n return structuredClone(EMPTY_GRANTS);\n }\n throw error;\n }\n };\n\n private save = async (data: PanelAppClientGrantStoreData): Promise<void> => {\n await mkdir(dirname(this.filePath), { recursive: true });\n await writeFile(this.filePath, `${JSON.stringify(data, null, 2)}\\n`, \"utf8\");\n };\n}\n\nfunction normalizeStoreData(value: unknown): PanelAppClientGrantStoreData {\n if (!isRecord(value) || value.version !== 1 || !isRecord(value.grants)) {\n return structuredClone(EMPTY_GRANTS);\n }\n const grants: Record<string, StoredPanelAppClientGrant> = {};\n for (const [appId, grant] of Object.entries(value.grants)) {\n if (isRecord(grant) && typeof grant.grantedAt === \"string\") {\n grants[appId] = { grantedAt: grant.grantedAt };\n }\n }\n return { grants, version: 1 };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return isRecord(error) && error.code === \"ENOENT\";\n}\n","import {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpMessage,\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 { randomUUID } from \"node:crypto\";\nimport { extractTextFromNcpMessage } from \"@kernel/utils/ncp-message-bridge.utils.js\";\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 readEventCorrelationId(event: NcpEndpointEvent): string | undefined {\n if (!(\"payload\" in event)) {\n return undefined;\n }\n const correlationId =\n \"correlationId\" in event.payload ? event.payload.correlationId : 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 =\n \"sessionId\" in event.payload ? event.payload.sessionId : 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 (\n event.type === NcpEventType.MessageFailed ||\n event.type === NcpEventType.RunError ||\n event.type === NcpEventType.RunFinished\n );\n}\n\nfunction isRunEventMatch(params: {\n correlationId: string;\n event: NcpEndpointEvent;\n runId?: string;\n sessionId?: string;\n}): boolean {\n const { correlationId, event, runId, sessionId } = params;\n const eventCorrelationId = readEventCorrelationId(event);\n if (eventCorrelationId) {\n return eventCorrelationId === correlationId;\n }\n if (!sessionId || !runId) {\n return false;\n }\n return (\n readEventSessionId(event) === sessionId && readEventRunId(event) === runId\n );\n}\n\nclass AgentRunEventQueue<T> implements AsyncIterable<T> {\n private readonly values: T[] = [];\n private readonly waiters: Array<(result: IteratorResult<T>) => void> = [];\n private closed = false;\n\n push = (value: T): void => {\n if (this.closed) {\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 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.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 AgentRunEventQueue<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(\n eventKeys.ncpEvent,\n this.handleEvent,\n );\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* (\n this: AgentRunObserver,\n ): AsyncGenerator<NcpEndpointEvent> {\n for await (const event of this.queue) {\n yield event;\n }\n };\n\n waitForReply = async (\n options: AgentRunReplyOptions = {},\n ): 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(\n event.payload.error ?? options.runErrorMessage ?? \"NCP run failed.\",\n );\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 (\n this.disposed ||\n !isRunEventMatch({\n correlationId: this.options.correlationId,\n event,\n runId: this.runId,\n sessionId: this.sessionId,\n })\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<\n AgentRunSendIngressPayload,\n NcpRunHandle\n >(\n {\n type: ingressKeys.agentRun.send,\n payload: {\n ...input,\n correlationId,\n },\n },\n { source: \"agent-run-client\" },\n );\n };\n}\n","import { validateToolArgs } from \"@nextclaw/ncp-agent-runtime\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport const STRUCTURED_RESULT_TOOL_NAME = \"nextclaw_submit_result\";\n\nexport type StructuredResultContract = {\n requestId: string;\n schema: Record<string, unknown>;\n toolName: typeof STRUCTURED_RESULT_TOOL_NAME;\n};\n\nexport class StructuredResultSubmitTool implements NcpTool {\n readonly name = STRUCTURED_RESULT_TOOL_NAME;\n readonly description = \"Submit the structured object result for this request.\";\n\n constructor(private readonly contract: StructuredResultContract) {}\n\n get parameters(): Record<string, unknown> {\n return this.contract.schema;\n }\n\n validateArgs = (args: Record<string, unknown>): string[] =>\n validateToolArgs(args, this.contract.schema);\n\n execute = async (args: Record<string, unknown>): Promise<unknown> => args;\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n NcpEventType,\n type NcpEndpointEvent,\n type NcpOutboundMessageDraft,\n} from \"@nextclaw/ncp\";\nimport type { AgentRunSendIngressPayload } from \"@nextclaw/shared\";\nimport {\n STRUCTURED_RESULT_TOOL_NAME,\n} from \"@kernel/tools/structured-result.tools.js\";\nimport {\n PanelAppError,\n type PanelAppAgentGenerateObjectInput,\n type PanelAppAgentRunClient,\n type PanelAppAgentSendPayload,\n} from \"@kernel/types/panel-app.types.js\";\n\nconst PANEL_APP_AGENT_DEFAULT_TIMEOUT_MS = 60_000;\nconst PANEL_APP_AGENT_MAX_TIMEOUT_MS = 120_000;\nconst PANEL_APP_AGENT_MAX_PROMPT_CHARS = 20_000;\nconst PANEL_APP_AGENT_MAX_CONTEXT_CHARS = 80_000;\n\ntype PanelAppAgentBridgeSession = {\n appId: string;\n};\n\nexport type NormalizedPanelAppGenerateObjectInput =\n Required<Pick<PanelAppAgentGenerateObjectInput, \"peerId\" | \"prompt\" | \"schema\" | \"timeoutMs\">> &\n Pick<PanelAppAgentGenerateObjectInput, \"context\" | \"title\">;\n\nexport function normalizePanelAppGenerateObjectInput(\n input: PanelAppAgentGenerateObjectInput,\n): NormalizedPanelAppGenerateObjectInput {\n const peerId = input.peerId.trim();\n const prompt = input.prompt.trim();\n if (!peerId || !prompt || !isRecord(input.schema)) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"invalid generateObject request\");\n }\n if (prompt.length > PANEL_APP_AGENT_MAX_PROMPT_CHARS) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"generateObject prompt is too large\");\n }\n const contextText = stringifyJsonValue(input.context ?? null);\n if (contextText.length > PANEL_APP_AGENT_MAX_CONTEXT_CHARS) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"generateObject context is too large\");\n }\n return {\n context: input.context,\n peerId,\n prompt,\n schema: input.schema,\n timeoutMs: normalizeTimeoutMs(input.timeoutMs),\n title: input.title?.trim() || undefined,\n };\n}\n\nexport function createPanelAppGenerateObjectMessage(params: {\n bridgeSession: PanelAppAgentBridgeSession;\n request: NormalizedPanelAppGenerateObjectInput;\n requestId: string;\n}): NcpOutboundMessageDraft {\n const { bridgeSession, request, requestId } = params;\n return {\n id: `panel-app-agent-message-${randomUUID()}`,\n metadata: {\n ...createPanelAppAgentMetadata(bridgeSession),\n panel_app_peer_id: request.peerId,\n structured_result: {\n request_id: requestId,\n schema: structuredClone(request.schema),\n tool_name: STRUCTURED_RESULT_TOOL_NAME,\n },\n },\n parts: [{\n type: \"text\",\n text: buildGenerateObjectPrompt(bridgeSession, request),\n }],\n role: \"user\",\n status: \"final\",\n timestamp: new Date().toISOString(),\n };\n}\n\nexport async function waitForPanelAppStructuredResult(\n agentRunClient: PanelAppAgentRunClient,\n params: {\n payload: AgentRunSendIngressPayload;\n timeoutMs: number;\n },\n): Promise<unknown> {\n const iterator = agentRunClient\n .sendAndStreamEvents(params.payload)\n [Symbol.asyncIterator]();\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => reject(new PanelAppError(\n \"AGENT_OBJECT_RESULT_TIMEOUT\",\n \"agent object result timed out\",\n )), params.timeoutMs);\n });\n let resultToolCallId: string | null = null;\n try {\n while (true) {\n const next = await Promise.race([iterator.next(), timeout]);\n if (next.done) {\n break;\n }\n const result = readStructuredResultEvent(next.value, resultToolCallId);\n if (result.matchedToolCallId) {\n resultToolCallId = result.matchedToolCallId;\n }\n if (result.submitted) {\n return result.content;\n }\n throwIfTerminalError(next.value);\n }\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n await iterator.return?.(undefined);\n }\n throw new PanelAppError(\n \"AGENT_OBJECT_RESULT_NOT_SUBMITTED\",\n \"agent did not submit a structured object result\",\n );\n}\n\nexport function withPanelAppAgentMetadata(\n payload: PanelAppAgentSendPayload,\n bridgeSession: PanelAppAgentBridgeSession,\n): AgentRunSendIngressPayload {\n const panelAppMetadata = createPanelAppAgentMetadata(bridgeSession);\n const peerId = readOptionalPeerId(payload.peerId);\n const sessionId = readOptionalSessionId(payload.sessionId);\n if (peerId && sessionId) {\n throw new PanelAppError(\n \"PANEL_APP_AGENT_REQUEST_INVALID\",\n \"agent send request cannot include both sessionId and peerId\",\n );\n }\n const metadata: Record<string, unknown> = {\n ...(payload.metadata ?? {}),\n ...panelAppMetadata,\n };\n if (peerId) {\n metadata.panel_app_peer_id = peerId;\n }\n if (Array.isArray(payload.content)) {\n return {\n content: structuredClone(payload.content),\n metadata,\n peerId,\n sessionId,\n };\n }\n if (!payload.message) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"agent send request is required\");\n }\n return {\n message: {\n ...structuredClone(payload.message),\n metadata: {\n ...(payload.message.metadata ?? {}),\n ...panelAppMetadata,\n },\n },\n metadata,\n peerId,\n sessionId,\n };\n}\n\nexport function createPanelAppAgentMetadata(\n bridgeSession: PanelAppAgentBridgeSession,\n): Record<string, unknown> {\n return {\n agent_peer_scope: `panel-app:${bridgeSession.appId}`,\n panel_app_bridge_request_id: randomUUID(),\n panel_app_id: bridgeSession.appId,\n source_kind: \"panel_app\",\n };\n}\n\nfunction normalizeTimeoutMs(timeoutMs: number | undefined): number {\n if (!Number.isFinite(timeoutMs) || typeof timeoutMs !== \"number\") {\n return PANEL_APP_AGENT_DEFAULT_TIMEOUT_MS;\n }\n return Math.min(\n PANEL_APP_AGENT_MAX_TIMEOUT_MS,\n Math.max(1000, Math.trunc(timeoutMs)),\n );\n}\n\nfunction readOptionalPeerId(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const peerId = value.trim();\n if (!peerId) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"agent peerId cannot be empty\");\n }\n return peerId;\n}\n\nfunction readOptionalSessionId(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const sessionId = value.trim();\n if (!sessionId) {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"agent sessionId cannot be empty\");\n }\n return sessionId;\n}\n\nfunction buildGenerateObjectPrompt(\n bridgeSession: PanelAppAgentBridgeSession,\n request: NormalizedPanelAppGenerateObjectInput,\n): string {\n return [\n \"Panel App generateObject request\",\n \"\",\n `Panel App ID: ${bridgeSession.appId}`,\n `Peer ID: ${request.peerId}`,\n \"\",\n \"Context JSON:\",\n stringifyJsonValue(request.context ?? null),\n \"\",\n \"Task:\",\n request.prompt,\n \"\",\n \"Result contract:\",\n `Call the ${STRUCTURED_RESULT_TOOL_NAME} tool exactly once with an object matching the provided schema.`,\n \"Do not use natural language as the result.\",\n ].join(\"\\n\");\n}\n\nfunction readStructuredResultEvent(\n event: NcpEndpointEvent,\n resultToolCallId: string | null,\n): {\n matchedToolCallId?: string;\n submitted: boolean;\n content?: unknown;\n} {\n if (\n event.type === NcpEventType.MessageToolCallStart &&\n event.payload.toolName === STRUCTURED_RESULT_TOOL_NAME\n ) {\n return { matchedToolCallId: event.payload.toolCallId, submitted: false };\n }\n if (\n event.type !== NcpEventType.MessageToolCallResult ||\n event.payload.toolCallId !== resultToolCallId\n ) {\n return { submitted: false };\n }\n assertToolResultContent(event.payload.content);\n return { content: event.payload.content, submitted: true };\n}\n\nfunction assertToolResultContent(content: unknown): void {\n if (!isRecord(content) || content.ok !== false || !isRecord(content.error)) {\n return;\n }\n const code = content.error.code;\n if (code === \"invalid_tool_arguments\") {\n throw new PanelAppError(\n \"AGENT_OBJECT_RESULT_SCHEMA_INVALID\",\n \"agent object result did not match the schema\",\n );\n }\n throw new PanelAppError(\n \"AGENT_OBJECT_REQUEST_FAILED\",\n typeof content.error.message === \"string\"\n ? content.error.message\n : \"agent object request failed\",\n );\n}\n\nfunction throwIfTerminalError(event: NcpEndpointEvent): void {\n if (event.type === NcpEventType.MessageFailed) {\n throw new PanelAppError(\"AGENT_OBJECT_REQUEST_FAILED\", event.payload.error.message);\n }\n if (event.type === NcpEventType.RunError) {\n throw new PanelAppError(\n \"AGENT_OBJECT_REQUEST_FAILED\",\n event.payload.error ?? \"agent object request failed\",\n );\n }\n if (event.type === NcpEventType.RunFinished) {\n throw new PanelAppError(\n \"AGENT_OBJECT_RESULT_NOT_SUBMITTED\",\n \"agent did not submit a structured object result\",\n );\n }\n}\n\nfunction stringifyJsonValue(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n throw new PanelAppError(\"PANEL_APP_AGENT_REQUEST_INVALID\", \"value is not JSON serializable\");\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { randomUUID } from \"node:crypto\";\nimport {\n PANEL_APP_AGENT_CAPABILITIES,\n PanelAppError,\n isPanelAppAgentCapability,\n type PanelAppAgentCapability,\n type PanelAppAgentGenerateObjectInput,\n type PanelAppAgentGenerateObjectResult,\n type PanelAppAgentRunClient,\n type PanelAppAgentSendPayload,\n type PanelAppAgentSendResult,\n type PanelAppCapabilityGrant,\n} from \"@kernel/types/panel-app.types.js\";\nimport type { ServiceActionCaller } from \"@kernel/types/service-app.types.js\";\nimport type { PanelAppCapabilityGrantStore } from \"@kernel/stores/panel-app-capability-grant.store.js\";\nimport {\n createPanelAppAgentMetadata,\n createPanelAppGenerateObjectMessage,\n normalizePanelAppGenerateObjectInput,\n waitForPanelAppStructuredResult,\n withPanelAppAgentMetadata,\n} from \"@kernel/utils/panel-app-agent.utils.js\";\n\ntype PanelAppAgentBridgeSession = {\n appId: string;\n caller: ServiceActionCaller;\n declaredCapabilities: string[];\n};\n\nexport class PanelAppAgentBridgeService {\n constructor(private readonly params: {\n agentRunClient: PanelAppAgentRunClient | null;\n createCapabilityGrantStore: () => PanelAppCapabilityGrantStore;\n }) {}\n\n sendAgentMessage = async (\n bridgeSession: PanelAppAgentBridgeSession,\n payload: PanelAppAgentSendPayload,\n ): Promise<PanelAppAgentSendResult> => {\n await this.assertAgentCapabilityGranted(bridgeSession, \"agent:send\");\n return await this.requireAgentRunClient().send(\n withPanelAppAgentMetadata(payload, bridgeSession),\n );\n };\n\n generateAgentObject = async (\n bridgeSession: PanelAppAgentBridgeSession,\n input: PanelAppAgentGenerateObjectInput,\n ): Promise<PanelAppAgentGenerateObjectResult> => {\n await this.assertAgentCapabilityGranted(bridgeSession, \"agent:generateObject\");\n const request = normalizePanelAppGenerateObjectInput(input);\n const requestId = randomUUID();\n const message = createPanelAppGenerateObjectMessage({\n bridgeSession,\n request,\n requestId,\n });\n const result = await waitForPanelAppStructuredResult(this.requireAgentRunClient(), {\n payload: {\n message,\n metadata: {\n ...createPanelAppAgentMetadata(bridgeSession),\n panel_app_peer_id: request.peerId,\n },\n peerId: request.peerId,\n },\n timeoutMs: request.timeoutMs,\n });\n return { result };\n };\n\n grantAgentCapability = async (\n bridgeSession: PanelAppAgentBridgeSession,\n capability: PanelAppAgentCapability,\n ): Promise<PanelAppCapabilityGrant> => {\n if (!isPanelAppAgentCapability(capability)) {\n throw new PanelAppError(\n \"PANEL_APP_AGENT_REQUEST_INVALID\",\n \"unknown panel app agent capability\",\n );\n }\n this.assertDeclaredCapability(bridgeSession, capability);\n return await this.params.createCapabilityGrantStore().grant({\n caller: bridgeSession.caller,\n capability,\n grantedAt: new Date().toISOString(),\n });\n };\n\n private assertAgentCapabilityGranted = async (\n bridgeSession: PanelAppAgentBridgeSession,\n capability: PanelAppAgentCapability,\n ): Promise<void> => {\n this.assertDeclaredCapability(bridgeSession, capability);\n const granted = await this.params.createCapabilityGrantStore().isGranted(\n bridgeSession.caller,\n capability,\n );\n if (!granted) {\n throw new PanelAppError(\n \"AUTHORIZATION_REQUIRED\",\n `This panel app needs permission to use ${capability}.`,\n );\n }\n };\n\n private assertDeclaredCapability = (\n bridgeSession: PanelAppAgentBridgeSession,\n capability: PanelAppAgentCapability,\n ): void => {\n if (!bridgeSession.declaredCapabilities.includes(capability)) {\n throw new PanelAppError(\n \"PANEL_APP_CAPABILITY_NOT_DECLARED\",\n this.describeMissingAgentCapability(bridgeSession.declaredCapabilities, capability),\n );\n }\n };\n\n private describeMissingAgentCapability = (\n declaredCapabilities: string[],\n capability: PanelAppAgentCapability,\n ): string => {\n const declared = declaredCapabilities.length > 0\n ? declaredCapabilities.join(\", \")\n : \"none\";\n const valid = PANEL_APP_AGENT_CAPABILITIES.join(\", \");\n const hint = declaredCapabilities.includes(capability.replace(\":\", \".\"))\n ? ` Use ${capability}, not ${capability.replace(\":\", \".\")}.`\n : \"\";\n return [\n `panel app did not declare ${capability}.`,\n `Declared: ${declared}.`,\n `Valid capabilities: ${valid}.`,\n `Declare it with nextclaw-panel-capabilities or panel-app.json capabilities.`,\n hint.trim(),\n ].filter(Boolean).join(\" \");\n };\n\n private requireAgentRunClient = (): PanelAppAgentRunClient => {\n if (!this.params.agentRunClient) {\n throw new PanelAppError(\n \"PANEL_APP_AGENT_REQUEST_INVALID\",\n \"panel app agent client is not configured\",\n );\n }\n return this.params.agentRunClient;\n };\n}\n","const PANEL_APP_BRIDGE_MARKER = \"nextclaw:panel-app-service-actions:request\";\n\nexport function injectPanelAppBridgeScript(html: string, params: {\n appId: string;\n runtimeToken: string;\n}): string {\n if (html.includes(PANEL_APP_BRIDGE_MARKER)) {\n return html;\n }\n const script = `<script>${getPanelAppBridgeScript(params)}</script>`;\n const headMatch = /<head(?:\\s[^>]*)?>/i.exec(html);\n if (headMatch?.index !== undefined) {\n const insertAt = headMatch.index + headMatch[0].length;\n return `${html.slice(0, insertAt)}${script}${html.slice(insertAt)}`;\n }\n return `${script}${html}`;\n}\n\nexport function getPanelAppBridgeScript(params: {\n appId: string;\n runtimeToken: string;\n} = { appId: \"\", runtimeToken: \"\" }): string {\n const appId = JSON.stringify(params.appId);\n const runtimeToken = JSON.stringify(params.runtimeToken);\n return `\n(() => {\n const requestType = \"nextclaw:panel-app-service-actions:request\";\n const responseType = \"nextclaw:panel-app-service-actions:response\";\n const appId = ${appId};\n const runtimeToken = ${runtimeToken};\n const pending = new Map();\n let counter = 0;\n\n function createRequestId() {\n counter += 1;\n return \"panel-bridge-\" + Date.now().toString(36) + \"-\" + counter.toString(36);\n }\n\n function request(method, payload) {\n const requestId = createRequestId();\n return new Promise((resolve, reject) => {\n pending.set(requestId, { method, resolve, reject });\n window.parent.postMessage({ type: requestType, requestId, appId, runtimeToken, method, payload }, \"*\");\n });\n }\n\n function unwrapServiceActionResult(result) {\n if (!result || typeof result !== \"object\") {\n return result;\n }\n if (Object.prototype.hasOwnProperty.call(result, \"structuredContent\") && result.structuredContent !== undefined) {\n return result.structuredContent;\n }\n const content = Array.isArray(result.content) ? result.content : undefined;\n if (content && content.length === 1 && content[0]?.type === \"text\" && typeof content[0].text === \"string\") {\n try {\n return JSON.parse(content[0].text);\n } catch {\n return content[0].text;\n }\n }\n return result;\n }\n\n function resolveBridgeData(entry, data) {\n if (entry.method === \"list\") {\n return Array.isArray(data.data?.actions) ? data.data.actions : [];\n }\n if (entry.method === \"invoke\") {\n return unwrapServiceActionResult(data.data?.result);\n }\n if (entry.method === \"agent.generateObject\") {\n return data.data?.result;\n }\n return data.data;\n }\n\n window.addEventListener(\"message\", (event) => {\n const data = event.data;\n if (!data || data.type !== responseType || typeof data.requestId !== \"string\") {\n return;\n }\n const entry = pending.get(data.requestId);\n if (!entry) {\n return;\n }\n pending.delete(data.requestId);\n if (data.ok) {\n entry.resolve(resolveBridgeData(entry, data));\n return;\n }\n const error = new Error(data.error?.message || \"NextClaw panel bridge request failed.\");\n error.code = data.error?.code;\n error.details = data.error?.details;\n entry.reject(error);\n });\n\n const existing = window.nextclaw && typeof window.nextclaw === \"object\" ? window.nextclaw : {};\n Object.defineProperty(window, \"nextclaw\", {\n configurable: true,\n value: {\n ...existing,\n serviceActions: {\n list: () => request(\"list\", {}),\n invoke: (actionId, input) => request(\"invoke\", { actionId, input }),\n requestGrant: (actionId) => request(\"requestGrant\", { actionId }),\n revokeGrant: (actionId) => request(\"revokeGrant\", { actionId })\n },\n agent: {\n send: (input) => request(\"agent.send\", { request: input }),\n generateObject: (input) => request(\"agent.generateObject\", { input })\n }\n }\n });\n})();\n`.trim();\n}\n","const PANEL_APP_CLIENT_MARKER = \"nextclaw:panel-app-client:init\";\nconst PANEL_APP_CLIENT_SDK_PATH = \"/api/panel-app-client-sdk.js\";\n\nexport function injectPanelAppClientScript(html: string, params: {\n runtimeToken: string;\n}): string {\n if (html.includes(PANEL_APP_CLIENT_MARKER)) {\n return html;\n }\n const script = [\n `<script src=\"${PANEL_APP_CLIENT_SDK_PATH}\"></script>`,\n `<script>${getPanelAppClientInitScript(params)}</script>`,\n ].join(\"\");\n const headMatch = /<head(?:\\s[^>]*)?>/i.exec(html);\n if (headMatch?.index !== undefined) {\n const insertAt = headMatch.index + headMatch[0].length;\n return `${html.slice(0, insertAt)}${script}${html.slice(insertAt)}`;\n }\n return `${script}${html}`;\n}\n\nfunction getPanelAppClientInitScript(params: { runtimeToken: string }): string {\n const runtimeToken = JSON.stringify(params.runtimeToken);\n return `\n(() => {\n const marker = \"${PANEL_APP_CLIENT_MARKER}\";\n if (typeof window.NextClawClient !== \"function\") {\n console.error(\"[NextClaw] Panel App client SDK failed to load.\");\n return;\n }\n const existing = window.nextclaw && typeof window.nextclaw === \"object\" ? window.nextclaw : {};\n const client = new window.NextClawClient({\n baseUrl: window.location.origin,\n headers: {\n \"x-nextclaw-panel-bridge-session\": ${runtimeToken}\n }\n });\n Object.defineProperty(window, \"nextclaw\", {\n configurable: true,\n value: {\n ...existing,\n client\n }\n });\n Object.defineProperty(window.nextclaw, \"__clientInitMarker\", {\n configurable: true,\n enumerable: false,\n value: marker\n });\n})();\n`.trim();\n}\n","export type PanelAppManifest = {\n id?: string;\n title?: string;\n description?: string;\n icon?: string;\n entry?: string;\n capabilities: string[];\n client: boolean;\n serviceActions: string[];\n};\n\nconst PANEL_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\nexport function parsePanelAppManifest(html: string): PanelAppManifest {\n const fields = {\n ...readHtmlTitle(html),\n ...readStandardIcon(html),\n ...readPanelAppMeta(html),\n };\n return {\n ...fields,\n capabilities: readPanelAppCapabilities(html),\n client: false,\n serviceActions: readPanelAppServiceActions(html),\n };\n}\n\nexport function parsePanelAppFolderManifest(raw: string): PanelAppManifest & {\n title: string;\n entry: string;\n} {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new Error(\n `panel-app.json is not valid JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n if (!isRecord(parsed)) {\n throw new Error(\"panel-app.json must contain an object.\");\n }\n const id = readOptionalString(parsed, \"id\");\n if (id && !PANEL_APP_ID_PATTERN.test(id)) {\n throw new Error(\"panel app id must be kebab-case.\");\n }\n return {\n id,\n title: readRequiredString(parsed, \"title\"),\n description: readOptionalString(parsed, \"description\"),\n icon: readOptionalString(parsed, \"icon\"),\n entry: readRequiredString(parsed, \"entry\"),\n capabilities: readStringArray(parsed.capabilities, \"capabilities\"),\n client: readOptionalBoolean(parsed, \"client\"),\n serviceActions: readStringArray(parsed.actions, \"actions\"),\n };\n}\n\nfunction readPanelAppMeta(html: string): Partial<PanelAppManifest> {\n return {\n ...readPanelAppMetaField(html, \"title\"),\n ...readPanelAppMetaField(html, \"description\"),\n ...readPanelAppMetaField(html, \"icon\"),\n };\n}\n\nfunction readPanelAppMetaField(\n html: string,\n field: keyof Pick<PanelAppManifest, \"description\" | \"icon\" | \"title\">,\n): Partial<PanelAppManifest> {\n const content = readMetaContent(html, `nextclaw-panel-${field}`, field === \"icon\" ? \"attribute\" : \"text\");\n const manifest: Partial<PanelAppManifest> = {};\n if (content) {\n manifest[field] = content;\n }\n return manifest;\n}\n\nfunction readHtmlTitle(html: string): Partial<PanelAppManifest> {\n const match = html.match(/<title[^>]*>([\\s\\S]*?)<\\/title>/i);\n const title = normalizeTextValue(match?.[1]);\n return title ? { title } : {};\n}\n\nfunction readStandardIcon(html: string): Partial<PanelAppManifest> {\n const icon = readLinkHref(html, (relTokens) => relTokens.includes(\"icon\"));\n const appleTouchIcon = readLinkHref(html, (relTokens) =>\n relTokens.some((token) => token === \"apple-touch-icon\" || token === \"apple-touch-icon-precomposed\")\n );\n const href = normalizeIconHref(icon ?? appleTouchIcon);\n return href ? { icon: href } : {};\n}\n\nfunction readMetaContent(html: string, name: string, valueKind: \"attribute\" | \"text\"): string | undefined {\n const metaTags = html.matchAll(/<meta\\s+([^>]*?)>/gi);\n for (const tag of metaTags) {\n const attributes = tag[1] ?? \"\";\n if (readHtmlAttribute(attributes, \"name\") === name) {\n const content = readHtmlAttribute(attributes, \"content\");\n return valueKind === \"attribute\"\n ? normalizeAttributeValue(content)\n : normalizeTextValue(content);\n }\n }\n return undefined;\n}\n\nfunction readLinkHref(html: string, matchesRel: (relTokens: string[]) => boolean): string | undefined {\n const linkTags = html.matchAll(/<link\\s+([^>]*?)>/gi);\n for (const tag of linkTags) {\n const attributes = tag[1] ?? \"\";\n const relTokens = (readHtmlAttribute(attributes, \"rel\") ?? \"\")\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean);\n if (matchesRel(relTokens)) {\n return normalizeAttributeValue(readHtmlAttribute(attributes, \"href\"));\n }\n }\n return undefined;\n}\n\nfunction readHtmlAttribute(attributes: string, attribute: string): string | undefined {\n const match = attributes.match(new RegExp(`(?:^|\\\\s)${attribute}\\\\s*=\\\\s*([\"'])(.*?)\\\\1`, \"i\"));\n return match?.[2] ? decodeHtmlAttribute(match[2]) : undefined;\n}\n\nfunction readPanelAppServiceActions(html: string): string[] {\n const content = readMetaContent(html, \"nextclaw-panel-actions\", \"attribute\");\n return parseTokenList(content);\n}\n\nfunction readPanelAppCapabilities(html: string): string[] {\n const content = readMetaContent(html, \"nextclaw-panel-capabilities\", \"attribute\");\n return parseTokenList(content);\n}\n\nfunction parseTokenList(content: string | undefined): string[] {\n if (!content) {\n return [];\n }\n return [...new Set(\n content\n .split(/[,\\s]+/)\n .map((entry) => entry.trim())\n .filter(Boolean),\n )];\n}\n\nfunction readRequiredString(record: Record<string, unknown>, key: string): string {\n const value = readOptionalString(record, key);\n if (!value) {\n throw new Error(`panel app ${key} is required.`);\n }\n return value;\n}\n\nfunction readOptionalString(\n record: Record<string, unknown>,\n key: string,\n): string | undefined {\n return typeof record[key] === \"string\" && record[key].trim()\n ? record[key].trim()\n : undefined;\n}\n\nfunction readOptionalBoolean(\n record: Record<string, unknown>,\n key: string,\n): boolean {\n const value = record[key];\n if (value === undefined) {\n return false;\n }\n if (typeof value !== \"boolean\") {\n throw new Error(`panel app ${key} must be a boolean.`);\n }\n return value;\n}\n\nfunction readStringArray(value: unknown, key: string): string[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n throw new Error(`panel app ${key} must be a string array.`);\n }\n return [...new Set(value.map((entry) => entry.trim()).filter(Boolean))];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction normalizeTextValue(value: string | undefined): string | undefined {\n const normalized = decodeHtmlAttribute(value ?? \"\").replace(/\\s+/g, \" \").trim();\n return normalized || undefined;\n}\n\nfunction normalizeAttributeValue(value: string | undefined): string | undefined {\n const normalized = decodeHtmlAttribute(value ?? \"\").trim();\n return normalized || undefined;\n}\n\nfunction normalizeIconHref(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n if (\n value.startsWith(\"data:image/\") ||\n value.startsWith(\"http://\") ||\n value.startsWith(\"https://\") ||\n value.startsWith(\"/\")\n ) {\n return value;\n }\n return undefined;\n}\n\nfunction decodeHtmlAttribute(value: string): string {\n return value\n .replace(/"/g, \"\\\"\")\n .replace(/"/g, \"\\\"\")\n .replace(/'/g, \"'\")\n .replace(/'/g, \"'\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/&/g, \"&\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport { extname, isAbsolute, join, normalize, relative, resolve } from \"node:path\";\nimport type { Dirent, Stats } from \"node:fs\";\nimport { PanelAppError } from \"@kernel/types/panel-app.types.js\";\nimport {\n parsePanelAppFolderManifest,\n type PanelAppManifest,\n} from \"@kernel/utils/panel-app-manifest.utils.js\";\n\nexport const PANEL_APP_FILE_SUFFIX = \".panel.html\";\nexport const PANEL_APP_DIR_SUFFIX = \".panel\";\nexport const PANEL_APP_FOLDER_MANIFEST_FILE_NAME = \"panel-app.json\";\n\nexport type PanelAppSourceKind = \"single-file\" | \"folder\";\n\nexport type PanelAppSource = {\n kind: PanelAppSourceKind;\n sourceName: string;\n sourcePath: string;\n entryPath: string;\n manifest?: PanelAppManifest;\n sourceStat: Stats;\n};\n\nexport type PanelAppAssetContentType =\n | \"application/javascript; charset=utf-8\"\n | \"application/json; charset=utf-8\"\n | \"application/octet-stream\"\n | \"image/png\"\n | \"image/svg+xml; charset=utf-8\"\n | \"image/webp\"\n | \"text/css; charset=utf-8\"\n | \"text/plain; charset=utf-8\";\n\nexport type PanelAppAsset = {\n content: Buffer;\n contentType: PanelAppAssetContentType;\n};\n\nexport function isPanelAppSourceEntry(entry: Dirent): boolean {\n return (\n (entry.isFile() && isPanelAppFileName(entry.name)) ||\n (entry.isDirectory() && isPanelAppDirName(entry.name))\n );\n}\n\nexport function isPanelAppFileName(fileName: string): boolean {\n return hasSafeBaseName(fileName) && fileName.endsWith(PANEL_APP_FILE_SUFFIX);\n}\n\nexport function isPanelAppDirName(dirName: string): boolean {\n return hasSafeBaseName(dirName) && dirName.endsWith(PANEL_APP_DIR_SUFFIX);\n}\n\nexport function toPanelAppTitle(sourceName: string): string {\n return (\n sourceName\n .replace(new RegExp(`${escapeRegExp(PANEL_APP_FILE_SUFFIX)}$`), \"\")\n .replace(new RegExp(`${escapeRegExp(PANEL_APP_DIR_SUFFIX)}$`), \"\")\n .replace(/[-_]+/g, \" \")\n .trim() || sourceName\n );\n}\n\nexport function encodePanelAppId(sourceName: string): string {\n return Buffer.from(sourceName, \"utf8\").toString(\"base64url\");\n}\n\nexport function decodePanelAppId(id: string): string {\n const normalizedId = id.trim();\n if (!normalizedId) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ID\", \"panel app id is required\");\n }\n let sourceName = \"\";\n try {\n sourceName = Buffer.from(normalizedId, \"base64url\").toString(\"utf8\");\n } catch {\n throw new PanelAppError(\"PANEL_APP_INVALID_ID\", \"invalid panel app id\");\n }\n if (\n encodePanelAppId(sourceName) !== normalizedId ||\n (!isPanelAppFileName(sourceName) && !isPanelAppDirName(sourceName))\n ) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ID\", \"invalid panel app id\");\n }\n return sourceName;\n}\n\nexport async function readPanelAppFolderManifest(\n dirPath: string,\n dirName: string,\n): Promise<PanelAppManifest & { id: string; title: string; entry: string }> {\n const raw = await readFile(join(dirPath, PANEL_APP_FOLDER_MANIFEST_FILE_NAME), \"utf8\");\n const manifest = parsePanelAppFolderManifest(raw);\n const expectedId = dirName.slice(0, -PANEL_APP_DIR_SUFFIX.length);\n if (manifest.id && manifest.id !== expectedId) {\n throw new PanelAppError(\n \"PANEL_APP_MANIFEST_INVALID\",\n \"panel app manifest id must match the directory name\",\n );\n }\n return { ...manifest, id: expectedId };\n}\n\nexport function resolvePanelAppRelativePath(rootPath: string, relativePath: string): string {\n if (!relativePath.trim() || relativePath.includes(\"\\0\") || isAbsolute(relativePath)) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n const normalizedPath = normalize(relativePath);\n if (normalizedPath === \".\" || normalizedPath.startsWith(\"..\")) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n const resolvedPath = resolve(rootPath, normalizedPath);\n const resolvedRoot = resolve(rootPath);\n const pathFromRoot = relative(resolvedRoot, resolvedPath);\n if (pathFromRoot.startsWith(\"..\") || isAbsolute(pathFromRoot)) {\n throw new PanelAppError(\"PANEL_APP_INVALID_ASSET_PATH\", \"invalid panel app asset path\");\n }\n return resolvedPath;\n}\n\nexport function resolvePanelAppAssetContentType(path: string): PanelAppAssetContentType {\n switch (extname(path).toLowerCase()) {\n case \".css\":\n return \"text/css; charset=utf-8\";\n case \".js\":\n case \".mjs\":\n return \"application/javascript; charset=utf-8\";\n case \".json\":\n return \"application/json; charset=utf-8\";\n case \".png\":\n return \"image/png\";\n case \".svg\":\n return \"image/svg+xml; charset=utf-8\";\n case \".webp\":\n return \"image/webp\";\n case \".txt\":\n return \"text/plain; charset=utf-8\";\n default:\n return \"application/octet-stream\";\n }\n}\n\nexport function resolvePanelAppIconUrl(\n id: string,\n icon: string | undefined,\n): string | undefined {\n if (!icon) {\n return undefined;\n }\n if (\n icon.startsWith(\"data:image/\") ||\n icon.startsWith(\"http://\") ||\n icon.startsWith(\"https://\") ||\n icon.startsWith(\"/\") ||\n isLikelyTextIcon(icon)\n ) {\n return icon;\n }\n return `/api/panel-apps/${encodeURIComponent(id)}/assets/${encodePanelAppAssetPath(icon)}`;\n}\n\nexport function injectPanelAppAssetBase(html: string, baseHref: string): string {\n const base = `<base href=\"${baseHref}\">`;\n if (/<base\\b/i.test(html)) {\n return html;\n }\n if (/<head[^>]*>/i.test(html)) {\n return html.replace(/<head[^>]*>/i, (head) => `${head}${base}`);\n }\n return `${base}${html}`;\n}\n\nfunction encodePanelAppAssetPath(path: string): string {\n return path\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => encodeURIComponent(segment))\n .join(\"/\");\n}\n\nfunction hasSafeBaseName(name: string): boolean {\n return !name.includes(\"/\") && !name.includes(\"\\\\\") && !name.includes(\"\\0\");\n}\n\nfunction isLikelyTextIcon(icon: string): boolean {\n return !icon.includes(\"/\") && !icon.includes(\".\") && icon.length <= 4;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { PanelAppError, isPanelAppError } from \"@kernel/types/panel-app.types.js\";\nimport {\n decodePanelAppId,\n isPanelAppDirName,\n isPanelAppFileName,\n isPanelAppSourceEntry,\n readPanelAppFolderManifest,\n resolvePanelAppAssetContentType,\n resolvePanelAppRelativePath,\n type PanelAppAsset,\n type PanelAppSource,\n} from \"@kernel/utils/panel-app-source.utils.js\";\n\nexport class PanelAppSourceService {\n listSources = async (panelsPath: string): Promise<PanelAppSource[]> => {\n try {\n const entries = await readdir(panelsPath, { withFileTypes: true });\n const sources: PanelAppSource[] = [];\n for (const entry of entries.filter(isPanelAppSourceEntry)) {\n try {\n sources.push(await this.readSource(panelsPath, entry.name));\n } catch (error) {\n if (!isPanelAppError(error) || error.code !== \"PANEL_APP_NOT_FOUND\") {\n throw error;\n }\n }\n }\n return sources;\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n return [];\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n resolveSource = async (\n panelsPath: string,\n id: string,\n ): Promise<PanelAppSource> => {\n const sourceName = decodePanelAppId(id);\n try {\n return await this.readSource(panelsPath, sourceName);\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n getAsset = async (\n panelsPath: string,\n id: string,\n assetPath: string,\n ): Promise<PanelAppAsset> => {\n const source = await this.resolveSource(panelsPath, id);\n if (source.kind !== \"folder\") {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app asset not found\");\n }\n const filePath = resolvePanelAppRelativePath(source.sourcePath, assetPath);\n try {\n const fileStat = await stat(filePath);\n if (!fileStat.isFile()) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app asset not found\");\n }\n return {\n content: await readFile(filePath),\n contentType: resolvePanelAppAssetContentType(filePath),\n };\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app asset not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n private readSource = async (\n panelsPath: string,\n sourceName: string,\n ): Promise<PanelAppSource> => {\n const sourcePath = join(panelsPath, sourceName);\n const sourceStat = await stat(sourcePath);\n if (sourceStat.isFile() && isPanelAppFileName(sourceName)) {\n return {\n kind: \"single-file\",\n sourceName,\n sourcePath,\n entryPath: sourcePath,\n sourceStat,\n };\n }\n if (sourceStat.isDirectory() && isPanelAppDirName(sourceName)) {\n return await this.readFolderSource(sourcePath, sourceName, sourceStat);\n }\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n };\n\n private readFolderSource = async (\n sourcePath: string,\n sourceName: string,\n sourceStat: PanelAppSource[\"sourceStat\"],\n ): Promise<PanelAppSource> => {\n try {\n const manifest = await readPanelAppFolderManifest(sourcePath, sourceName);\n const entryPath = resolvePanelAppRelativePath(sourcePath, manifest.entry);\n const entryStat = await stat(entryPath);\n if (!entryStat.isFile()) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app entry not found\");\n }\n return {\n kind: \"folder\",\n sourceName,\n sourcePath,\n entryPath,\n manifest,\n sourceStat,\n };\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_MANIFEST_INVALID\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\"\n );\n}\n","import type { Stats } from \"node:fs\";\n\nexport type PanelAppActivityRecord = {\n createdAt: string;\n lastOpenedAt?: string;\n updatedAt: string;\n};\n\nexport function resolvePanelAppCreatedAt(fileStat: Stats): string {\n return fileStat.birthtimeMs > 0 ? fileStat.birthtime.toISOString() : fileStat.mtime.toISOString();\n}\n\nexport function resolvePanelAppActivityMs(entry: PanelAppActivityRecord): number {\n return Math.max(\n new Date(entry.lastOpenedAt ?? 0).getTime(),\n new Date(entry.createdAt).getTime(),\n new Date(entry.updatedAt).getTime(),\n );\n}\n","import { readFile } from \"node:fs/promises\";\nimport {\n encodePanelAppId,\n injectPanelAppAssetBase,\n type PanelAppSource,\n} from \"@kernel/utils/panel-app-source.utils.js\";\nimport { parsePanelAppManifest } from \"@kernel/utils/panel-app-manifest.utils.js\";\nimport type { PanelAppManifest } from \"@kernel/utils/panel-app-manifest.utils.js\";\nimport type { PanelAppSourceService } from \"@kernel/services/panel-app-source.service.js\";\nimport {\n isPanelAppError,\n PanelAppError,\n} from \"@kernel/types/panel-app.types.js\";\n\nexport type ResolvedPanelAppContentSource = {\n appId: string;\n sourceId: string;\n source: PanelAppSource;\n manifest: PanelAppManifest;\n html: string;\n htmlWithBase: string;\n};\n\nexport async function readPanelAppContentSource(params: {\n createAssetBaseHref: (source: PanelAppSource) => string;\n id: string;\n panelsPath: string;\n sourceService: PanelAppSourceService;\n}): Promise<ResolvedPanelAppContentSource> {\n const { createAssetBaseHref, id, panelsPath, sourceService } = params;\n const source = await sourceService.resolveSource(panelsPath, id);\n const html = await readFile(source.entryPath, \"utf8\");\n const manifest = source.manifest ?? parsePanelAppManifest(html);\n const sourceId = encodePanelAppId(source.sourceName);\n return {\n appId: resolvePanelAppAppId(source, manifest),\n sourceId,\n source,\n manifest,\n html,\n htmlWithBase: source.kind === \"folder\"\n ? injectPanelAppAssetBase(html, createAssetBaseHref(source))\n : html,\n };\n}\n\nexport async function readPanelAppContentSourceByIdOrAppId(params: {\n appIdOrSourceId: string;\n createAssetBaseHref: (source: PanelAppSource) => string;\n panelsPath: string;\n sourceService: PanelAppSourceService;\n}): Promise<ResolvedPanelAppContentSource> {\n const { appIdOrSourceId, createAssetBaseHref, panelsPath, sourceService } = params;\n try {\n return await readPanelAppContentSource({\n createAssetBaseHref,\n id: appIdOrSourceId,\n panelsPath,\n sourceService,\n });\n } catch (error) {\n if (!isPanelAppError(error)) {\n throw error;\n }\n if (error.code !== \"PANEL_APP_INVALID_ID\" && error.code !== \"PANEL_APP_NOT_FOUND\") {\n throw error;\n }\n }\n const sources = await sourceService.listSources(panelsPath);\n for (const source of sources) {\n const html = await readFile(source.entryPath, \"utf8\");\n const manifest = source.manifest ?? parsePanelAppManifest(html);\n if (resolvePanelAppAppId(source, manifest) === appIdOrSourceId) {\n return await readPanelAppContentSource({\n createAssetBaseHref,\n id: encodePanelAppId(source.sourceName),\n panelsPath,\n sourceService,\n });\n }\n }\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n}\n\nexport function resolvePanelAppAppId(\n source: PanelAppSource,\n manifest: PanelAppManifest,\n): string {\n return manifest.id ?? encodePanelAppId(source.sourceName);\n}\n\nexport async function assertPanelAppDeclaresClient(params: {\n appId: string;\n panelsPath: string;\n sourceService: PanelAppSourceService;\n}): Promise<void> {\n const { appId, panelsPath, sourceService } = params;\n const sources = await sourceService.listSources(panelsPath);\n for (const source of sources) {\n const manifest = source.manifest ?? parsePanelAppManifest(await readFile(source.entryPath, \"utf8\"));\n if (resolvePanelAppAppId(source, manifest) !== appId) {\n continue;\n }\n if (!manifest.client) {\n throw new PanelAppError(\n \"PANEL_APP_CLIENT_NOT_DECLARED\",\n \"panel app did not declare client access\",\n );\n }\n return;\n }\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n}\n","import { randomUUID } from \"node:crypto\";\nimport { readFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { DEFAULT_PANELS_DIR, getWorkspacePathFromConfig } from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { PanelAppAssetTokenService } from \"@kernel/services/panel-app-asset-token.service.js\";\nimport { PanelAppStateStore } from \"@kernel/stores/panel-app-state.store.js\";\nimport type { PanelAppPreferencesUpdate, PanelAppStateEntry } from \"@kernel/stores/panel-app-state.store.js\";\nimport { PanelAppCapabilityGrantStore } from \"@kernel/stores/panel-app-capability-grant.store.js\";\nimport { PanelAppClientGrantStore } from \"@kernel/stores/panel-app-client-grant.store.js\";\nimport type { PanelAppClientGrant } from \"@kernel/stores/panel-app-client-grant.store.js\";\nimport type { ServiceActionCaller } from \"@kernel/types/service-app.types.js\";\nimport type {\n PanelAppAgentCapability,\n PanelAppAgentGenerateObjectInput,\n PanelAppAgentGenerateObjectResult,\n PanelAppAgentRunClient,\n PanelAppAgentSendPayload,\n PanelAppAgentSendResult,\n PanelAppCapabilityGrant,\n} from \"@kernel/types/panel-app.types.js\";\nimport {\n isPanelAppError,\n PanelAppError,\n} from \"@kernel/types/panel-app.types.js\";\nimport { AgentRunClient } from \"@kernel/services/agent-run-client.service.js\";\nimport { PanelAppAgentBridgeService } from \"@kernel/services/panel-app-agent-bridge.service.js\";\nimport {\n getPanelAppBridgeScript,\n injectPanelAppBridgeScript,\n} from \"@kernel/utils/panel-app-bridge.utils.js\";\nimport { injectPanelAppClientScript } from \"@kernel/utils/panel-app-client-injection.utils.js\";\nimport { parsePanelAppManifest } from \"@kernel/utils/panel-app-manifest.utils.js\";\nimport {\n encodePanelAppId,\n resolvePanelAppIconUrl,\n toPanelAppTitle,\n type PanelAppAsset,\n type PanelAppSource,\n} from \"@kernel/utils/panel-app-source.utils.js\";\nimport { PanelAppSourceService } from \"@kernel/services/panel-app-source.service.js\";\nimport {\n resolvePanelAppActivityMs,\n resolvePanelAppCreatedAt,\n} from \"@kernel/utils/panel-app-time.utils.js\";\nimport {\n assertPanelAppDeclaresClient,\n readPanelAppContentSource,\n readPanelAppContentSourceByIdOrAppId,\n resolvePanelAppAppId,\n} from \"@kernel/utils/panel-app-content-source.utils.js\";\nimport type {\n EventBus,\n Ingress,\n} from \"@nextclaw/shared\";\n\nexport type { PanelAppPreferencesUpdate } from \"@kernel/stores/panel-app-state.store.js\";\n\nconst PANEL_APP_CONTENT_BASE_PATH = \"/api/panel-apps\";\nconst PANEL_APP_TOKENIZED_ASSET_BASE_PATH = \"/api/panel-app-assets\";\nconst PANEL_APP_CONTENT_TYPE = \"text/html; charset=utf-8\" as const;\nconst PANEL_APP_CAPABILITY_GRANTS_FILE_NAME = \".panel-app-capability-grants.json\";\nconst PANEL_APP_CLIENT_GRANTS_FILE_NAME = \".panel-app-client-grants.json\";\nconst PANEL_APP_RUNTIME_TOKEN_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport type PanelAppEntry = {\n id: string;\n appId: string;\n fileName: string;\n kind: \"single-file\" | \"folder\";\n title: string;\n description?: string;\n icon?: string;\n contentPath: string;\n createdAt: string;\n updatedAt: string;\n sizeBytes: number;\n favorite: boolean;\n clientDeclared: boolean;\n clientGranted: boolean;\n lastOpenedAt?: string;\n openCount: number;\n};\n\nexport type PanelAppList = {\n workspacePath: string;\n panelsPath: string;\n entries: PanelAppEntry[];\n};\n\nexport type PanelAppContent = {\n id: string;\n appId: string;\n fileName: string;\n html: string;\n contentType: typeof PANEL_APP_CONTENT_TYPE;\n capabilities: string[];\n clientDeclared: boolean;\n clientGranted: boolean;\n serviceActions: string[];\n};\n\nexport type PanelAppDeleteResult = {\n deleted: true;\n fileName: string;\n id: string;\n};\n\nexport type PanelAppBridgeSession = {\n id: string;\n token: string;\n appId: string;\n caller: ServiceActionCaller;\n declaredCapabilities: string[];\n declaredActions: string[];\n clientDeclared: boolean;\n createdAt: string;\n expiresAt: string;\n};\n\nexport class PanelAppManager {\n private readonly bridgeSessions = new Map<string, PanelAppBridgeSession>();\n private readonly agentRunClient: PanelAppAgentRunClient | null;\n private readonly agentBridgeService: PanelAppAgentBridgeService;\n private readonly assetTokenService = new PanelAppAssetTokenService();\n private readonly sourceService = new PanelAppSourceService();\n\n constructor(private readonly params: {\n agentRunClient?: PanelAppAgentRunClient;\n configManager: ConfigManager;\n eventBus?: EventBus;\n ingress?: Ingress;\n }) {\n this.agentRunClient = params.agentRunClient ??\n (params.eventBus && params.ingress\n ? new AgentRunClient({ eventBus: params.eventBus, ingress: params.ingress })\n : null);\n this.agentBridgeService = new PanelAppAgentBridgeService({\n agentRunClient: this.agentRunClient,\n createCapabilityGrantStore: this.createCapabilityGrantStore,\n });\n }\n\n listPanelApps = async (): Promise<PanelAppList> => {\n const workspacePath = this.getWorkspacePath();\n const panelsPath = this.getPanelsPath(workspacePath);\n const sources = await this.sourceService.listSources(panelsPath);\n const appState = await this.createStateStore(panelsPath).load();\n const entries = await Promise.all(\n sources.map((source) =>\n this.buildPanelAppEntry(\n source,\n appState[encodePanelAppId(source.sourceName)] ?? {},\n ),\n ),\n );\n\n return {\n workspacePath,\n panelsPath,\n entries: entries.sort(this.comparePanelApps),\n };\n };\n\n getPanelAppContent = async (id: string): Promise<PanelAppContent> => {\n try {\n const resolved = await readPanelAppContentSource({\n createAssetBaseHref: this.createAssetBaseHref,\n id,\n panelsPath: this.getPanelsPath(this.getWorkspacePath()),\n sourceService: this.sourceService,\n });\n const clientGranted = await this.isPanelAppClientGranted(\n resolved.appId,\n resolved.manifest.client,\n );\n const session = this.createPanelAppRuntimeTokenSession({\n appId: resolved.appId,\n clientDeclared: resolved.manifest.client,\n declaredActions: resolved.manifest.serviceActions,\n declaredCapabilities: resolved.manifest.capabilities,\n });\n const htmlWithBridge = injectPanelAppBridgeScript(resolved.htmlWithBase, {\n appId: resolved.appId,\n runtimeToken: session.token,\n });\n const html = resolved.manifest.client && clientGranted\n ? injectPanelAppClientScript(htmlWithBridge, { runtimeToken: session.token })\n : htmlWithBridge;\n return {\n id: resolved.sourceId,\n appId: resolved.appId,\n fileName: resolved.source.sourceName,\n html,\n capabilities: resolved.manifest.capabilities,\n clientDeclared: resolved.manifest.client,\n clientGranted,\n contentType: PANEL_APP_CONTENT_TYPE,\n serviceActions: resolved.manifest.serviceActions,\n };\n } catch (error) {\n if (isPanelAppError(error)) {\n throw error;\n }\n if (this.isMissingFileError(error)) {\n throw new PanelAppError(\"PANEL_APP_NOT_FOUND\", \"panel app not found\");\n }\n throw new PanelAppError(\n \"PANEL_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n getPanelAppAsset = async (id: string, assetPath: string): Promise<PanelAppAsset> => {\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n return await this.sourceService.getAsset(panelsPath, id, assetPath);\n };\n\n getPanelAppAssetByToken = async (\n token: string,\n assetPath: string,\n ): Promise<PanelAppAsset> => {\n const claims = this.assetTokenService.verify(token);\n if (encodePanelAppId(claims.sourceName) !== claims.panelAppId) {\n throw new PanelAppError(\n \"PANEL_APP_ASSET_TOKEN_INVALID\",\n \"invalid panel app asset token\",\n );\n }\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n return await this.sourceService.getAsset(panelsPath, claims.panelAppId, assetPath);\n };\n\n getPanelAppBridgeScript = (): string =>\n getPanelAppBridgeScript({ appId: \"\", runtimeToken: \"\" });\n\n createPanelAppRuntimeTokenSession = (params: {\n appId: string;\n clientDeclared: boolean;\n declaredActions: string[];\n declaredCapabilities: string[];\n }): PanelAppBridgeSession => {\n const {\n appId,\n clientDeclared,\n declaredActions,\n declaredCapabilities,\n } = params;\n const now = new Date();\n const session: PanelAppBridgeSession = {\n id: randomUUID(),\n token: randomUUID(),\n appId,\n caller: {\n surface: \"panel-app\",\n appId,\n },\n declaredCapabilities,\n declaredActions,\n clientDeclared,\n createdAt: now.toISOString(),\n expiresAt: new Date(now.getTime() + PANEL_APP_RUNTIME_TOKEN_TTL_MS).toISOString(),\n };\n this.bridgeSessions.set(session.token, session);\n return session;\n };\n\n createPanelAppBridgeSession = async (params: {\n id: string;\n }): Promise<PanelAppBridgeSession> => {\n const resolved = await readPanelAppContentSourceByIdOrAppId({\n appIdOrSourceId: params.id,\n createAssetBaseHref: this.createAssetBaseHref,\n panelsPath: this.getPanelsPath(this.getWorkspacePath()),\n sourceService: this.sourceService,\n });\n return this.createPanelAppRuntimeTokenSession({\n appId: resolved.appId,\n clientDeclared: resolved.manifest.client,\n declaredActions: resolved.manifest.serviceActions,\n declaredCapabilities: resolved.manifest.capabilities,\n });\n };\n\n grantPanelAppClient = async (appId: string): Promise<PanelAppClientGrant> => {\n await assertPanelAppDeclaresClient({\n appId,\n panelsPath: this.getPanelsPath(this.getWorkspacePath()),\n sourceService: this.sourceService,\n });\n return await this.createClientGrantStore().grant({\n appId,\n grantedAt: new Date().toISOString(),\n });\n };\n\n revokePanelAppClient = async (appId: string): Promise<void> => {\n await this.createClientGrantStore().revoke(appId);\n };\n\n resolvePanelAppBridgeSession = (token: string): PanelAppBridgeSession => {\n this.deleteExpiredBridgeSessions();\n const session = this.bridgeSessions.get(token.trim());\n if (!session) {\n throw new PanelAppError(\n \"PANEL_APP_BRIDGE_SESSION_NOT_FOUND\",\n \"panel app bridge session not found\",\n );\n }\n return session;\n };\n\n deletePanelAppBridgeSession = (token: string): void => {\n this.bridgeSessions.delete(token.trim());\n };\n\n sendAgentMessage = async (\n bridgeSessionToken: string,\n payload: PanelAppAgentSendPayload,\n ): Promise<PanelAppAgentSendResult> => {\n const bridgeSession = this.resolvePanelAppBridgeSession(bridgeSessionToken);\n return await this.agentBridgeService.sendAgentMessage(bridgeSession, payload);\n };\n\n generateAgentObject = async (\n bridgeSessionToken: string,\n input: PanelAppAgentGenerateObjectInput,\n ): Promise<PanelAppAgentGenerateObjectResult> => {\n const bridgeSession = this.resolvePanelAppBridgeSession(bridgeSessionToken);\n return await this.agentBridgeService.generateAgentObject(bridgeSession, input);\n };\n\n grantAgentCapability = async (\n bridgeSessionToken: string,\n capability: PanelAppAgentCapability,\n ): Promise<PanelAppCapabilityGrant> => {\n const bridgeSession = this.resolvePanelAppBridgeSession(bridgeSessionToken);\n return await this.agentBridgeService.grantAgentCapability(bridgeSession, capability);\n };\n\n updatePanelAppPreferences = async (\n id: string,\n preferences: PanelAppPreferencesUpdate,\n ): Promise<PanelAppEntry> => {\n const fileName = await this.resolvePanelAppFileName(id);\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n const state = await this.createStateStore(panelsPath).updatePreferences(\n encodePanelAppId(fileName),\n preferences,\n );\n return await this.buildPanelAppEntry(\n await this.sourceService.resolveSource(panelsPath, encodePanelAppId(fileName)),\n state,\n );\n };\n\n recordPanelAppOpened = async (id: string): Promise<PanelAppEntry> => {\n const fileName = await this.resolvePanelAppFileName(id);\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n const state = await this.createStateStore(panelsPath).recordOpened(\n encodePanelAppId(fileName),\n );\n return await this.buildPanelAppEntry(\n await this.sourceService.resolveSource(panelsPath, encodePanelAppId(fileName)),\n state,\n );\n };\n\n deletePanelApp = async (id: string): Promise<PanelAppDeleteResult> => {\n const panelsPath = this.getPanelsPath(this.getWorkspacePath());\n const source = await this.sourceService.resolveSource(panelsPath, id);\n const panelAppId = encodePanelAppId(source.sourceName);\n const manifest = source.manifest ?? parsePanelAppManifest(await readFile(source.entryPath, \"utf8\"));\n const appId = resolvePanelAppAppId(source, manifest);\n await rm(source.sourcePath, { recursive: source.kind === \"folder\" });\n await this.createStateStore(panelsPath).deleteEntry(panelAppId);\n await this.createCapabilityGrantStore().deleteCaller({\n surface: \"panel-app\",\n appId,\n });\n await this.createClientGrantStore().revoke(appId);\n this.deleteBridgeSessionsByPanelAppId(appId);\n return { deleted: true, fileName: source.sourceName, id: panelAppId };\n };\n\n private getWorkspacePath = (): string =>\n getWorkspacePathFromConfig(this.params.configManager.config);\n\n private getPanelsPath = (workspacePath: string): string =>\n join(workspacePath, DEFAULT_PANELS_DIR);\n\n private createAssetBaseHref = (source: PanelAppSource): string => {\n const token = this.assetTokenService.issue({\n panelAppId: encodePanelAppId(source.sourceName),\n sourceName: source.sourceName,\n });\n return `${PANEL_APP_TOKENIZED_ASSET_BASE_PATH}/${encodeURIComponent(token)}/`;\n };\n\n private createStateStore = (panelsPath: string): PanelAppStateStore =>\n new PanelAppStateStore(panelsPath);\n\n private createCapabilityGrantStore = (): PanelAppCapabilityGrantStore =>\n new PanelAppCapabilityGrantStore(\n join(this.getPanelsPath(this.getWorkspacePath()), PANEL_APP_CAPABILITY_GRANTS_FILE_NAME),\n );\n\n private createClientGrantStore = (): PanelAppClientGrantStore =>\n new PanelAppClientGrantStore(\n join(this.getPanelsPath(this.getWorkspacePath()), PANEL_APP_CLIENT_GRANTS_FILE_NAME),\n );\n\n private buildPanelAppEntry = async (\n source: PanelAppSource,\n state: PanelAppStateEntry,\n ): Promise<PanelAppEntry> => {\n const manifest = source.manifest ?? parsePanelAppManifest(await readFile(source.entryPath, \"utf8\"));\n const id = encodePanelAppId(source.sourceName);\n const appId = resolvePanelAppAppId(source, manifest);\n const createdAt = resolvePanelAppCreatedAt(source.sourceStat);\n const updatedAt = source.sourceStat.mtime.toISOString();\n const entry: PanelAppEntry = {\n id,\n appId,\n fileName: source.sourceName,\n kind: source.kind,\n title: manifest.title ?? toPanelAppTitle(source.sourceName),\n contentPath: `${PANEL_APP_CONTENT_BASE_PATH}/${encodeURIComponent(id)}/content`,\n createdAt,\n updatedAt,\n sizeBytes: source.sourceStat.size,\n favorite: state.favorite ?? false,\n clientDeclared: manifest.client,\n clientGranted: await this.isPanelAppClientGranted(appId, manifest.client),\n openCount: state.openCount ?? 0,\n };\n if (manifest.description) {\n entry.description = manifest.description;\n }\n if (manifest.icon) {\n entry.icon = source.kind === \"folder\"\n ? resolvePanelAppIconUrl(id, manifest.icon)\n : manifest.icon;\n }\n if (state.lastOpenedAt) {\n entry.lastOpenedAt = state.lastOpenedAt;\n }\n return entry;\n };\n\n private resolvePanelAppFileName = async (id: string): Promise<string> => {\n const source = await this.sourceService.resolveSource(\n this.getPanelsPath(this.getWorkspacePath()),\n id,\n );\n return source.sourceName;\n };\n\n private comparePanelApps = (left: PanelAppEntry, right: PanelAppEntry): number =>\n resolvePanelAppActivityMs(right) - resolvePanelAppActivityMs(left) ||\n Number(right.favorite) - Number(left.favorite) ||\n left.title.localeCompare(right.title);\n\n private deleteExpiredBridgeSessions = (): void => {\n const now = Date.now();\n for (const [token, session] of this.bridgeSessions) {\n if (new Date(session.expiresAt).getTime() <= now) {\n this.bridgeSessions.delete(token);\n }\n }\n };\n\n private deleteBridgeSessionsByPanelAppId = (panelAppId: string): void => {\n for (const [token, session] of this.bridgeSessions) {\n if (session.appId === panelAppId) {\n this.bridgeSessions.delete(token);\n }\n }\n };\n\n private isPanelAppClientGranted = async (\n appId: string,\n clientDeclared: boolean,\n ): Promise<boolean> => {\n if (!clientDeclared) {\n return false;\n }\n return await this.createClientGrantStore().isGranted(appId);\n };\n\n private isMissingFileError = (error: unknown): boolean =>\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n","import type {\n ServiceActionCaller,\n ServiceActionGrantState,\n ServiceActionRisk,\n} from \"@kernel/types/service-app.types.js\";\n\nexport const DEFAULT_SERVICE_ACTION_RISK: ServiceActionRisk = \"dangerous\";\n\nexport function buildServiceActionId(appId: string, actionName: string): string {\n return `${appId}.${actionName}`;\n}\n\nexport function getServiceActionName(actionId: string, appId: string): string {\n const prefix = `${appId}.`;\n if (!actionId.startsWith(prefix)) {\n throw new Error(\"service action does not belong to service app.\");\n }\n const name = actionId.slice(prefix.length).trim();\n if (!name) {\n throw new Error(\"service action name is required.\");\n }\n return name;\n}\n\nexport function getServiceActionCallerKey(caller: ServiceActionCaller): string {\n return `${caller.surface}:${caller.appId}`;\n}\n\nexport function parseServiceActionCallerKey(key: string): ServiceActionCaller | null {\n const [surface, appId, ...rest] = key.split(\":\");\n if (surface !== \"panel-app\" || !appId || rest.length > 0) {\n return null;\n }\n return { surface, appId };\n}\n\nexport function resolveServiceActionGrantState({\n actionId,\n declaredActions,\n granted,\n}: {\n actionId: string;\n declaredActions?: readonly string[];\n granted: boolean;\n}): ServiceActionGrantState {\n if (declaredActions && !declaredActions.includes(actionId)) {\n return \"not-declared\";\n }\n return granted ? \"granted\" : \"not-granted\";\n}\n","import type { Config } from \"@nextclaw/core\";\nimport { McpServerLifecycleManager } from \"@nextclaw/mcp\";\nimport type { McpServerRecord, McpToolCatalogEntry } from \"@nextclaw/mcp\";\nimport type {\n ServiceAction,\n ServiceAppManifest,\n ServiceAppRecord,\n ServiceAppRuntimeStatus,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n buildServiceActionId,\n DEFAULT_SERVICE_ACTION_RISK,\n} from \"@kernel/utils/service-action.utils.js\";\n\ntype RuntimeState = {\n status: ServiceAppRuntimeStatus;\n lastError?: string;\n lastStartedAt?: string;\n lastReadyAt?: string;\n lastFailedAt?: string;\n};\n\nexport class McpServiceAppRuntimeService {\n private readonly lifecycleManager: McpServerLifecycleManager;\n private readonly states = new Map<string, RuntimeState>();\n\n constructor(private readonly params: { getConfig: () => Config }) {\n this.lifecycleManager = new McpServerLifecycleManager({\n getConfig: params.getConfig,\n });\n }\n\n getStatus = (appId: string): RuntimeState => {\n return this.states.get(appId) ?? { status: \"idle\" };\n };\n\n listActions = async ({\n app,\n manifest,\n }: {\n app: ServiceAppRecord;\n manifest: ServiceAppManifest;\n }): Promise<ServiceAction[]> => {\n if (!app.enabled) {\n return [];\n }\n const lastStartedAt = new Date().toISOString();\n this.states.set(app.id, { status: \"starting\", lastStartedAt });\n try {\n const state = await this.lifecycleManager.warmServer(\n this.toMcpServerRecord(app, manifest),\n );\n this.states.set(app.id, {\n status: \"running\",\n lastStartedAt,\n lastReadyAt: state.lastReadyAt,\n });\n return state.tools.map((tool) => this.toServiceAction(manifest, tool));\n } catch (error) {\n const lastError = error instanceof Error ? error.message : String(error);\n this.states.set(app.id, {\n status: \"failed\",\n lastError,\n lastStartedAt,\n lastFailedAt: new Date().toISOString(),\n });\n return [];\n }\n };\n\n invokeAction = async ({\n app,\n manifest,\n actionName,\n input,\n }: {\n app: ServiceAppRecord;\n manifest: ServiceAppManifest;\n actionName: string;\n input: Record<string, unknown>;\n }): Promise<unknown> => {\n const lastStartedAt = new Date().toISOString();\n this.states.set(app.id, { status: \"starting\", lastStartedAt });\n try {\n const result = await this.lifecycleManager.callTool(\n this.toMcpServerRecord(app, manifest),\n actionName,\n input,\n );\n this.states.set(app.id, {\n status: \"running\",\n lastStartedAt,\n lastReadyAt: new Date().toISOString(),\n });\n return result;\n } catch (error) {\n const lastError = error instanceof Error ? error.message : String(error);\n this.states.set(app.id, {\n status: \"failed\",\n lastError,\n lastStartedAt,\n lastFailedAt: new Date().toISOString(),\n });\n throw error;\n }\n };\n\n restart = async (appId: string): Promise<void> => {\n await this.lifecycleManager.closeServer(appId);\n this.states.set(appId, { status: \"idle\" });\n };\n\n dispose = async (): Promise<void> => {\n await this.lifecycleManager.closeAll();\n this.states.clear();\n };\n\n private toMcpServerRecord = (\n app: ServiceAppRecord,\n manifest: ServiceAppManifest,\n ): McpServerRecord => ({\n name: app.id,\n definition: {\n enabled: manifest.enabled,\n transport: {\n type: \"stdio\",\n command: manifest.command,\n args: manifest.args,\n cwd: app.dirPath,\n env: {},\n stderr: \"pipe\",\n },\n scope: {\n allAgents: false,\n agents: [],\n },\n policy: {\n trust: \"explicit\",\n start: \"eager\",\n },\n },\n });\n\n private toServiceAction = (\n manifest: ServiceAppManifest,\n tool: McpToolCatalogEntry,\n ): ServiceAction => {\n const actionId = buildServiceActionId(manifest.id, tool.toolName);\n const manifestAction = manifest.actions[tool.toolName];\n const risk = manifestAction?.risk ?? DEFAULT_SERVICE_ACTION_RISK;\n return {\n id: actionId,\n appId: manifest.id,\n name: tool.toolName,\n title: manifestAction?.title ?? tool.toolName,\n description: manifestAction?.description ?? tool.description,\n inputSchema: tool.parameters,\n risk,\n };\n };\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type {\n ServiceActionCaller,\n ServiceActionGrant,\n ServiceActionRisk,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n getServiceActionCallerKey,\n parseServiceActionCallerKey,\n} from \"@kernel/utils/service-action.utils.js\";\n\ntype StoredServiceActionGrant = {\n grantedAt: string;\n risk: ServiceActionRisk;\n};\n\ntype ServiceActionGrantStoreData = {\n version: 1;\n grants: Record<string, {\n actions: Record<string, StoredServiceActionGrant>;\n }>;\n};\n\nconst EMPTY_GRANTS: ServiceActionGrantStoreData = {\n version: 1,\n grants: {},\n};\n\nexport class ServiceActionGrantStore {\n constructor(private readonly storePath: string) {}\n\n isGranted = async (\n caller: ServiceActionCaller,\n actionId: string,\n ): Promise<boolean> => {\n const data = await this.load();\n return Boolean(data.grants[getServiceActionCallerKey(caller)]?.actions[actionId]);\n };\n\n grant = async ({\n actionId,\n caller,\n grantedAt,\n risk,\n }: {\n caller: ServiceActionCaller;\n actionId: string;\n risk: ServiceActionRisk;\n grantedAt: string;\n }): Promise<ServiceActionGrant> => {\n const data = await this.load();\n const callerKey = getServiceActionCallerKey(caller);\n const callerGrants = data.grants[callerKey] ?? { actions: {} };\n callerGrants.actions[actionId] = {\n grantedAt,\n risk,\n };\n data.grants[callerKey] = callerGrants;\n await this.save(data);\n return {\n caller,\n actionId,\n risk,\n grantedAt,\n };\n };\n\n list = async (): Promise<ServiceActionGrant[]> => {\n const data = await this.load();\n return Object.entries(data.grants).flatMap(([callerKey, callerGrants]) => {\n const caller = parseServiceActionCallerKey(callerKey);\n if (!caller) {\n return [];\n }\n return Object.entries(callerGrants.actions).map(([actionId, grant]) => ({\n caller,\n actionId,\n risk: grant.risk,\n grantedAt: grant.grantedAt,\n }));\n }).sort((left, right) =>\n new Date(right.grantedAt).getTime() - new Date(left.grantedAt).getTime()\n );\n };\n\n revoke = async (\n caller: ServiceActionCaller,\n actionId: string,\n ): Promise<void> => {\n const data = await this.load();\n const callerKey = getServiceActionCallerKey(caller);\n const callerGrants = data.grants[callerKey];\n if (!callerGrants) {\n return;\n }\n delete callerGrants.actions[actionId];\n if (Object.keys(callerGrants.actions).length === 0) {\n delete data.grants[callerKey];\n }\n await this.save(data);\n };\n\n revokeActionsByPrefix = async (actionIdPrefix: string): Promise<void> => {\n const data = await this.load();\n let changed = false;\n for (const [callerKey, callerGrants] of Object.entries(data.grants)) {\n for (const actionId of Object.keys(callerGrants.actions)) {\n if (actionId.startsWith(actionIdPrefix)) {\n delete callerGrants.actions[actionId];\n changed = true;\n }\n }\n if (Object.keys(callerGrants.actions).length === 0) {\n delete data.grants[callerKey];\n }\n }\n if (changed) {\n await this.save(data);\n }\n };\n\n private load = async (): Promise<ServiceActionGrantStoreData> => {\n try {\n return normalizeStoreData(JSON.parse(await readFile(this.storePath, \"utf8\")));\n } catch (error) {\n if (isMissingFileError(error)) {\n return structuredClone(EMPTY_GRANTS);\n }\n throw error;\n }\n };\n\n private save = async (data: ServiceActionGrantStoreData): Promise<void> => {\n await mkdir(dirname(this.storePath), { recursive: true });\n await writeFile(this.storePath, `${JSON.stringify(data, null, 2)}\\n`, \"utf8\");\n };\n}\n\nfunction normalizeStoreData(value: unknown): ServiceActionGrantStoreData {\n if (!isRecord(value) || value.version !== 1 || !isRecord(value.grants)) {\n return structuredClone(EMPTY_GRANTS);\n }\n const grants: ServiceActionGrantStoreData[\"grants\"] = {};\n for (const [callerKey, callerValue] of Object.entries(value.grants)) {\n if (!isRecord(callerValue) || !isRecord(callerValue.actions)) {\n continue;\n }\n const actions: Record<string, StoredServiceActionGrant> = {};\n for (const [actionId, actionValue] of Object.entries(callerValue.actions)) {\n if (\n isRecord(actionValue) &&\n typeof actionValue.grantedAt === \"string\" &&\n isServiceActionRisk(actionValue.risk)\n ) {\n actions[actionId] = {\n grantedAt: actionValue.grantedAt,\n risk: actionValue.risk,\n };\n }\n }\n grants[callerKey] = { actions };\n }\n return { version: 1, grants };\n}\n\nfunction isServiceActionRisk(value: unknown): value is ServiceActionRisk {\n return (\n value === \"read\" ||\n value === \"write\" ||\n value === \"external\" ||\n value === \"dangerous\"\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 isMissingFileError(error: unknown): boolean {\n return isRecord(error) && error.code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type {\n ServiceActionRisk,\n ServiceAppManifest,\n ServiceAppManifestAction,\n} from \"@kernel/types/service-app.types.js\";\n\nconst SERVICE_APP_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst SERVICE_ACTION_RISKS = new Set<ServiceActionRisk>([\n \"read\",\n \"write\",\n \"external\",\n \"dangerous\",\n]);\n\nexport const SERVICE_APP_MANIFEST_FILE_NAME = \"service-app.json\";\n\nexport function getServiceAppManifestPath(dirPath: string): string {\n return join(dirPath, SERVICE_APP_MANIFEST_FILE_NAME);\n}\n\nexport async function readServiceAppManifest(\n dirPath: string,\n): Promise<ServiceAppManifest> {\n return parseServiceAppManifest(\n await readFile(getServiceAppManifestPath(dirPath), \"utf8\"),\n );\n}\n\nexport function parseServiceAppManifest(raw: string): ServiceAppManifest {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new Error(\n `service-app.json is not valid JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n\n if (!isRecord(parsed)) {\n throw new Error(\"service-app.json must contain an object.\");\n }\n\n const id = readRequiredString(parsed, \"id\");\n if (!SERVICE_APP_ID_PATTERN.test(id)) {\n throw new Error(\"service app id must be kebab-case.\");\n }\n\n const protocol = readOptionalString(parsed, \"protocol\") ?? \"mcp\";\n if (protocol !== \"mcp\") {\n throw new Error(\"service app protocol must be mcp.\");\n }\n\n return {\n id,\n title: readRequiredString(parsed, \"title\"),\n description: readOptionalString(parsed, \"description\"),\n enabled: readOptionalBoolean(parsed, \"enabled\") ?? true,\n protocol,\n command: readRequiredString(parsed, \"command\"),\n args: readStringArray(parsed.args, \"args\"),\n actions: readManifestActions(parsed.actions),\n };\n}\n\nfunction readManifestActions(value: unknown): Record<string, ServiceAppManifestAction> {\n if (value === undefined) {\n throw new Error(\"service app actions are required.\");\n }\n if (!isRecord(value)) {\n throw new Error(\"service app actions must be an object.\");\n }\n if (Object.keys(value).length === 0) {\n throw new Error(\"service app actions cannot be empty.\");\n }\n\n const actions: Record<string, ServiceAppManifestAction> = {};\n for (const [name, action] of Object.entries(value)) {\n if (!name.trim()) {\n throw new Error(\"service app action name cannot be empty.\");\n }\n if (!isRecord(action)) {\n throw new Error(`service app action ${name} must be an object.`);\n }\n const risk = readOptionalString(action, \"risk\");\n if (risk !== undefined && !SERVICE_ACTION_RISKS.has(risk as ServiceActionRisk)) {\n throw new Error(`service app action ${name} has invalid risk.`);\n }\n const inputSchema = action.inputSchema;\n if (inputSchema !== undefined && !isRecord(inputSchema)) {\n throw new Error(`service app action ${name} inputSchema must be an object.`);\n }\n actions[name] = {\n risk: risk as ServiceActionRisk | undefined,\n title: readOptionalString(action, \"title\"),\n description: readOptionalString(action, \"description\"),\n inputSchema,\n };\n }\n return actions;\n}\n\nfunction readRequiredString(record: Record<string, unknown>, key: string): string {\n const value = readOptionalString(record, key);\n if (!value) {\n throw new Error(`service app ${key} is required.`);\n }\n return value;\n}\n\nfunction readOptionalString(\n record: Record<string, unknown>,\n key: string,\n): string | undefined {\n return typeof record[key] === \"string\" && record[key].trim()\n ? record[key].trim()\n : undefined;\n}\n\nfunction readOptionalBoolean(\n record: Record<string, unknown>,\n key: string,\n): boolean | undefined {\n if (record[key] === undefined) {\n return undefined;\n }\n if (typeof record[key] !== \"boolean\") {\n throw new Error(`service app ${key} must be boolean.`);\n }\n return record[key];\n}\n\nfunction readStringArray(value: unknown, key: string): string[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n throw new Error(`service app ${key} must be a string array.`);\n }\n return value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n","import type {\n ServiceAction,\n ServiceAppManifest,\n ServiceAppRecord,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n buildServiceActionId,\n DEFAULT_SERVICE_ACTION_RISK,\n} from \"@kernel/utils/service-action.utils.js\";\n\nexport function listServiceAppManifestActions(\n record: ServiceAppRecord,\n manifest: ServiceAppManifest,\n): ServiceAction[] {\n if (!record.enabled) {\n return [];\n }\n return Object.entries(manifest.actions)\n .map(([name, action]) => ({\n id: buildServiceActionId(record.id, name),\n appId: record.id,\n name,\n title: action.title ?? name,\n description: action.description,\n inputSchema: action.inputSchema,\n risk: action.risk ?? DEFAULT_SERVICE_ACTION_RISK,\n }))\n .sort((left, right) => left.id.localeCompare(right.id));\n}\n\nexport function mergeServiceAppRuntimeActions({\n record,\n manifest,\n runtimeActions,\n}: {\n record: ServiceAppRecord;\n manifest: ServiceAppManifest;\n runtimeActions: ServiceAction[];\n}): ServiceAction[] {\n const runtimeByName = new Map(runtimeActions.map((action) => [action.name, action]));\n const declared = listServiceAppManifestActions(record, manifest).map((action) => {\n const runtimeAction = runtimeByName.get(action.name);\n return {\n ...action,\n description: runtimeAction?.description ?? action.description,\n inputSchema: runtimeAction?.inputSchema ?? action.inputSchema,\n runtimeState: runtimeAction ? \"matched\" as const : \"missing\" as const,\n };\n });\n const undeclared = runtimeActions\n .filter((action) => !Object.hasOwn(manifest.actions, action.name))\n .map((action) => ({\n ...action,\n risk: DEFAULT_SERVICE_ACTION_RISK,\n runtimeState: \"undeclared\" as const,\n }));\n return [...declared, ...undeclared].sort((left, right) => left.id.localeCompare(right.id));\n}\n","import { readdir, rm, stat } from \"node:fs/promises\";\nimport { basename, join } from \"node:path\";\nimport {\n DEFAULT_SERVICE_APPS_DIR,\n getWorkspacePathFromConfig,\n} from \"@nextclaw/core\";\nimport type { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { McpServiceAppRuntimeService } from \"@kernel/services/mcp-service-app-runtime.service.js\";\nimport { ServiceActionGrantStore } from \"@kernel/stores/service-action-grant.store.js\";\nimport type {\n ServiceAction,\n ServiceActionCaller,\n ServiceActionGrant,\n ServiceActionGrantRequest,\n ServiceActionInvokeRequest,\n ServiceActionInvokeResult,\n ServiceAppManifest,\n ServiceAppRecord,\n} from \"@kernel/types/service-app.types.js\";\nimport {\n getServiceAppManifestPath,\n readServiceAppManifest,\n} from \"@kernel/utils/service-app-manifest.utils.js\";\nimport {\n getServiceActionName,\n resolveServiceActionGrantState,\n} from \"@kernel/utils/service-action.utils.js\";\nimport {\n listServiceAppManifestActions,\n mergeServiceAppRuntimeActions,\n} from \"@kernel/utils/service-app-runtime-action.utils.js\";\n\nconst SERVICE_ACTION_GRANTS_FILE_NAME = \".service-action-grants.json\";\n\nexport type ServiceAppList = {\n workspacePath: string;\n serviceAppsPath: string;\n entries: ServiceAppRecord[];\n};\n\nexport type ServiceAppDeleteResult = {\n deleted: true;\n id: string;\n};\n\nexport type ServiceAppErrorCode =\n | \"AUTHORIZATION_REQUIRED\"\n | \"SERVICE_APP_ACTION_NOT_DECLARED\"\n | \"SERVICE_APP_ACTION_NOT_FOUND\"\n | \"SERVICE_APP_INVALID_ACTION\"\n | \"SERVICE_APP_INVALID_CALLER\"\n | \"SERVICE_APP_INVALID_MANIFEST\"\n | \"SERVICE_APP_NOT_FOUND\"\n | \"SERVICE_APP_READ_FAILED\"\n | \"SERVICE_APP_RUNTIME_FAILED\";\n\nexport class ServiceAppError extends Error {\n constructor(\n readonly code: ServiceAppErrorCode,\n message: string,\n ) {\n super(message);\n this.name = \"ServiceAppError\";\n }\n}\n\nexport function isServiceAppError(error: unknown): error is ServiceAppError {\n return error instanceof ServiceAppError;\n}\n\nexport class ServiceAppManager {\n private readonly runtimeService: ServiceAppRuntime;\n\n constructor(private readonly params: {\n configManager: ConfigManager;\n runtimeService?: ServiceAppRuntime;\n }) {\n this.runtimeService = params.runtimeService ?? new McpServiceAppRuntimeService({\n getConfig: () => params.configManager.config,\n });\n }\n\n listServiceApps = async (): Promise<ServiceAppList> => {\n const workspacePath = this.getWorkspacePath();\n const serviceAppsPath = this.getServiceAppsPath(workspacePath);\n const dirNames = await this.listServiceAppDirNames(serviceAppsPath);\n const entries = await Promise.all(\n dirNames.map((dirName) => this.buildServiceAppRecord(serviceAppsPath, dirName)),\n );\n return {\n workspacePath,\n serviceAppsPath,\n entries: entries\n .filter((entry): entry is ServiceAppRecord => Boolean(entry))\n .sort((left, right) => left.title.localeCompare(right.title)),\n };\n };\n\n getServiceApp = async (appId: string): Promise<ServiceAppRecord> => {\n const { record } = await this.requireServiceApp(appId);\n return record;\n };\n\n listServiceActions = async (params: {\n caller?: ServiceActionCaller;\n appId?: string;\n declaredActions?: readonly string[];\n } = {}): Promise<ServiceAction[]> => {\n const manifests = params.appId\n ? [await this.requireServiceApp(params.appId)]\n : await this.listValidServiceApps();\n const actions = manifests.flatMap(({ manifest, record }) =>\n this.listManifestActions(record, manifest),\n );\n return await Promise.all(\n actions.map(async (action) => await this.withGrantState(action, params)),\n );\n };\n\n discoverServiceAppActions = async (appId: string): Promise<ServiceAction[]> => {\n const { manifest, record } = await this.requireServiceApp(appId);\n const runtimeActions = await this.runtimeService.listActions({ app: record, manifest });\n return mergeServiceAppRuntimeActions({ record, manifest, runtimeActions });\n };\n\n invokeServiceAction = async (\n actionId: string,\n request: ServiceActionInvokeRequest,\n ): Promise<ServiceActionInvokeResult> => {\n this.assertCaller(request.caller);\n this.assertDeclaredAction(actionId, request.declaredActions);\n const { manifest, record } = await this.requireServiceAppForAction(actionId);\n const actionName = getServiceActionName(actionId, record.id);\n if (!Object.hasOwn(manifest.actions, actionName)) {\n throw new ServiceAppError(\"SERVICE_APP_ACTION_NOT_FOUND\", \"service action not found\");\n }\n if (!await this.createGrantStore().isGranted(request.caller, actionId)) {\n throw new ServiceAppError(\n \"AUTHORIZATION_REQUIRED\",\n `This panel app needs permission to call ${actionId}.`,\n );\n }\n const result = await this.runtimeService.invokeAction({\n app: record,\n manifest,\n actionName,\n input: request.input ?? {},\n });\n return { actionId, result };\n };\n\n grantServiceAction = async (\n actionId: string,\n request: ServiceActionGrantRequest,\n ): Promise<ServiceActionGrant> => {\n const [grant] = await this.grantServiceActions([actionId], request);\n if (!grant) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_ACTION\", \"service action id is invalid\");\n }\n return grant;\n };\n\n grantServiceActions = async (\n actionIds: readonly string[],\n request: ServiceActionGrantRequest,\n ): Promise<ServiceActionGrant[]> => {\n this.assertCaller(request.caller);\n const normalizedActionIds = this.normalizeActionIds(actionIds);\n if (normalizedActionIds.length === 0) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_ACTION\", \"service action id is invalid\");\n }\n const actions: ServiceAction[] = [];\n for (const actionId of normalizedActionIds) {\n this.assertDeclaredAction(actionId, request.declaredActions);\n actions.push(await this.requireServiceAction(actionId));\n }\n const grantedAt = new Date().toISOString();\n const grantStore = this.createGrantStore();\n const grants: ServiceActionGrant[] = [];\n for (const action of actions) {\n grants.push(await grantStore.grant({\n caller: request.caller,\n actionId: action.id,\n risk: action.risk,\n grantedAt,\n }));\n }\n return grants;\n };\n\n listServiceActionGrants = async (): Promise<ServiceActionGrant[]> => {\n return await this.createGrantStore().list();\n };\n\n revokeServiceAction = async (\n caller: ServiceActionCaller,\n actionId: string,\n ): Promise<void> => {\n this.assertCaller(caller);\n await this.createGrantStore().revoke(caller, actionId);\n };\n\n restartServiceApp = async (appId: string): Promise<ServiceAppRecord> => {\n const { record } = await this.requireServiceApp(appId);\n await this.runtimeService.restart(record.id);\n return await this.getServiceApp(appId);\n };\n\n deleteServiceApp = async (appId: string): Promise<ServiceAppDeleteResult> => {\n const { record } = await this.requireServiceApp(appId);\n await this.runtimeService.restart(record.id);\n await rm(record.dirPath, { recursive: true });\n await this.createGrantStore().revokeActionsByPrefix(`${record.id}.`);\n return {\n deleted: true,\n id: record.id,\n };\n };\n\n dispose = async (): Promise<void> => {\n await this.runtimeService.dispose();\n };\n\n private withGrantState = async (\n action: ServiceAction,\n params: {\n caller?: ServiceActionCaller;\n declaredActions?: readonly string[];\n },\n ): Promise<ServiceAction> => {\n if (!params.caller) {\n return action;\n }\n const granted = await this.createGrantStore().isGranted(params.caller, action.id);\n return {\n ...action,\n grantState: resolveServiceActionGrantState({\n actionId: action.id,\n declaredActions: params.declaredActions,\n granted,\n }),\n };\n };\n\n private requireServiceAction = async (actionId: string): Promise<ServiceAction> => {\n const { manifest, record } = await this.requireServiceAppForAction(actionId);\n const action = this.listManifestActions(record, manifest)\n .find((entry) => entry.id === actionId);\n if (!action) {\n throw new ServiceAppError(\"SERVICE_APP_ACTION_NOT_FOUND\", \"service action not found\");\n }\n return action;\n };\n\n private requireServiceAppForAction = async (\n actionId: string,\n ): Promise<{ manifest: ServiceAppManifest; record: ServiceAppRecord }> => {\n const appId = actionId.split(\".\")[0]?.trim();\n if (!appId) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_ACTION\", \"service action id is invalid\");\n }\n return await this.requireServiceApp(appId);\n };\n\n private listManifestActions = (\n record: ServiceAppRecord,\n manifest: ServiceAppManifest,\n ): ServiceAction[] => listServiceAppManifestActions(record, manifest);\n\n private requireServiceApp = async (\n appId: string,\n ): Promise<{ manifest: ServiceAppManifest; record: ServiceAppRecord }> => {\n const serviceAppsPath = this.getServiceAppsPath(this.getWorkspacePath());\n const dirPath = join(serviceAppsPath, appId);\n try {\n const dirStat = await stat(dirPath);\n if (!dirStat.isDirectory()) {\n throw new ServiceAppError(\"SERVICE_APP_NOT_FOUND\", \"service app not found\");\n }\n const manifest = await readServiceAppManifest(dirPath);\n if (manifest.id !== appId) {\n throw new ServiceAppError(\n \"SERVICE_APP_INVALID_MANIFEST\",\n \"service app manifest id must match directory name\",\n );\n }\n return {\n manifest,\n record: this.toServiceAppRecord(dirPath, manifest),\n };\n } catch (error) {\n if (isServiceAppError(error)) {\n throw error;\n }\n if (this.isMissingFileError(error)) {\n throw new ServiceAppError(\"SERVICE_APP_NOT_FOUND\", \"service app not found\");\n }\n throw new ServiceAppError(\n \"SERVICE_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n private listValidServiceApps = async (): Promise<Array<{\n manifest: ServiceAppManifest;\n record: ServiceAppRecord;\n }>> => {\n const workspacePath = this.getWorkspacePath();\n const serviceAppsPath = this.getServiceAppsPath(workspacePath);\n const dirNames = await this.listServiceAppDirNames(serviceAppsPath);\n const entries = await Promise.all(\n dirNames.map(async (dirName) => {\n const dirPath = join(serviceAppsPath, dirName);\n try {\n const manifest = await readServiceAppManifest(dirPath);\n return {\n manifest,\n record: this.toServiceAppRecord(dirPath, manifest),\n };\n } catch {\n return null;\n }\n }),\n );\n return entries.filter((entry): entry is NonNullable<typeof entry> => Boolean(entry));\n };\n\n private buildServiceAppRecord = async (\n serviceAppsPath: string,\n dirName: string,\n ): Promise<ServiceAppRecord | null> => {\n const dirPath = join(serviceAppsPath, dirName);\n try {\n const manifest = await readServiceAppManifest(dirPath);\n return this.toServiceAppRecord(dirPath, manifest);\n } catch (error) {\n if (this.isMissingFileError(error)) {\n return null;\n }\n return {\n id: dirName,\n title: toTitle(dirName),\n dirPath,\n manifestPath: getServiceAppManifestPath(dirPath),\n cwd: dirPath,\n enabled: false,\n protocol: \"mcp\",\n status: \"failed\",\n lastError: error instanceof Error ? error.message : String(error),\n };\n }\n };\n\n private toServiceAppRecord = (\n dirPath: string,\n manifest: ServiceAppManifest,\n ): ServiceAppRecord => {\n const runtimeStatus = this.runtimeService.getStatus(manifest.id);\n const record: ServiceAppRecord = {\n id: manifest.id,\n title: manifest.title,\n dirPath,\n manifestPath: getServiceAppManifestPath(dirPath),\n command: manifest.command,\n args: manifest.args,\n cwd: dirPath,\n enabled: manifest.enabled,\n protocol: manifest.protocol,\n status: manifest.enabled ? runtimeStatus.status : \"stopped\",\n };\n if (manifest.description) {\n record.description = manifest.description;\n }\n if (runtimeStatus.lastError) {\n record.lastError = runtimeStatus.lastError;\n }\n if (runtimeStatus.lastStartedAt) {\n record.lastStartedAt = runtimeStatus.lastStartedAt;\n }\n if (runtimeStatus.lastReadyAt) {\n record.lastReadyAt = runtimeStatus.lastReadyAt;\n }\n if (runtimeStatus.lastFailedAt) {\n record.lastFailedAt = runtimeStatus.lastFailedAt;\n }\n return record;\n };\n\n private assertCaller = (caller: ServiceActionCaller): void => {\n if (caller.surface !== \"panel-app\" || !caller.appId.trim()) {\n throw new ServiceAppError(\"SERVICE_APP_INVALID_CALLER\", \"service action caller is invalid\");\n }\n };\n\n private assertDeclaredAction = (\n actionId: string,\n declaredActions: readonly string[],\n ): void => {\n if (!declaredActions.includes(actionId)) {\n throw new ServiceAppError(\n \"SERVICE_APP_ACTION_NOT_DECLARED\",\n \"panel app did not declare this service action\",\n );\n }\n };\n\n private normalizeActionIds = (actionIds: readonly string[]): string[] =>\n Array.from(new Set(\n actionIds\n .map((actionId) => actionId.trim())\n .filter((actionId) => actionId.length > 0),\n ));\n\n private getWorkspacePath = (): string =>\n getWorkspacePathFromConfig(this.params.configManager.config);\n\n private getServiceAppsPath = (workspacePath: string): string =>\n join(workspacePath, DEFAULT_SERVICE_APPS_DIR);\n\n private createGrantStore = (): ServiceActionGrantStore =>\n new ServiceActionGrantStore(\n join(this.getServiceAppsPath(this.getWorkspacePath()), SERVICE_ACTION_GRANTS_FILE_NAME),\n );\n\n private listServiceAppDirNames = async (\n serviceAppsPath: string,\n ): Promise<string[]> => {\n try {\n const entries = await readdir(serviceAppsPath, { withFileTypes: true });\n return entries\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith(\".\"))\n .map((entry) => entry.name);\n } catch (error) {\n if (this.isMissingFileError(error)) {\n return [];\n }\n throw new ServiceAppError(\n \"SERVICE_APP_READ_FAILED\",\n error instanceof Error ? error.message : String(error),\n );\n }\n };\n\n private isMissingFileError = (error: unknown): boolean =>\n Boolean(error) &&\n typeof error === \"object\" &&\n (error as { code?: unknown }).code === \"ENOENT\";\n}\n\ntype ServiceAppRuntime = Pick<\n McpServiceAppRuntimeService,\n \"dispose\" | \"getStatus\" | \"invokeAction\" | \"listActions\" | \"restart\"\n>;\n\nfunction toTitle(value: string): string {\n return basename(value).replace(/[-_]+/g, \" \").trim() || value;\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 { SessionManager } from \"@kernel/managers/session.manager.js\";\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\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 readonly statusListeners = new Set<(status: \"idle\" | \"running\") => void>();\n private activeRunId: string | null = null;\n private activeRunController: AbortController | null = null;\n\n constructor(\n seed: {\n sessionId: string;\n messages: readonly NcpMessage[];\n },\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 = (): { messages: readonly NcpMessage[] } => {\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 onStatusChange = (\n listener: (status: \"idle\" | \"running\") => void,\n ): (() => void) => {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n };\n\n beginRun = (): { runId: string; signal: AbortSignal } => {\n if (this.activeRunId) {\n throw new Error(`Session ${this.sessionId} already has an active run.`);\n }\n const wasRunning = this.isRunning();\n const runId = `agent-run-${randomUUID()}`;\n const controller = new AbortController();\n this.activeRunId = runId;\n this.activeRunController = controller;\n this.emitStatusChangeIfNeeded(wasRunning);\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 const wasRunning = this.isRunning();\n this.activeRunController.abort();\n this.activeRunController = null;\n this.activeRunId = null;\n this.emitStatusChangeIfNeeded(wasRunning);\n return true;\n };\n\n isRunning = (): boolean => this.activeRunId !== null;\n\n dispose = (): void => {\n const wasRunning = this.isRunning();\n this.activeRunController?.abort();\n this.activeRunController = null;\n this.activeRunId = null;\n this.emitStatusChangeIfNeeded(wasRunning);\n this.statusListeners.clear();\n };\n\n private applyRunEvents = (events: readonly NcpEndpointEvent[]): void => {\n const wasRunning = this.isRunning();\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.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 this.emitStatusChangeIfNeeded(wasRunning);\n };\n\n private emitStatusChangeIfNeeded = (\n wasRunning: boolean,\n ): void => {\n const running = this.isRunning();\n if (running === wasRunning) {\n return;\n }\n for (const listener of [...this.statusListeners]) {\n listener(running ? \"running\" : \"idle\");\n }\n };\n}\n\nexport class SessionRunManager {\n private readonly runs = new Map<string, SessionRun>();\n\n constructor(private readonly sessionManager: SessionManager) {}\n\n getSessionRun = (sessionId: string): SessionRun | null =>\n this.runs.get(sessionId) ?? null;\n\n isSessionRunning = (sessionId: string): boolean => this.runs.get(sessionId.trim())?.isRunning() ?? false;\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.sessionManager.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 { 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 type { NcpTool } from \"@nextclaw/ncp\";\nimport type {\n Config,\n SearchConfig,\n} from \"@nextclaw/core\";\nimport type {\n AgentRunRequest,\n ToolProvider,\n} from \"@kernel/types/agent-run.types.js\";\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 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 const seen = new Set<string>();\n for (const provider of [...this.providers]) {\n for (const tool of await provider.provide(request)) {\n if (seen.has(tool.name)) {\n continue;\n }\n seen.add(tool.name);\n tools.push(tool);\n }\n }\n return tools;\n };\n\n dispose = (): void => {\n this.providers.clear();\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 { 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 { SessionManager } from \"@kernel/managers/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 sessionManager: SessionManager;\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.sessionManager.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.sessionManager.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.sessionManager.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 { 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 {\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 { 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 { 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-provider.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 { 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 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/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/managers/agent-runtime.manager.js\";\nimport type { AgentRunSession } from \"@kernel/types/session.types.js\";\nimport type { AgentRunSpec } from \"@kernel/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 { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { DEFAULT_AGENT_RUNTIME_ENTRY_ID } from \"@kernel/configs/agent-runtime.config.js\";\nimport { BuiltinNarpRuntimeProviderService } 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 { AgentRunMessageProjector } from \"@kernel/services/agent-run-message-projector.service.js\";\nimport { AgentRunModelInputBudgeter } from \"@kernel/services/agent-run-model-input-budgeter.service.js\";\nimport { AgentRunModelInputBuilder } from \"@kernel/services/agent-run-model-input-builder.service.js\";\nimport { NcpAgentRuntimeWrapper } from \"@kernel/services/ncp-agent-runtime-wrapper.service.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(private readonly kernel: NextclawKernel) {\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.kernel.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.kernel.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.kernel.sessionManager.getAgentRunSession(sessionRun.sessionId);\n return await this.kernel.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.kernel.agentRuntimeManager.register({\n kind: provider.kind,\n label: provider.label,\n defaultReuseScope: \"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 { AgentRunSession } from \"@kernel/types/session.types.js\";\nimport type { AgentRunRequest } from \"@kernel/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 type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type {\n AgentRunRequest,\n ContextBlock,\n ContextProvider,\n} from \"@kernel/types/agent-run.types.js\";\nimport { buildAgentRunRequestMetadata } from \"@kernel/utils/agent-run-request-metadata.utils.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(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly ContextBlock[]> => {\n const session = request.sessionId\n ? await this.kernel.sessionManager.getAgentRunSession(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 tools = await this.kernel.toolProviderManager.buildTools(request);\n\n return [\n this.buildSystemContextBlock({\n availableTools: buildToolCatalogEntries(\n tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n })),\n ),\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 { 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(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.unregister) {\n return;\n }\n this.unregister = this.kernel.contextProviderManager.register(\n new KernelContextProvider(this.kernel),\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 {\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(private readonly kernel: NextclawKernel) {\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.kernel.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(`[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.kernel.sessionRunManager.getSessionRun(sessionId);\n if (!sessionRun) {\n return;\n }\n const session = await this.kernel.sessionManager.getAgentRunSession(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: \"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 { 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 { SessionManager } from \"@kernel/managers/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 SessionManager,\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.sessionManager;\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 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\ntype SessionActivityPreviewEventOptions = {\n readToolName?: (sessionId: string, toolCallId: string) => string | null;\n};\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\nfunction readToolCallId(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 formatToolDoneStatus(toolName: string | null): string {\n return toolName ? `工具调用完成:${toolName}` : \"工具调用完成\";\n}\n\nexport function createSessionActivityPreviewFromNcpEvent(\n event: NcpEndpointEvent,\n timestamp: string,\n options: SessionActivityPreviewEventOptions = {},\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 const sessionId = readSessionId(event.payload.sessionId);\n const toolCallId = readToolCallId(event.payload.toolCallId);\n return createProjection(sessionId, {\n state: \"running\",\n statusText: formatToolDoneStatus(\n sessionId && toolCallId ? options.readToolName?.(sessionId, toolCallId) ?? null : null,\n ),\n timestamp,\n });\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 { NcpEventType, type NcpEndpointEvent } from \"@nextclaw/ncp\";\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 private readonly toolNames = new Map<string, string>();\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 this.rememberToolName(event);\n const projection = createSessionActivityPreviewFromNcpEvent(event, new Date().toISOString(), {\n readToolName: this.readToolName,\n });\n this.clearFinishedRunToolNames(event);\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 this.toolNames.clear();\n };\n\n private rememberToolName = (event: NcpEndpointEvent): void => {\n if (event.type !== NcpEventType.MessageToolCallStart) {\n return;\n }\n const sessionId = event.payload.sessionId.trim();\n const toolCallId = event.payload.toolCallId.trim();\n const toolName = event.payload.toolName.trim();\n if (!sessionId || !toolCallId || !toolName) {\n return;\n }\n this.toolNames.set(this.createToolNameKey(sessionId, toolCallId), toolName);\n };\n\n private readToolName = (sessionId: string, toolCallId: string): string | null =>\n this.toolNames.get(this.createToolNameKey(sessionId, toolCallId)) ?? null;\n\n private clearFinishedRunToolNames = (event: NcpEndpointEvent): void => {\n if (event.type !== NcpEventType.RunFinished && event.type !== NcpEventType.RunError) {\n return;\n }\n const sessionId = this.readNonEmptyString(event.payload.sessionId);\n if (!sessionId) {\n return;\n }\n for (const key of this.toolNames.keys()) {\n if (key.startsWith(`${sessionId}:`)) {\n this.toolNames.delete(key);\n }\n }\n };\n\n private readNonEmptyString = (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\n private createToolNameKey = (sessionId: string, toolCallId: string): string => `${sessionId}:${toolCallId}`;\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.sessionManager.getSessionRecord(projection.sessionId);\n const nextMetadata = writeSessionActivityPreviewMetadata(session?.metadata, projection);\n if (!nextMetadata) {\n return;\n }\n await this.kernel.sessionManager.updateSessionMetadata(projection.sessionId, nextMetadata);\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport { createAssetTools } from \"@kernel/features/native-runtime/index.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class AssetToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (_request: AgentRunRequest): Promise<readonly NcpTool[]> =>\n createAssetTools({ assetStore: this.kernel.assetStore });\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest } from \"@kernel/types/agent-run.types.js\";\nimport { buildAgentRunRequestMetadata } from \"@kernel/utils/agent-run-request-metadata.utils.js\";\nimport { resolveNextclawNcpRunContext } from \"@kernel/features/native-runtime/index.js\";\n\nexport type ToolProviderResolvedRunContext = Awaited<\n ReturnType<typeof resolveToolProviderRunContext>\n>;\n\nexport async function resolveToolProviderRunContext(params: {\n kernel: NextclawKernel;\n request: AgentRunRequest;\n}) {\n const { kernel, request } = params;\n const session = request.sessionId\n ? await kernel.sessionManager.getAgentRunSession(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: kernel.configManager,\n sessionId,\n requestMetadata,\n sessionMetadata: session?.metadata ?? requestMetadata,\n storedAgentId: request.agentId ?? session?.agentId,\n });\n return {\n requestMetadata,\n runContext,\n session,\n sessionId,\n toolRunContext: runContext.toolRunContext,\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport {\n EditFileTool,\n ExecTool,\n GatewayTool,\n ListDirTool,\n MemoryGetTool,\n MemorySearchTool,\n ReadFileTool,\n WebFetchTool,\n WebSearchTool,\n WriteFileTool,\n} from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class CoreToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n const {\n channel,\n chatId,\n execTimeoutSeconds,\n restrictToWorkspace,\n searchConfig,\n sessionId,\n workspace,\n } = toolRunContext;\n const allowedDir = restrictToWorkspace ? workspace : undefined;\n const execTool = new ExecTool({\n restrictToWorkspace,\n timeout: execTimeoutSeconds,\n workingDir: workspace,\n });\n execTool.setContext({ channel, chatId, sessionKey: sessionId });\n const gatewayTool = new GatewayTool(this.kernel.getGatewayController());\n gatewayTool.setContext({ sessionKey: sessionId });\n return [\n new ReadFileTool(allowedDir),\n new WriteFileTool(allowedDir),\n new EditFileTool(allowedDir),\n new ListDirTool(allowedDir),\n execTool,\n new WebSearchTool(searchConfig),\n new WebFetchTool(),\n new MemorySearchTool(workspace),\n new MemoryGetTool(workspace),\n gatewayTool,\n ];\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class McpToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n return this.kernel.mcpManager.listToolsForRun({ agentId: toolRunContext.agentId });\n };\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport { normalizeString } from \"@kernel/utils/ncp-message-bridge.utils.js\";\nimport { CronTool, MessageTool } from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\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 MessagingToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n const { channel, chatId, metadata } = toolRunContext;\n const accountId = readMetadataAccountId(metadata);\n const messageTool = new MessageTool(\n async (message) => {\n const delivered = await this.kernel.channels.deliver(message);\n if (!delivered) {\n throw new Error(`channel \"${message.channel}\" is not available`);\n }\n },\n { resolveChannels: this.resolveMessageChannels },\n );\n messageTool.setContext(channel, chatId, accountId ?? null);\n const cronTool = new CronTool(this.kernel.automation);\n return [messageTool, 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","import { normalizeToolParams } from \"@nextclaw/core\";\nimport type { NcpMessage, NcpSessionSummary, NcpTool } from \"@nextclaw/ncp\";\nimport type { SessionManager } from \"@kernel/managers/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 implements NcpTool {\n readonly name = \"sessions_list\";\n readonly description = \"List available sessions with timestamps.\";\n readonly parameters = {\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 constructor(private readonly sessions: SessionManager) {}\n\n execute = async (args: unknown): Promise<string> => {\n const params = normalizeToolParams(args);\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 implements NcpTool {\n readonly name = \"sessions_history\";\n readonly description = \"Fetch recent messages from a session\";\n readonly parameters = {\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 constructor(private readonly sessions: SessionManager) {}\n\n execute = async (args: unknown): Promise<string> => {\n const params = normalizeToolParams(args);\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 {\n normalizeToolParams,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\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 implements NcpTool {\n readonly name = \"sessions_request\";\n readonly description =\n \"Send one task to another session. Use notify to control whether this session should continue after the target session finishes.\";\n readonly parameters = {\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 private sourceSessionId = \"\";\n private handoffDepth = 0;\n\n constructor(private readonly manager: SessionRequestManager) {}\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 (args: unknown, context?: ToolExecutionContext): Promise<unknown> => {\n const params = normalizeToolParams(args);\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\n return this.manager.requestSession({\n sourceSessionId: this.sourceSessionId,\n sourceToolCallId: context?.toolCallId,\n updateToolCallResult: context?.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 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 normalizeToolParams,\n type SessionRequestNotifyMode,\n type ToolExecutionContext,\n} from \"@nextclaw/core\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\nimport type { SessionManager } from \"@kernel/managers/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 implements NcpTool {\n readonly name = \"sessions_spawn\";\n readonly description =\n \"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 readonly parameters = {\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 private sourceSessionId = \"\";\n private sourceSessionMetadata: Record<string, unknown> = {};\n private handoffDepth = 0;\n\n constructor(\n private readonly sessionManager: SessionManager,\n private readonly sessionRequestManager: SessionRequestManager,\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 (args: unknown, context?: ToolExecutionContext): Promise<unknown> => {\n const params = normalizeToolParams(args);\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\n if (notify) {\n return this.sessionRequestManager.spawnSessionAndRequest({\n sourceSessionId: this.sourceSessionId,\n sourceToolCallId: context?.toolCallId,\n updateToolCallResult: context?.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,\n notify,\n });\n }\n\n const session = await this.sessionManager.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,\n });\n\n return {\n kind: \"nextclaw.session\",\n sessionId: session.sessionId,\n agentId: session.agentId,\n 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 { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport { resolveToolProviderRunContext } from \"@kernel/contributions/tool-provider/utils/tool-provider-run-context.utils.js\";\nimport { SessionsHistoryTool, SessionsListTool } from \"@kernel/tools/session-history.tools.js\";\nimport { SessionRequestTool } from \"@kernel/tools/session-request.tools.js\";\nimport { SessionSearchTool } from \"@kernel/tools/session-search.tools.js\";\nimport { SessionSpawnTool } from \"@kernel/tools/session-spawn.tools.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\nexport class SessionToolProvider implements ToolProvider {\n constructor(private readonly kernel: NextclawKernel) {}\n\n provide = async (request: AgentRunRequest): Promise<readonly NcpTool[]> => {\n const { toolRunContext } = await resolveToolProviderRunContext({\n kernel: this.kernel,\n request,\n });\n const { handoffDepth, metadata, sessionId } = toolRunContext;\n const sessionsSpawnTool = new SessionSpawnTool(\n this.kernel.sessionManager,\n this.kernel.sessionRequests,\n );\n sessionsSpawnTool.setContext({\n sourceSessionId: sessionId,\n sourceSessionMetadata: metadata,\n handoffDepth,\n });\n\n const sessionsRequestTool = new SessionRequestTool(this.kernel.sessionRequests);\n sessionsRequestTool.setContext({\n sourceSessionId: sessionId,\n handoffDepth,\n });\n const tools: NcpTool[] = [\n sessionsSpawnTool,\n sessionsRequestTool,\n new SessionsListTool(this.kernel.sessionManager),\n new SessionsHistoryTool(this.kernel.sessionManager),\n ];\n if (!this.kernel.sessionSearch.isReady()) {\n return tools;\n }\n tools.push(\n new SessionSearchTool(\n { search: this.kernel.sessionSearch.search },\n { currentSessionId: sessionId },\n ),\n );\n return tools;\n };\n}\n","import type { AgentRunRequest, ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport {\n STRUCTURED_RESULT_TOOL_NAME,\n StructuredResultSubmitTool,\n type StructuredResultContract,\n} from \"@kernel/tools/structured-result.tools.js\";\nimport type { NcpTool } from \"@nextclaw/ncp\";\n\ntype StructuredResultMetadata = {\n request_id?: unknown;\n schema?: unknown;\n tool_name?: unknown;\n};\n\nexport class StructuredResultToolProvider implements ToolProvider {\n provide = (request: AgentRunRequest): readonly NcpTool[] => {\n const contract = readStructuredResultContract(request.message.metadata);\n return contract ? [new StructuredResultSubmitTool(contract)] : [];\n };\n}\n\nfunction readStructuredResultContract(\n metadata: Record<string, unknown> | undefined,\n): StructuredResultContract | null {\n const value = metadata?.structured_result;\n if (!isRecord(value)) {\n return null;\n }\n const candidate = value as StructuredResultMetadata;\n if (\n candidate.tool_name !== STRUCTURED_RESULT_TOOL_NAME ||\n typeof candidate.request_id !== \"string\" ||\n !isRecord(candidate.schema)\n ) {\n return null;\n }\n return {\n requestId: candidate.request_id,\n schema: candidate.schema,\n toolName: STRUCTURED_RESULT_TOOL_NAME,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n","import type { NextclawKernel } from \"@kernel/app/nextclaw-kernel.js\";\nimport type { ToolProvider } from \"@kernel/types/agent-run.types.js\";\nimport type { KernelContribution } from \"@kernel/types/kernel-contribution.types.js\";\nimport { AssetToolProvider } from \"./providers/asset-tool.provider.js\";\nimport { CoreToolProvider } from \"./providers/core-tool.provider.js\";\nimport { McpToolProvider } from \"./providers/mcp-tool.provider.js\";\nimport { MessagingToolProvider } from \"./providers/messaging-tool.provider.js\";\nimport { SessionToolProvider } from \"./providers/session-tool.provider.js\";\nimport { StructuredResultToolProvider } from \"./providers/structured-result-tool.provider.js\";\n\nexport class ToolProviderContribution implements KernelContribution {\n private readonly cleanups: Array<() => void> = [];\n\n constructor(private readonly kernel: NextclawKernel) {}\n\n start = (): void => {\n if (this.cleanups.length > 0) {\n return;\n }\n\n for (const provider of this.createToolProviders()) {\n this.cleanups.push(this.kernel.toolProviderManager.register(provider));\n }\n };\n\n dispose = (): void => {\n while (this.cleanups.length > 0) {\n this.cleanups.pop()?.();\n }\n };\n\n private createToolProviders = (): ToolProvider[] => [\n new StructuredResultToolProvider(),\n new CoreToolProvider(this.kernel),\n new MessagingToolProvider(this.kernel),\n new SessionToolProvider(this.kernel),\n new AssetToolProvider(this.kernel),\n new McpToolProvider(this.kernel),\n ];\n}\n","import { AgentManager } from \"@kernel/managers/agent.manager.js\";\nimport { AgentRunContextCompactionManager } from \"@kernel/managers/agent-run-context-compaction.manager.js\";\nimport { AgentRunRequestManager } from \"@kernel/managers/agent-run-request.manager.js\";\nimport { AgentRuntimeManager } from \"@kernel/managers/agent-runtime.manager.js\";\nimport { AccessManager } from \"@kernel/managers/access.manager.js\";\nimport { AutomationManager } from \"@kernel/managers/automation.manager.js\";\nimport { ConfigManager } from \"@kernel/managers/config.manager.js\";\nimport { ContextProviderManager } from \"@kernel/managers/context-provider.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 { SessionManager } from \"@kernel/managers/session.manager.js\";\nimport { PanelAppManager } from \"@kernel/managers/panel-app.manager.js\";\nimport { ServiceAppManager } from \"@kernel/managers/service-app.manager.js\";\nimport { SessionRunManager } from \"@kernel/managers/session-run.manager.js\";\nimport { SkillManager } from \"@kernel/managers/skill.manager.js\";\nimport { ToolProviderManager } from \"@kernel/managers/tool-provider.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 { AgentRunRuntimeContribution } from \"@kernel/contributions/agent-run-runtime/index.js\";\nimport { ContextProviderContribution } from \"@kernel/contributions/context-provider/index.js\";\nimport { ContextWindowContribution } from \"@kernel/contributions/context-window/index.js\";\nimport { LearningLoopContribution } from \"@kernel/contributions/learning-loop/index.js\";\nimport { SessionActivityPreviewContribution } from \"@kernel/contributions/session-activity-preview/index.js\";\nimport { ToolProviderContribution } from \"@kernel/contributions/tool-provider/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 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(\n options: NextclawKernelOptions,\n): 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<TGatewayInput, TUiInput, TStartInput> = {\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<TGatewayInput, TUiInput, TStartInput> {\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 accessManager: AccessManager;\n readonly agents: AgentManager;\n readonly control: NextclawKernelControlManager<unknown, unknown, unknown>;\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 sessionManager: SessionManager;\n readonly panelAppManager: PanelAppManager;\n readonly serviceAppManager: ServiceAppManager;\n readonly extensions: ExtensionManager;\n readonly agentRuntimeManager = new AgentRuntimeManager();\n readonly contextCompactionManager: AgentRunContextCompactionManager;\n readonly contextProviderManager = new ContextProviderManager();\n readonly sessionRunManager: SessionRunManager;\n readonly toolProviderManager = new ToolProviderManager();\n readonly agentRunRequestManager: AgentRunRequestManager;\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.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.channels = new ChannelManager({\n bus: this.messageBus,\n });\n this.configManager = new ConfigManager({\n configPath: options.configPath,\n channels: this.channels,\n providerManager: this.llmProviders,\n });\n this.accessManager = new AccessManager({\n configManager: this.configManager,\n homeDir: options.homeDir,\n });\n this.sessionManager = new SessionManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n journalStore: this.ncpAgentSessionJournalStore,\n sessionSearch: this.sessionSearch,\n });\n this.panelAppManager = new PanelAppManager({\n configManager: this.configManager,\n eventBus: this.eventBus,\n ingress: this.ingress,\n });\n this.serviceAppManager = new ServiceAppManager({\n configManager: this.configManager,\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.sessionManager,\n });\n this.skills = new SkillManager({\n workspace: getWorkspacePath(\n this.configManager.config.agents.defaults.workspace,\n ),\n });\n this.mcpManager = new McpManager(this.configManager.loadConfig);\n this.configManager.installRuntimeHooks({\n resolveChannelConfig: this.extensions.toConfigView,\n getExtensionChannels: () =>\n this.extensions.getExtensionRegistry().channels,\n reloadMcp: async ({ config }) =>\n await this.mcpManager.applyConfig(config),\n });\n this.sessionRequests = new SessionRequestManager({\n sessionManager: this.sessionManager,\n dispatcher: createAgentRuntimeSessionRequestDispatcher({\n eventBus: this.eventBus,\n ingress: this.ingress,\n }),\n });\n this.contextCompactionManager = new AgentRunContextCompactionManager(\n this.configManager,\n this.llmProviders,\n this.sessionManager,\n );\n this.sessionRunManager = new SessionRunManager(this.sessionManager);\n this.agentRunRequestManager = new AgentRunRequestManager(\n this.agentRuntimeManager,\n this.configManager,\n this.contextProviderManager,\n this.eventBus,\n this.ingress,\n this.sessionManager,\n this.sessionRunManager,\n this.toolProviderManager,\n );\n this.contributions = [\n new ToolProviderContribution(this),\n new SessionActivityPreviewContribution(this),\n new LearningLoopContribution(this),\n new ContextProviderContribution(this),\n new AgentRunRuntimeContribution(this),\n new ContextWindowContribution(this),\n ];\n }\n\n listSessionTypes = (params?: AgentRuntimeSessionTypeDescribeParams) =>\n this.agentRuntimeManager.listSessionTypes(params);\n\n isSessionRunning = (sessionId: string): boolean =>\n this.sessionRunManager.isSessionRunning(sessionId);\n\n provideGatewayController = (gatewayController: GatewayController): void => {\n this.gatewayController = gatewayController;\n };\n\n getGatewayController = (): GatewayController | undefined =>\n this.gatewayController;\n\n start = async (): Promise<void> => {\n void this.sessionSearch.start();\n this.mcpManager.start();\n this.sessionManager.start();\n for (const contribution of this.contributions) {\n contribution.start();\n }\n this.agentRunRequestManager.start();\n };\n\n dispose = async (): Promise<void> => {\n this.agentRunRequestManager.dispose();\n for (const contribution of [...this.contributions].reverse()) {\n await contribution.dispose();\n }\n this.toolProviderManager.dispose();\n this.contextProviderManager.dispose();\n await this.agentRuntimeManager.dispose();\n this.sessionRunManager.dispose();\n this.sessionManager.dispose();\n await this.mcpManager.dispose();\n await this.serviceAppManager.dispose();\n await this.sessionSearch.dispose();\n };\n}\n","import type { InboundAttachment } from \"@nextclaw/core\";\nimport type { NcpMessagePart } from \"@nextclaw/ncp\";\nimport type { AgentRunSendIngressPayload } from \"@nextclaw/shared\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\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\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","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 type { AgentRunClient } from \"@kernel/services/agent-run-client.service.js\";\nimport {\n buildAgentRunSendPayload,\n type AssetApi,\n} from \"@kernel/utils/agent-run-send-payload.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 createAssistantStreamDeltaControlMessage,\n createAssistantStreamResetControlMessage,\n createTypingStopControlMessage,\n type ChannelManager,\n type Config,\n type InboundMessage,\n type MessageBus,\n} from \"@nextclaw/core\";\nimport { CommandRegistry } from \"@kernel/services/command-registry.service.js\";\nimport type { SessionManager } from \"@kernel/managers/session.manager.js\";\nimport { eventKeys, type EventBus } from \"@nextclaw/shared\";\nimport {\n dispatchChannelReplyRoute,\n resolveChannelReplyRoute,\n} from \"@kernel/features/ncp-dispatch/utils/channel-reply.utils.js\";\nimport {\n buildRunMetadata,\n} from \"@kernel/utils/agent-run-metadata.utils.js\";\nimport {\n buildAgentRunSendPayload,\n type AssetApi,\n} from \"@kernel/utils/agent-run-send-payload.utils.js\";\nimport type {\n AgentRunClient,\n AgentRunReply,\n} from \"@kernel/services/agent-run-client.service.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 =\n error instanceof Error\n ? error.message || error.name\n : 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 (\n await this.dispatchChannelReplyRouteMaybe(message, route, runMetadata)\n ) {\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(\n 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 {\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 );\n await this.publishChannelReply(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(\n this.runtime.configManager.loadConfig(),\n ).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 publishChannelReply = async (\n message: InboundMessage,\n route: GatewayRoute,\n result: AgentRunReply,\n ): Promise<void> => {\n if (message.channel === \"system\") {\n this.runtime.appEventBus?.emit(\n eventKeys.sessionUpdated,\n { sessionKey: route.sessionKey },\n {\n emittedAt: new Date().toISOString(),\n source: \"backend\",\n },\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 parseAgentScopedSessionKey,\n type Config,\n type InboundAttachment,\n type InboundMessage,\n} from \"@nextclaw/core\";\nimport { CommandRegistry } from \"@kernel/services/command-registry.service.js\";\nimport type { AgentRunClient } from \"@kernel/services/agent-run-client.service.js\";\nimport { buildRunMetadata } from \"@kernel/utils/agent-run-metadata.utils.js\";\nimport { buildAgentRunSendPayload } from \"@kernel/utils/agent-run-send-payload.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":"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"}
|