@hermespilot/link 0.2.1 → 0.2.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/http/app.ts","../src/conversations/conversation-service.ts","../src/database/link-database.ts","../src/hermes/cron-link-delivery.ts","../src/storage/atomic-json.ts","../src/hermes/config.ts","../src/core/errors.ts","../src/conversations/statistics.ts","../src/conversations/blob-store.ts","../src/conversations/media.ts","../src/conversations/delivery-contract.ts","../src/conversations/profile-runtime.ts","../src/conversations/conversation-view.ts","../src/hermes/gateway.ts","../src/runtime/logger.ts","../src/runtime/paths.ts","../src/constants.ts","../src/hermes/cli.ts","../src/conversations/slash-commands.ts","../src/conversations/conversation-commands.ts","../src/conversations/conversation-maintenance.ts","../src/config/config.ts","../src/hermes/session-title.ts","../src/conversations/conversation-metadata.ts","../src/conversations/conversation-turns.ts","../src/conversations/conversation-orchestration.ts","../src/conversations/agent-events.ts","../src/conversations/conversation-queries.ts","../src/conversations/conversation-store.ts","../src/conversations/run-lifecycle.ts","../src/hermes/api-server.ts","../src/conversations/history-builder.ts","../src/hermes/stt.ts","../src/conversations/hermes-sse.ts","../src/conversations/stream-events.ts","../src/identity/identity.ts","../src/security/devices.ts","../src/security/app-connect-token.ts","../src/http/auth.ts","../src/http/request.ts","../src/http/sse.ts","../src/http/routes/conversations.ts","../src/http/middleware/error-handler.ts","../src/hermes/profiles.ts","../src/http/routes/cron-jobs.ts","../src/http/routes/gateway-reload.ts","../src/http/routes/model-configs.ts","../src/http/routes/profile-catalog.ts","../src/hermes/profile-creation.ts","../src/http/routes/profile-configs.ts","../src/hermes/memory.ts","../src/http/routes/profile-memory.ts","../src/hermes/skills.ts","../src/http/routes/profile-skills.ts","../src/http/routes/profiles.ts","../src/http/routes/runs.ts","../src/http/routes/statistics.ts","../src/hermes/updates.ts","../src/link/updates.ts","../src/daemon/process.ts","../src/daemon/service.ts","../src/relay/control-client.ts","../src/daemon/scheduler.ts","../src/pairing/pairing.ts","../src/relay/bootstrap.ts","../src/topology/network.ts","../src/http/routes/system.ts","../src/http/routes/hermes-updates.ts","../src/http/routes/link-updates.ts","../src/http/routes/pairing.ts"],"sourcesContent":["import Koa from 'koa'\nimport Router from '@koa/router'\nimport { ConversationService } from '../conversations/conversation-service.js'\nimport { syncHermesLinkCronDeliveries } from '../hermes/cron-link-delivery.js'\nimport { createFileLogger, type FileLogger } from '../runtime/logger.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport { registerConversationRoutes } from './routes/conversations.js'\nimport { createHttpErrorMiddleware } from './middleware/error-handler.js'\nimport { registerCronJobRoutes } from './routes/cron-jobs.js'\nimport { registerModelConfigRoutes } from './routes/model-configs.js'\nimport { registerProfileCatalogRoutes } from './routes/profile-catalog.js'\nimport { registerProfileRoutes } from './routes/profiles.js'\nimport { registerRunRoutes } from './routes/runs.js'\nimport { registerStatisticsRoutes } from './routes/statistics.js'\nimport { registerSystemRoutes } from './routes/system.js'\nimport { registerHermesUpdateRoutes } from './routes/hermes-updates.js'\nimport { registerLinkUpdateRoutes } from './routes/link-updates.js'\nimport { registerPairingRoutes } from './routes/pairing.js'\n\nexport interface CreateAppOptions {\n paths?: RuntimePaths\n logger?: FileLogger\n conversations?: ConversationService\n onPairingClaimed?: () => void | Promise<void>\n}\n\nexport async function createApp(options: CreateAppOptions = {}): Promise<Koa> {\n const paths = options.paths ?? resolveRuntimePaths()\n const logger = options.logger ?? createFileLogger({ paths })\n const conversations =\n options.conversations ?? new ConversationService(paths, logger)\n let cronDeliverySyncRunning = false\n const syncCronDeliveries = async () => {\n if (cronDeliverySyncRunning) {\n return\n }\n cronDeliverySyncRunning = true\n try {\n await syncHermesLinkCronDeliveries(paths, conversations, logger)\n } catch (error) {\n void logger.warn('cron_link_delivery_sync_failed', {\n error: error instanceof Error ? error.message : String(error),\n })\n } finally {\n cronDeliverySyncRunning = false\n }\n }\n const app = new Koa()\n const router = new Router()\n\n app.use(createHttpErrorMiddleware(logger))\n\n registerSystemRoutes(router, {\n paths,\n logger,\n onPairingClaimed: options.onPairingClaimed,\n })\n registerPairingRoutes(router, { paths })\n\n registerHermesUpdateRoutes(router, { paths, logger })\n registerLinkUpdateRoutes(router, { paths, logger })\n\n registerStatisticsRoutes(router, { paths, logger, conversations })\n registerModelConfigRoutes(router, { paths, logger })\n registerProfileCatalogRoutes(router, { paths })\n registerCronJobRoutes(router, {\n paths,\n logger,\n conversations,\n syncCronDeliveries,\n })\n\n registerConversationRoutes(router, { paths, conversations })\n\n registerRunRoutes(router, { paths, logger, conversations })\n\n registerProfileRoutes(router, { paths, logger, conversations })\n\n app.use(router.routes())\n app.use(router.allowedMethods())\n return app\n}\n","import { EventEmitter } from 'node:events'\nimport { randomUUID } from 'node:crypto'\nimport {\n deleteConversationStatsForProfile,\n readLinkStatistics,\n replaceRunUsageFactsForConversation,\n replaceConversationStatsIndex,\n type ConversationStatsIndexRecord,\n type LinkStatistics,\n type LinkStatisticsFilter,\n type RunUsageFactRecord,\n} from '../database/link-database.js'\nimport { syncHermesLinkCronDeliveries } from '../hermes/cron-link-delivery.js'\nimport { LinkHttpError } from '../core/errors.js'\nimport type { FileLogger } from '../runtime/logger.js'\nimport { type RuntimePaths } from '../runtime/paths.js'\nimport type {\n BulkDeleteConversationResult,\n CancelRunResult,\n ConversationEvent,\n ConversationEventListener,\n ConversationManifest,\n ConversationMessagesPageInfo,\n ConversationMessagesPageOptions,\n ConversationRuntimeMetadata,\n ConversationSnapshot,\n ConversationSummary,\n ConversationUsageStats,\n DeleteConversationResult,\n LinkMessage,\n SendMessageInput,\n SendMessageResult,\n} from './types.js'\nimport {\n buildConversationStats,\n buildRunUsageFacts,\n toStatsIndexRecord,\n} from './statistics.js'\nimport {\n listConversationBlobIds,\n removeConversationFiles as removeConversationFilesFromStore,\n pruneConversationBlobReference,\n} from './blob-store.js'\nimport {\n buildConversationRuntimeMetadata,\n normalizeProfileName,\n resolveConversationProfileTarget,\n} from './profile-runtime.js'\nimport {\n DEFAULT_CONVERSATION_TITLE,\n emptySnapshot,\n hasQueuedRuns,\n hasRunningRuns,\n isDefaultConversationTitle,\n} from './conversation-view.js'\nimport { ConversationCommandHandlers } from './conversation-commands.js'\nimport { ConversationMaintenanceCoordinator } from './conversation-maintenance.js'\nimport { ConversationMetadataCoordinator } from './conversation-metadata.js'\nimport { ConversationOrchestrationCoordinator } from './conversation-orchestration.js'\nimport { ConversationQueryCoordinator } from './conversation-queries.js'\nimport { ConversationStore } from './conversation-store.js'\nimport { ConversationRunLifecycle } from './run-lifecycle.js'\nimport { isValidModelId } from './slash-commands.js'\nimport { collectBlobIds } from './media.js'\n\nexport type {\n ConversationEvent,\n ConversationSummary,\n LinkMessage,\n LinkMessagePart,\n LinkRun,\n} from './types.js'\n\nconst ALL_CONVERSATION_EVENTS = 'conversation:*'\n\nexport class ConversationService {\n private readonly emitter = new EventEmitter()\n private readonly conversationLocks = new Map<string, Promise<void>>()\n private readonly activeRunControllers = new Map<\n string,\n { conversationId: string; controller: AbortController }\n >()\n private readonly store: ConversationStore\n private readonly commandHandlers: ConversationCommandHandlers\n private readonly metadata: ConversationMetadataCoordinator\n private readonly maintenance: ConversationMaintenanceCoordinator\n private readonly orchestration: ConversationOrchestrationCoordinator\n private readonly queries: ConversationQueryCoordinator\n private readonly runLifecycle: ConversationRunLifecycle\n\n constructor(\n private readonly paths: RuntimePaths,\n private readonly logger: FileLogger,\n ) {\n this.emitter.setMaxListeners(0)\n this.store = new ConversationStore(this.paths)\n this.metadata = new ConversationMetadataCoordinator({\n paths: this.paths,\n store: this.store,\n appendEvent: (conversationId, input) =>\n this.appendEvent(conversationId, input),\n })\n this.queries = new ConversationQueryCoordinator({\n paths: this.paths,\n store: this.store,\n metadata: this.metadata,\n })\n this.maintenance = new ConversationMaintenanceCoordinator({\n paths: this.paths,\n logger: this.logger,\n store: this.store,\n metadata: this.metadata,\n withConversationLock: (conversationId, task) =>\n this.withConversationLock(conversationId, task),\n appendEvent: (conversationId, input) =>\n this.appendEvent(conversationId, input),\n })\n this.commandHandlers = new ConversationCommandHandlers({\n paths: this.paths,\n logger: this.logger,\n hasActiveRuns: () => this.activeRunControllers.size > 0,\n appendEvent: (conversationId, input) =>\n this.appendEvent(conversationId, input),\n appendCommandResult: (input) =>\n this.orchestration.appendCommandResult(input),\n renameConversation: (conversationId, title, input) =>\n this.metadata.renameConversation(conversationId, title, input),\n readManifest: (conversationId) => this.store.readManifest(conversationId),\n writeManifest: (manifest) => this.store.writeManifest(manifest),\n })\n this.runLifecycle = new ConversationRunLifecycle({\n paths: this.paths,\n logger: this.logger,\n activeRunControllers: this.activeRunControllers,\n withConversationLock: (conversationId, task) =>\n this.withConversationLock(conversationId, task),\n readSnapshot: (conversationId) => this.store.readSnapshot(conversationId),\n writeSnapshot: (conversationId, snapshot) =>\n this.store.writeSnapshot(conversationId, snapshot),\n appendEvent: (conversationId, input) =>\n this.appendEvent(conversationId, input),\n persistConversationStats: (conversationId, snapshot, statsOverride) =>\n this.metadata.persistConversationStats(\n conversationId,\n snapshot,\n statsOverride,\n ),\n readActiveManifest: (conversationId) =>\n this.store.readActiveManifest(conversationId),\n isConversationActive: (conversationId) =>\n this.store.isConversationActive(conversationId),\n writeBlob: (conversationId, input) =>\n this.maintenance.writeBlob(conversationId, input),\n syncCronDeliveries: () => this.syncCronDeliveries(),\n scheduleTitleRefresh: (conversationId) =>\n this.metadata.scheduleGeneratedTitleRefresh(conversationId),\n })\n this.orchestration = new ConversationOrchestrationCoordinator({\n paths: this.paths,\n store: this.store,\n metadata: this.metadata,\n commandHandlers: this.commandHandlers,\n runLifecycle: this.runLifecycle,\n withConversationLock: (conversationId, task) =>\n this.withConversationLock(conversationId, task),\n appendEvent: (conversationId, input) =>\n this.appendEvent(conversationId, input),\n resolveMessageAttachmentParts: (conversationId, attachments) =>\n this.maintenance.resolveMessageAttachmentParts(\n conversationId,\n attachments,\n ),\n })\n }\n\n private async withConversationLock<T>(\n conversationId: string,\n task: () => Promise<T>,\n ): Promise<T> {\n const previous =\n this.conversationLocks.get(conversationId) ?? Promise.resolve()\n let release!: () => void\n const current = new Promise<void>((resolve) => {\n release = resolve\n })\n const next = previous.catch(() => undefined).then(() => current)\n this.conversationLocks.set(conversationId, next)\n await previous.catch(() => undefined)\n try {\n return await task()\n } finally {\n release()\n if (this.conversationLocks.get(conversationId) === next) {\n this.conversationLocks.delete(conversationId)\n }\n }\n }\n\n async listConversations(): Promise<ConversationSummary[]> {\n return this.queries.listConversations()\n }\n\n async getStatistics(\n filter: LinkStatisticsFilter = {},\n ): Promise<LinkStatistics> {\n return readLinkStatistics(this.paths, filter)\n }\n\n async rebuildStatisticsIndex(): Promise<void> {\n const records: ConversationStatsIndexRecord[] = []\n const usageFacts: Array<{\n conversationId: string\n records: RunUsageFactRecord[]\n }> = []\n for (const conversationId of await this.store.listConversationIds()) {\n const manifest = await this.store.readManifest(conversationId).catch(\n () => null,\n )\n if (!manifest) {\n continue\n }\n const snapshot = await this.store.readSnapshot(conversationId).catch(() =>\n emptySnapshot(),\n )\n records.push(\n toStatsIndexRecord(\n manifest,\n buildConversationStats(manifest, snapshot),\n ),\n )\n const facts = buildRunUsageFacts(manifest, snapshot)\n if (facts.length > 0) {\n usageFacts.push({ conversationId: manifest.id, records: facts })\n }\n }\n await replaceConversationStatsIndex(this.paths, records)\n for (const facts of usageFacts) {\n await replaceRunUsageFactsForConversation(\n this.paths,\n facts.conversationId,\n facts.records,\n )\n }\n }\n\n async createConversation(\n input: { title?: string; profileName?: string } = {},\n ): Promise<ConversationSummary> {\n await this.store.ensureConversationsDir()\n const now = new Date().toISOString()\n const id = `conv_${randomUUID().replaceAll('-', '')}`\n const title = input.title?.trim() || DEFAULT_CONVERSATION_TITLE\n const profile = await resolveConversationProfileTarget(\n this.paths,\n input.profileName,\n )\n const manifest: ConversationManifest = {\n id,\n schema_version: 1,\n kind: 'direct',\n title,\n title_source: isDefaultConversationTitle(title) ? 'default' : 'hermes',\n status: 'active',\n hermes_session_id: `hp_${id}`,\n profile_uid: profile.profileUid,\n profile_name_snapshot: profile.profileName,\n profile: profile.profileName,\n created_at: now,\n updated_at: now,\n last_event_seq: 0,\n }\n await this.store.createConversation(manifest, emptySnapshot())\n const event = await this.appendEvent(manifest.id, {\n type: 'conversation.created',\n payload: {\n title,\n profile: {\n uid: profile.profileUid,\n name: profile.profileName,\n display_name: profile.profileDisplayName,\n avatar_url: profile.profileAvatarUrl,\n },\n },\n })\n await this.persistConversationStats(manifest.id, emptySnapshot())\n return {\n ...(await this.queries.summarizeConversation(\n { ...manifest, last_event_seq: event.seq },\n emptySnapshot(),\n {\n uid: profile.profileUid,\n name: profile.profileName,\n display_name: profile.profileDisplayName,\n avatar_url: profile.profileAvatarUrl,\n },\n )),\n last_event_seq: event.seq,\n }\n }\n\n async ensureCronInboxConversation(\n input: { profileName?: string } = {},\n ): Promise<string> {\n const profileName = normalizeProfileName(input.profileName)\n for (const conversationId of await this.store.listConversationIds()) {\n const manifest = await this.store.readManifest(conversationId).catch(\n () => null,\n )\n if (\n manifest?.status === 'active' &&\n manifest.title === 'HermesLink 定时任务' &&\n normalizeProfileName(\n manifest.profile_name_snapshot ?? manifest.profile,\n ) === profileName\n ) {\n return manifest.id\n }\n }\n const created = await this.createConversation({\n title: 'HermesLink 定时任务',\n profileName,\n })\n await this.store.writeManifest({\n ...(await this.store.readActiveManifest(created.id)),\n title_source: 'manual',\n })\n return created.id\n }\n\n async appendCronDelivery(input: {\n conversationId: string\n profileName: string\n jobId: string\n jobName?: string\n outputPath: string\n content: string\n runAt?: string\n }): Promise<void> {\n await this.withConversationLock(input.conversationId, async () => {\n const manifest = await this.store.readActiveManifest(input.conversationId)\n const snapshot = await this.store.readSnapshot(input.conversationId)\n if (\n snapshot.messages.some(\n (message) => message.hermes?.cron_output_path === input.outputPath,\n )\n ) {\n return\n }\n const now = new Date().toISOString()\n const createdAt = input.runAt ?? now\n const profileName = normalizeProfileName(\n manifest.profile_name_snapshot ?? manifest.profile ?? input.profileName,\n )\n const message: LinkMessage = {\n id: `msg_${randomUUID().replaceAll('-', '')}`,\n schema_version: 1,\n conversation_id: manifest.id,\n role: 'assistant',\n status: 'completed',\n created_at: createdAt,\n updated_at: now,\n sender: {\n id: 'hermes_cron',\n type: 'agent',\n display_name: 'Hermes Cron',\n profile: profileName,\n },\n parts: [{ type: 'text', text: input.content }],\n attachments: [],\n hermes: {\n cron_job_id: input.jobId,\n cron_job_name: input.jobName,\n cron_profile: input.profileName,\n cron_output_path: input.outputPath,\n },\n raw: {\n format: 'hermes-link-cron-delivery',\n payload: {\n job_id: input.jobId,\n job_name: input.jobName,\n profile: input.profileName,\n output_path: input.outputPath,\n },\n },\n }\n snapshot.messages.push(message)\n await this.store.writeSnapshot(manifest.id, snapshot)\n await this.appendEvent(manifest.id, {\n type: 'message.created',\n message_id: message.id,\n payload: { message },\n })\n await this.persistConversationStats(manifest.id, snapshot)\n })\n }\n\n async syncCronDeliveries(): Promise<void> {\n await syncHermesLinkCronDeliveries(this.paths, this, this.logger)\n }\n\n async getMessages(\n conversationId: string,\n options: ConversationMessagesPageOptions = {},\n ): Promise<{\n messages: LinkMessage[]\n last_event_seq: number\n runtime: ConversationRuntimeMetadata\n page: ConversationMessagesPageInfo\n }> {\n return this.queries.getMessages(conversationId, options)\n }\n\n async setConversationModel(\n conversationId: string,\n modelId: string,\n ): Promise<{\n conversation_id: string\n model_override: string\n runtime: ConversationRuntimeMetadata\n last_event_seq: number\n }> {\n const normalizedModelId = modelId.trim()\n if (!normalizedModelId || !isValidModelId(normalizedModelId)) {\n throw new LinkHttpError(\n 400,\n 'model_id_invalid',\n 'model_id must be a valid model id',\n )\n }\n\n return this.withConversationLock(conversationId, async () => {\n const manifest = await this.store.readActiveManifest(conversationId)\n const snapshot = await this.store.readSnapshot(conversationId)\n const nextManifest: ConversationManifest = {\n ...manifest,\n command_state: {\n ...manifest.command_state,\n model_override: normalizedModelId,\n },\n updated_at: new Date().toISOString(),\n }\n await this.store.writeManifest(nextManifest)\n\n const runtime = await buildConversationRuntimeMetadata(\n this.paths,\n nextManifest,\n snapshot,\n )\n const event = await this.appendEvent(conversationId, {\n type: 'conversation.updated',\n payload: {\n command: 'model',\n model_override: normalizedModelId,\n runtime,\n },\n })\n return {\n conversation_id: conversationId,\n model_override: normalizedModelId,\n runtime,\n last_event_seq: event.seq,\n }\n })\n }\n\n async setConversationProfile(\n conversationId: string,\n profileName: string,\n ): Promise<{\n conversation_id: string\n profile: {\n uid: string\n name: string\n display_name: string\n avatar_url: string | null\n }\n runtime: ConversationRuntimeMetadata\n conversation: ConversationSummary\n last_event_seq: number\n }> {\n return this.withConversationLock(conversationId, async () => {\n const manifest = await this.store.readActiveManifest(conversationId)\n const snapshot = await this.store.readSnapshot(conversationId)\n if (\n hasRunningRuns(snapshot) ||\n hasQueuedRuns(snapshot) ||\n this.hasActiveRunControllerForConversation(conversationId)\n ) {\n throw new LinkHttpError(\n 409,\n 'conversation_profile_switch_not_allowed',\n 'This conversation has an active or queued run. Wait for it to finish before switching profile.',\n )\n }\n\n const profile = await resolveConversationProfileTarget(\n this.paths,\n profileName,\n )\n const currentProfile = normalizeProfileName(\n manifest.profile_name_snapshot ?? manifest.profile,\n )\n if (\n currentProfile === profile.profileName &&\n (!manifest.profile_uid || manifest.profile_uid === profile.profileUid)\n ) {\n const runtime = await buildConversationRuntimeMetadata(\n this.paths,\n manifest,\n snapshot,\n )\n return {\n conversation_id: conversationId,\n profile: {\n uid: profile.profileUid,\n name: profile.profileName,\n display_name: profile.profileDisplayName,\n avatar_url: profile.profileAvatarUrl,\n },\n runtime,\n conversation: await this.queries.summarizeConversation(\n manifest,\n snapshot,\n runtime.profile,\n ),\n last_event_seq: manifest.last_event_seq,\n }\n }\n\n const commandState = manifest.command_state\n ? { ...manifest.command_state }\n : undefined\n if (commandState) {\n delete commandState.model_override\n delete commandState.reasoning\n }\n const updatedAt = new Date().toISOString()\n const nextManifest: ConversationManifest = {\n ...manifest,\n profile_uid: profile.profileUid,\n profile_name_snapshot: profile.profileName,\n profile: profile.profileName,\n command_state:\n commandState && Object.keys(commandState).length > 0\n ? commandState\n : undefined,\n updated_at: updatedAt,\n }\n await this.store.writeManifest(nextManifest)\n await this.persistConversationStats(conversationId, snapshot)\n\n const runtime = await buildConversationRuntimeMetadata(\n this.paths,\n nextManifest,\n snapshot,\n )\n const profileSummary = {\n uid: profile.profileUid,\n name: profile.profileName,\n display_name: profile.profileDisplayName,\n avatar_url: profile.profileAvatarUrl,\n }\n const event = await this.appendEvent(conversationId, {\n type: 'conversation.updated',\n payload: {\n command: 'profile',\n profile: profileSummary,\n runtime,\n conversation: await this.queries.summarizeConversation(\n {\n ...nextManifest,\n last_event_seq: manifest.last_event_seq + 1,\n updated_at: updatedAt,\n },\n snapshot,\n profileSummary,\n ),\n },\n })\n const conversation = await this.queries.summarizeConversation(\n {\n ...nextManifest,\n last_event_seq: event.seq,\n updated_at: event.created_at,\n },\n snapshot,\n profileSummary,\n )\n return {\n conversation_id: conversationId,\n profile: profileSummary,\n runtime,\n conversation,\n last_event_seq: event.seq,\n }\n })\n }\n\n async renameConversation(\n conversationId: string,\n title: string,\n ): Promise<{\n conversation_id: string\n title: string\n conversation: ConversationSummary\n hermes_synced: boolean\n last_event_seq: number\n }> {\n return this.withConversationLock(conversationId, async () => {\n const manifest = await this.store.readActiveManifest(conversationId)\n const snapshot = await this.store.readSnapshot(conversationId)\n return this.renameConversationLocked(conversationId, title, {\n manifest,\n snapshot,\n source: 'manual',\n })\n })\n }\n\n private async renameConversationLocked(\n conversationId: string,\n title: string,\n input: {\n manifest: ConversationManifest\n snapshot: ConversationSnapshot\n source: 'manual' | 'generated'\n },\n ): Promise<{\n conversation_id: string\n title: string\n conversation: ConversationSummary\n hermes_synced: boolean\n last_event_seq: number\n }> {\n const result = await this.metadata.renameConversation(\n conversationId,\n title,\n input,\n )\n return {\n conversation_id: conversationId,\n title: result.manifest.title,\n conversation: await this.queries.summarizeConversation(\n result.manifest,\n input.snapshot,\n ),\n hermes_synced: result.hermesSynced,\n last_event_seq: result.event.seq,\n }\n }\n\n async listEvents(\n conversationId: string,\n after = 0,\n ): Promise<ConversationEvent[]> {\n return this.queries.listEvents(conversationId, after)\n }\n\n subscribe(\n conversationId: string,\n listener: ConversationEventListener,\n ): () => void {\n const eventName = this.liveEventName(conversationId)\n this.emitter.on(eventName, listener)\n return () => this.emitter.off(eventName, listener)\n }\n\n subscribeAll(listener: ConversationEventListener): () => void {\n this.emitter.on(ALL_CONVERSATION_EVENTS, listener)\n return () => this.emitter.off(ALL_CONVERSATION_EVENTS, listener)\n }\n\n async sendMessage(input: SendMessageInput): Promise<SendMessageResult> {\n return this.orchestration.sendMessage(input)\n }\n\n async cancelRun(\n conversationId: string,\n runId: string,\n ): Promise<CancelRunResult> {\n const result = await this.runLifecycle.cancelRun(conversationId, runId, {\n abortUpstream: true,\n reason: 'cancelled by app',\n })\n if (result.run.status === 'cancelled') {\n void this.orchestration.startNextQueuedRun(conversationId)\n }\n return result\n }\n\n async cancelRunById(runId: string): Promise<CancelRunResult> {\n const active = this.activeRunControllers.get(runId)\n if (active) {\n return this.cancelRun(active.conversationId, runId)\n }\n const conversationId = await this.runLifecycle.findConversationIdForRun(\n runId,\n )\n if (!conversationId) {\n throw new LinkHttpError(404, 'run_not_found', 'Run was not found')\n }\n return this.cancelRun(conversationId, runId)\n }\n\n async deleteConversation(\n conversationId: string,\n ): Promise<DeleteConversationResult> {\n return this.maintenance.deleteConversation(conversationId)\n }\n\n async deleteConversations(conversationIds: string[]): Promise<{\n deleted_count: number\n failed_count: number\n conversations: BulkDeleteConversationResult[]\n }> {\n return this.maintenance.deleteConversations(conversationIds)\n }\n\n async deleteLocalConversationsForProfile(input: {\n profileName: string\n profileUid?: string | null\n }): Promise<{ deleted_count: number; conversation_ids: string[] }> {\n const profileName = normalizeProfileName(input.profileName)\n const profileUid = input.profileUid?.trim() || null\n const deletedConversationIds: string[] = []\n for (const conversationId of await this.store.listConversationIds()) {\n const manifest = await this.store.readManifest(conversationId).catch(\n () => null,\n )\n if (!manifest || !conversationMatchesProfile(manifest, profileName, profileUid)) {\n continue\n }\n const deleted = await this.withConversationLock(conversationId, async () => {\n const lockedManifest = await this.store.readManifest(conversationId).catch(\n () => null,\n )\n if (\n !lockedManifest ||\n !conversationMatchesProfile(lockedManifest, profileName, profileUid)\n ) {\n return false\n }\n this.abortActiveRunsForConversation(conversationId)\n const snapshot = await this.store.readSnapshot(conversationId).catch(() =>\n emptySnapshot(),\n )\n const blobIds = new Set([\n ...collectBlobIds(snapshot),\n ...(await listConversationBlobIds(this.paths, conversationId).catch(\n () => [],\n )),\n ])\n for (const blobId of blobIds) {\n await pruneConversationBlobReference(\n this.paths,\n conversationId,\n blobId,\n ).catch((error: unknown) => {\n void this.logger.warn('profile_delete_blob_gc_failed', {\n profile: profileName,\n conversation_id: conversationId,\n blob_id: blobId,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n }\n await removeConversationFilesFromStore(this.paths, conversationId)\n return true\n })\n if (deleted) {\n deletedConversationIds.push(conversationId)\n }\n }\n await deleteConversationStatsForProfile(this.paths, {\n profileName,\n profileUid,\n })\n return {\n deleted_count: deletedConversationIds.length,\n conversation_ids: deletedConversationIds,\n }\n }\n\n async writeBlob(\n conversationId: string,\n input: { bytes: Uint8Array; filename?: string; mime?: string },\n ): Promise<{ id: string; size: number; mime: string; filename: string }> {\n return this.maintenance.writeBlob(conversationId, input)\n }\n\n async readBlob(\n conversationId: string,\n blobId: string,\n ): Promise<{ bytes: Buffer; mime: string; filename: string; size: number }> {\n return this.maintenance.readBlob(conversationId, blobId)\n }\n\n async deleteUnreferencedBlob(\n conversationId: string,\n blobId: string,\n ): Promise<{ deleted: boolean; blob_id: string }> {\n return this.maintenance.deleteUnreferencedBlob(conversationId, blobId)\n }\n\n private async refreshTitleFromHermes(\n manifest: ConversationManifest,\n options: { emitEvent?: boolean; snapshot?: ConversationSnapshot } = {},\n ): Promise<ConversationManifest> {\n return this.metadata.refreshTitleFromHermes(manifest, options)\n }\n\n private async persistConversationStats(\n conversationId: string,\n snapshot: ConversationSnapshot,\n statsOverride?: ConversationUsageStats,\n ): Promise<void> {\n return this.metadata.persistConversationStats(\n conversationId,\n snapshot,\n statsOverride,\n )\n }\n\n private async appendEvent(\n conversationId: string,\n input: Omit<ConversationEvent, 'seq' | 'conversation_id' | 'created_at'>,\n ): Promise<ConversationEvent> {\n const event = await this.store.appendEvent(conversationId, input)\n this.emitter.emit(this.liveEventName(conversationId), event)\n this.emitter.emit(ALL_CONVERSATION_EVENTS, event)\n return event\n }\n\n private abortActiveRunsForConversation(conversationId: string): void {\n for (const [runId, active] of this.activeRunControllers) {\n if (active.conversationId !== conversationId) {\n continue\n }\n active.controller.abort()\n this.activeRunControllers.delete(runId)\n }\n }\n\n private hasActiveRunControllerForConversation(conversationId: string): boolean {\n for (const active of this.activeRunControllers.values()) {\n if (active.conversationId === conversationId) {\n return true\n }\n }\n return false\n }\n\n private liveEventName(conversationId: string): string {\n return `conversation:${conversationId}`\n }\n}\n\nfunction conversationMatchesProfile(\n manifest: ConversationManifest,\n profileName: string,\n profileUid: string | null,\n): boolean {\n if (profileUid && manifest.profile_uid === profileUid) {\n return true\n }\n return (\n normalizeProfileName(manifest.profile_name_snapshot ?? manifest.profile) ===\n profileName\n )\n}\n\nexport async function removeConversationFiles(\n paths: RuntimePaths,\n conversationId: string,\n): Promise<void> {\n return removeConversationFilesFromStore(paths, conversationId)\n}\n","import { mkdir } from 'node:fs/promises'\nimport { randomUUID } from 'node:crypto'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport type { DatabaseSync, SQLInputValue } from 'node:sqlite'\nimport type { RuntimePaths } from '../runtime/paths.js'\n\ninterface Migration {\n version: number\n name: string\n sql: string\n}\n\nexport interface LinkDatabaseMigrationResult {\n databaseFile: string\n appliedVersions: number[]\n currentVersion: number\n targetVersion: number\n}\n\nexport interface ConversationStatsIndexRecord {\n conversationId: string\n kind: string\n title: string\n status: string\n hermesSessionId: string\n profileUid?: string | null\n profileNameSnapshot?: string | null\n profile?: string | null\n model?: string | null\n provider?: string | null\n contextWindow?: number | null\n inputTokens: number\n outputTokens: number\n totalTokens: number\n messageCount: number\n runCount: number\n createdAt: string\n updatedAt: string\n deletedAt?: string | null\n statsUpdatedAt: string\n}\n\nexport interface RunUsageFactRecord {\n runId: string\n conversationId: string\n profileUid?: string | null\n profileNameSnapshot?: string | null\n profile?: string | null\n model?: string | null\n provider?: string | null\n inputTokens: number\n outputTokens: number\n totalTokens: number\n messageCount: number\n startedAt: string\n completedAt: string\n updatedAt: string\n}\n\nexport interface LinkStatistics {\n conversations: {\n total: number\n active: number\n deleted: number\n }\n tokens: {\n input_tokens: number\n output_tokens: number\n total_tokens: number\n }\n messages: {\n total: number\n }\n runs: {\n total: number\n }\n models: {\n total: number\n }\n profiles: {\n total: number\n }\n skills: {\n total: number\n }\n tools: {\n total: number\n }\n updated_at?: string\n}\n\nexport interface LinkStatisticsFilter {\n profileUid?: string | null\n profileName?: string | null\n}\n\nexport interface LinkUsageStatisticsFilter extends LinkStatisticsFilter {\n from?: string | null\n to?: string | null\n days?: number | null\n}\n\nexport interface LinkUsageStatistics {\n range: {\n from: string\n to: string\n days: number\n }\n totals: {\n input_tokens: number\n output_tokens: number\n total_tokens: number\n message_count: number\n run_count: number\n conversation_count: number\n model_count: number\n }\n daily: Array<{\n date: string\n input_tokens: number\n output_tokens: number\n total_tokens: number\n message_count: number\n run_count: number\n }>\n models: Array<{\n model: string\n provider?: string\n input_tokens: number\n output_tokens: number\n total_tokens: number\n message_count: number\n run_count: number\n }>\n profiles: Array<{\n profile_uid?: string\n profile: string\n input_tokens: number\n output_tokens: number\n total_tokens: number\n message_count: number\n run_count: number\n }>\n updated_at?: string\n}\n\nexport type ProfileAvatarType = 'default' | 'url'\n\nexport interface ProfileIdentityRecord {\n profileUid: string\n profileName: string\n profilePath: string\n displayName?: string | null\n description?: string | null\n avatarType: ProfileAvatarType\n avatarUrl?: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface ProfileMetadataUpdate {\n displayName?: string | null\n description?: string | null\n avatarType?: ProfileAvatarType\n avatarUrl?: string | null\n}\n\nconst MIGRATIONS: Migration[] = [\n {\n version: 1,\n name: 'create_conversation_stats',\n sql: `\n CREATE TABLE IF NOT EXISTS conversation_stats (\n conversation_id TEXT PRIMARY KEY,\n kind TEXT NOT NULL,\n title TEXT NOT NULL,\n status TEXT NOT NULL,\n hermes_session_id TEXT NOT NULL,\n profile TEXT,\n model TEXT,\n provider TEXT,\n context_window INTEGER,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n total_tokens INTEGER NOT NULL DEFAULT 0,\n message_count INTEGER NOT NULL DEFAULT 0,\n run_count INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n deleted_at TEXT,\n stats_updated_at TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_conversation_stats_status\n ON conversation_stats(status);\n CREATE INDEX IF NOT EXISTS idx_conversation_stats_updated_at\n ON conversation_stats(updated_at);\n CREATE INDEX IF NOT EXISTS idx_conversation_stats_model\n ON conversation_stats(model);\n CREATE INDEX IF NOT EXISTS idx_conversation_stats_profile\n ON conversation_stats(profile);\n `,\n },\n {\n version: 2,\n name: 'profile_identity_registry',\n sql: `\n CREATE TABLE IF NOT EXISTS profile_registry (\n profile_uid TEXT PRIMARY KEY,\n profile_name TEXT NOT NULL UNIQUE,\n profile_path TEXT NOT NULL,\n display_name TEXT,\n description TEXT,\n avatar_type TEXT NOT NULL DEFAULT 'default',\n avatar_url TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n `,\n },\n {\n version: 3,\n name: 'run_usage_facts',\n sql: `\n CREATE TABLE IF NOT EXISTS run_usage_facts (\n run_id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL,\n profile_uid TEXT,\n profile_name_snapshot TEXT,\n profile TEXT,\n model TEXT,\n provider TEXT,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n total_tokens INTEGER NOT NULL DEFAULT 0,\n message_count INTEGER NOT NULL DEFAULT 0,\n started_at TEXT NOT NULL,\n completed_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_run_usage_facts_completed_at\n ON run_usage_facts(completed_at);\n CREATE INDEX IF NOT EXISTS idx_run_usage_facts_conversation_id\n ON run_usage_facts(conversation_id);\n CREATE INDEX IF NOT EXISTS idx_run_usage_facts_model\n ON run_usage_facts(model);\n CREATE INDEX IF NOT EXISTS idx_run_usage_facts_profile_uid\n ON run_usage_facts(profile_uid);\n CREATE INDEX IF NOT EXISTS idx_run_usage_facts_profile_name_snapshot\n ON run_usage_facts(profile_name_snapshot);\n\n INSERT OR IGNORE INTO run_usage_facts (\n run_id,\n conversation_id,\n profile_uid,\n profile_name_snapshot,\n profile,\n model,\n provider,\n input_tokens,\n output_tokens,\n total_tokens,\n message_count,\n started_at,\n completed_at,\n updated_at\n )\n SELECT\n 'legacy_' || conversation_id,\n conversation_id,\n NULL,\n profile,\n profile,\n model,\n provider,\n input_tokens,\n output_tokens,\n total_tokens,\n message_count,\n COALESCE(stats_updated_at, updated_at, created_at),\n COALESCE(stats_updated_at, updated_at, created_at),\n COALESCE(stats_updated_at, updated_at, created_at)\n FROM conversation_stats\n WHERE input_tokens > 0\n OR output_tokens > 0\n OR total_tokens > 0\n OR message_count > 0\n OR run_count > 0;\n `,\n },\n]\n\nconst nodeRequire = createRequire(import.meta.url)\n\nexport async function migrateLinkDatabase(paths: RuntimePaths): Promise<LinkDatabaseMigrationResult> {\n await mkdir(path.dirname(paths.databaseFile), { recursive: true, mode: 0o700 })\n const db = openDatabase(paths)\n const appliedVersions: number[] = []\n try {\n db.exec(`\n CREATE TABLE IF NOT EXISTS schema_migrations (\n version INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n applied_at TEXT NOT NULL\n );\n `)\n const applied = readAppliedVersions(db)\n for (const migration of MIGRATIONS) {\n if (applied.has(migration.version)) {\n continue\n }\n db.exec('BEGIN IMMEDIATE')\n try {\n db.exec(migration.sql)\n db.prepare('INSERT INTO schema_migrations (version, name, applied_at) VALUES (?, ?, ?)').run(\n migration.version,\n migration.name,\n new Date().toISOString(),\n )\n db.exec('COMMIT')\n applied.add(migration.version)\n appliedVersions.push(migration.version)\n } catch (error) {\n rollback(db)\n throw error\n }\n }\n ensureProfileIdentitySchema(db)\n return {\n databaseFile: paths.databaseFile,\n appliedVersions,\n currentVersion: Math.max(0, ...applied),\n targetVersion: MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0,\n }\n } finally {\n db.close()\n }\n}\n\nexport async function replaceConversationStatsIndex(\n paths: RuntimePaths,\n records: ConversationStatsIndexRecord[],\n): Promise<void> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n try {\n db.exec('BEGIN IMMEDIATE')\n try {\n db.exec('DELETE FROM conversation_stats')\n const statement = db.prepare(conversationStatsUpsertSql())\n for (const record of records) {\n statement.run(...conversationStatsParams(record))\n }\n db.exec('COMMIT')\n } catch (error) {\n rollback(db)\n throw error\n }\n } finally {\n db.close()\n }\n}\n\nexport async function upsertConversationStats(\n paths: RuntimePaths,\n record: ConversationStatsIndexRecord,\n): Promise<void> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n try {\n db.prepare(conversationStatsUpsertSql()).run(...conversationStatsParams(record))\n } finally {\n db.close()\n }\n}\n\nexport async function replaceRunUsageFactsForConversation(\n paths: RuntimePaths,\n conversationId: string,\n records: RunUsageFactRecord[],\n): Promise<void> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n try {\n db.exec('BEGIN IMMEDIATE')\n try {\n db.prepare('DELETE FROM run_usage_facts WHERE conversation_id = ?').run(\n conversationId,\n )\n const statement = db.prepare(runUsageFactUpsertSql())\n for (const record of records) {\n statement.run(...runUsageFactParams(record))\n }\n db.exec('COMMIT')\n } catch (error) {\n rollback(db)\n throw error\n }\n } finally {\n db.close()\n }\n}\n\nexport async function readLinkStatistics(\n paths: RuntimePaths,\n filter: LinkStatisticsFilter = {},\n): Promise<LinkStatistics> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n try {\n const conversationWhere = statisticsWhereClause(filter)\n const usageWhere = runUsageWhereClause(filter)\n const conversationRow = db.prepare(`\n SELECT\n COUNT(*) AS total_conversations,\n SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) AS active_conversations,\n SUM(CASE WHEN status <> 'active' THEN 1 ELSE 0 END) AS deleted_conversations,\n COUNT(DISTINCT CASE\n WHEN profile_uid IS NOT NULL AND profile_uid <> '' THEN profile_uid\n WHEN profile_name_snapshot IS NOT NULL AND profile_name_snapshot <> '' THEN profile_name_snapshot\n WHEN profile IS NOT NULL AND profile <> '' THEN profile\n END) AS profile_count,\n MAX(stats_updated_at) AS updated_at\n FROM conversation_stats\n ${conversationWhere.sql}\n `).get(...conversationWhere.params) as Record<string, unknown> | undefined\n const usageRow = db.prepare(`\n SELECT\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(total_tokens), 0) AS total_tokens,\n COALESCE(SUM(message_count), 0) AS message_count,\n COUNT(*) AS run_count,\n COUNT(DISTINCT CASE WHEN model IS NOT NULL AND model <> '' THEN model END) AS model_count,\n COUNT(DISTINCT CASE\n WHEN profile_uid IS NOT NULL AND profile_uid <> '' THEN profile_uid\n WHEN profile_name_snapshot IS NOT NULL AND profile_name_snapshot <> '' THEN profile_name_snapshot\n WHEN profile IS NOT NULL AND profile <> '' THEN profile\n END) AS profile_count,\n MAX(updated_at) AS updated_at\n FROM run_usage_facts\n ${usageWhere.sql}\n `).get(...usageWhere.params) as Record<string, unknown> | undefined\n const updatedAt =\n readString(usageRow, 'updated_at') ?? readString(conversationRow, 'updated_at')\n return {\n conversations: {\n total: readNumber(conversationRow, 'total_conversations'),\n active: readNumber(conversationRow, 'active_conversations'),\n deleted: readNumber(conversationRow, 'deleted_conversations'),\n },\n tokens: {\n input_tokens: readNumber(usageRow, 'input_tokens'),\n output_tokens: readNumber(usageRow, 'output_tokens'),\n total_tokens: readNumber(usageRow, 'total_tokens'),\n },\n messages: {\n total: readNumber(usageRow, 'message_count'),\n },\n runs: {\n total: readNumber(usageRow, 'run_count'),\n },\n models: {\n total: readNumber(usageRow, 'model_count'),\n },\n profiles: {\n total:\n readNumber(usageRow, 'profile_count') ||\n readNumber(conversationRow, 'profile_count'),\n },\n skills: {\n total: 0,\n },\n tools: {\n total: 0,\n },\n ...(updatedAt ? { updated_at: updatedAt } : {}),\n }\n } finally {\n db.close()\n }\n}\n\nexport async function readLinkUsageStatistics(\n paths: RuntimePaths,\n filter: LinkUsageStatisticsFilter = {},\n): Promise<LinkUsageStatistics> {\n await migrateLinkDatabase(paths)\n const range = normalizeUsageRange(filter)\n const db = openDatabase(paths)\n try {\n const where = runUsageWhereClause({\n ...filter,\n from: range.fromInclusive,\n to: range.toExclusive,\n })\n const totalsRow = db.prepare(`\n SELECT\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(total_tokens), 0) AS total_tokens,\n COALESCE(SUM(message_count), 0) AS message_count,\n COUNT(*) AS run_count,\n COUNT(DISTINCT conversation_id) AS conversation_count,\n COUNT(DISTINCT CASE WHEN model IS NOT NULL AND model <> '' THEN model END) AS model_count,\n MAX(updated_at) AS updated_at\n FROM run_usage_facts\n ${where.sql}\n `).get(...where.params) as Record<string, unknown> | undefined\n const dailyRows = db.prepare(`\n SELECT\n substr(completed_at, 1, 10) AS date,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(total_tokens), 0) AS total_tokens,\n COALESCE(SUM(message_count), 0) AS message_count,\n COUNT(*) AS run_count\n FROM run_usage_facts\n ${where.sql}\n GROUP BY substr(completed_at, 1, 10)\n ORDER BY date ASC\n `).all(...where.params) as Array<Record<string, unknown>>\n const modelRows = db.prepare(`\n SELECT\n COALESCE(NULLIF(model, ''), 'unknown') AS model,\n provider,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(total_tokens), 0) AS total_tokens,\n COALESCE(SUM(message_count), 0) AS message_count,\n COUNT(*) AS run_count\n FROM run_usage_facts\n ${where.sql}\n GROUP BY COALESCE(NULLIF(model, ''), 'unknown'), provider\n HAVING total_tokens > 0\n ORDER BY total_tokens DESC, run_count DESC, model ASC\n LIMIT 12\n `).all(...where.params) as Array<Record<string, unknown>>\n const profileRows = db.prepare(`\n SELECT\n MAX(NULLIF(profile_uid, '')) AS profile_uid,\n COALESCE(\n NULLIF(profile_name_snapshot, ''),\n NULLIF(profile, ''),\n NULLIF(profile_uid, ''),\n 'unknown'\n ) AS profile,\n COALESCE(SUM(input_tokens), 0) AS input_tokens,\n COALESCE(SUM(output_tokens), 0) AS output_tokens,\n COALESCE(SUM(total_tokens), 0) AS total_tokens,\n COALESCE(SUM(message_count), 0) AS message_count,\n COUNT(*) AS run_count\n FROM run_usage_facts\n ${where.sql}\n GROUP BY COALESCE(\n NULLIF(profile_name_snapshot, ''),\n NULLIF(profile, ''),\n NULLIF(profile_uid, ''),\n 'unknown'\n )\n HAVING total_tokens > 0\n ORDER BY total_tokens DESC, run_count DESC, profile ASC\n LIMIT 12\n `).all(...where.params) as Array<Record<string, unknown>>\n const dailyByDate = new Map(\n dailyRows.map((row) => [readString(row, 'date') ?? '', row]),\n )\n return {\n range: {\n from: range.fromDate,\n to: range.toDate,\n days: range.days,\n },\n totals: {\n input_tokens: readNumber(totalsRow, 'input_tokens'),\n output_tokens: readNumber(totalsRow, 'output_tokens'),\n total_tokens: readNumber(totalsRow, 'total_tokens'),\n message_count: readNumber(totalsRow, 'message_count'),\n run_count: readNumber(totalsRow, 'run_count'),\n conversation_count: readNumber(totalsRow, 'conversation_count'),\n model_count: readNumber(totalsRow, 'model_count'),\n },\n daily: range.dates.map((date) => {\n const row = dailyByDate.get(date)\n return {\n date,\n input_tokens: readNumber(row, 'input_tokens'),\n output_tokens: readNumber(row, 'output_tokens'),\n total_tokens: readNumber(row, 'total_tokens'),\n message_count: readNumber(row, 'message_count'),\n run_count: readNumber(row, 'run_count'),\n }\n }),\n models: modelRows.map((row) => ({\n model: readString(row, 'model') ?? 'unknown',\n ...(readString(row, 'provider')\n ? { provider: readString(row, 'provider') }\n : {}),\n input_tokens: readNumber(row, 'input_tokens'),\n output_tokens: readNumber(row, 'output_tokens'),\n total_tokens: readNumber(row, 'total_tokens'),\n message_count: readNumber(row, 'message_count'),\n run_count: readNumber(row, 'run_count'),\n })),\n profiles: profileRows.map((row) => ({\n ...(readString(row, 'profile_uid')\n ? { profile_uid: readString(row, 'profile_uid') }\n : {}),\n profile: readString(row, 'profile') ?? 'unknown',\n input_tokens: readNumber(row, 'input_tokens'),\n output_tokens: readNumber(row, 'output_tokens'),\n total_tokens: readNumber(row, 'total_tokens'),\n message_count: readNumber(row, 'message_count'),\n run_count: readNumber(row, 'run_count'),\n })),\n ...(readString(totalsRow, 'updated_at')\n ? { updated_at: readString(totalsRow, 'updated_at') }\n : {}),\n }\n } finally {\n db.close()\n }\n}\n\nexport async function ensureProfileIdentity(\n paths: RuntimePaths,\n input: { profileName: string; profilePath: string },\n): Promise<ProfileIdentityRecord> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n const now = new Date().toISOString()\n try {\n const existing = db.prepare(`\n ${profileRegistrySelectSql()}\n FROM profile_registry\n WHERE profile_name = ?\n `).get(input.profileName) as Record<string, unknown> | undefined\n if (existing) {\n db.prepare(`\n UPDATE profile_registry\n SET profile_path = ?, updated_at = ?\n WHERE profile_uid = ?\n `).run(input.profilePath, now, readString(existing, 'profile_uid') ?? '')\n return profileIdentityFromRow({\n ...existing,\n profile_path: input.profilePath,\n updated_at: now,\n })\n }\n\n const profileUid = `prof_${randomUUID().replaceAll('-', '')}`\n db.prepare(`\n INSERT INTO profile_registry (\n profile_uid,\n profile_name,\n profile_path,\n created_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?)\n `).run(profileUid, input.profileName, input.profilePath, now, now)\n return {\n profileUid,\n profileName: input.profileName,\n profilePath: input.profilePath,\n avatarType: 'default',\n createdAt: now,\n updatedAt: now,\n }\n } finally {\n db.close()\n }\n}\n\nexport async function updateProfileMetadata(\n paths: RuntimePaths,\n input: { profileName: string; metadata: ProfileMetadataUpdate },\n): Promise<ProfileIdentityRecord> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n const now = new Date().toISOString()\n try {\n const existing = db.prepare(`\n ${profileRegistrySelectSql()}\n FROM profile_registry\n WHERE profile_name = ?\n `).get(input.profileName) as Record<string, unknown> | undefined\n if (!existing) {\n throw new Error('profile identity not found')\n }\n\n const updates: string[] = []\n const params: SQLInputValue[] = []\n if ('displayName' in input.metadata) {\n updates.push('display_name = ?')\n params.push(normalizeOptionalText(input.metadata.displayName))\n }\n if ('description' in input.metadata) {\n updates.push('description = ?')\n params.push(normalizeOptionalText(input.metadata.description))\n }\n if ('avatarType' in input.metadata) {\n updates.push('avatar_type = ?')\n params.push(input.metadata.avatarType ?? 'default')\n }\n if (input.metadata.avatarType === 'default') {\n updates.push('avatar_url = NULL')\n } else if ('avatarUrl' in input.metadata) {\n updates.push('avatar_url = ?')\n params.push(normalizeOptionalText(input.metadata.avatarUrl))\n }\n if (updates.length === 0) {\n return profileIdentityFromRow(existing)\n }\n\n db.prepare(`\n UPDATE profile_registry\n SET ${updates.join(', ')}, updated_at = ?\n WHERE profile_name = ?\n `).run(...params, now, input.profileName)\n\n const updated = db.prepare(`\n ${profileRegistrySelectSql()}\n FROM profile_registry\n WHERE profile_name = ?\n `).get(input.profileName) as Record<string, unknown> | undefined\n return profileIdentityFromRow(updated ?? existing)\n } finally {\n db.close()\n }\n}\n\nexport async function renameProfileIdentity(\n paths: RuntimePaths,\n input: { oldProfileName: string; newProfileName: string; newProfilePath: string },\n): Promise<ProfileIdentityRecord> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n const now = new Date().toISOString()\n let result: ProfileIdentityRecord | null = null\n try {\n const existing = db.prepare(`\n ${profileRegistrySelectSql()}\n FROM profile_registry\n WHERE profile_name = ?\n `).get(input.oldProfileName) as Record<string, unknown> | undefined\n if (existing) {\n const profileUid = readString(existing, 'profile_uid') ?? `prof_${randomUUID().replaceAll('-', '')}`\n db.prepare(`\n UPDATE profile_registry\n SET profile_name = ?, profile_path = ?, updated_at = ?\n WHERE profile_uid = ?\n `).run(input.newProfileName, input.newProfilePath, now, profileUid)\n result = {\n profileUid,\n profileName: input.newProfileName,\n profilePath: input.newProfilePath,\n displayName: readNullableString(existing, 'display_name'),\n description: readNullableString(existing, 'description'),\n avatarType: readProfileAvatarType(existing),\n avatarUrl: readNullableString(existing, 'avatar_url'),\n createdAt: readString(existing, 'created_at') ?? now,\n updatedAt: now,\n }\n }\n } finally {\n db.close()\n }\n if (result) {\n return result\n }\n return ensureProfileIdentity(paths, {\n profileName: input.newProfileName,\n profilePath: input.newProfilePath,\n })\n}\n\nexport async function deleteProfileIdentity(\n paths: RuntimePaths,\n input: { profileName: string; profileUid?: string | null },\n): Promise<void> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n try {\n if (input.profileUid?.trim()) {\n db.prepare(\n 'DELETE FROM profile_registry WHERE profile_uid = ? OR profile_name = ?',\n ).run(input.profileUid.trim(), input.profileName)\n return\n }\n db.prepare('DELETE FROM profile_registry WHERE profile_name = ?').run(\n input.profileName,\n )\n } finally {\n db.close()\n }\n}\n\nexport async function deleteConversationStatsForProfile(\n paths: RuntimePaths,\n input: { profileName: string; profileUid?: string | null },\n): Promise<void> {\n await migrateLinkDatabase(paths)\n const db = openDatabase(paths)\n try {\n if (input.profileUid?.trim()) {\n db.prepare(`\n DELETE FROM conversation_stats\n WHERE profile_uid = ?\n OR profile_name_snapshot = ?\n OR (\n (profile_name_snapshot IS NULL OR profile_name_snapshot = '')\n AND profile = ?\n )\n `).run(input.profileUid.trim(), input.profileName, input.profileName)\n return\n }\n db.prepare(`\n DELETE FROM conversation_stats\n WHERE profile_name_snapshot = ?\n OR (\n (profile_name_snapshot IS NULL OR profile_name_snapshot = '')\n AND profile = ?\n )\n `).run(input.profileName, input.profileName)\n } finally {\n db.close()\n }\n}\n\nfunction openDatabase(paths: RuntimePaths): DatabaseSync {\n const { DatabaseSync } = nodeRequire('node:sqlite') as typeof import('node:sqlite')\n const db = new DatabaseSync(paths.databaseFile, {\n timeout: 5_000,\n })\n db.exec(`\n PRAGMA foreign_keys = ON;\n PRAGMA busy_timeout = 5000;\n PRAGMA journal_mode = WAL;\n `)\n return db\n}\n\nfunction readAppliedVersions(db: DatabaseSync): Set<number> {\n const rows = db.prepare('SELECT version FROM schema_migrations').all() as Array<Record<string, unknown>>\n return new Set(rows.map((row) => readNumber(row, 'version')).filter((value) => value > 0))\n}\n\nfunction ensureProfileIdentitySchema(db: DatabaseSync): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS profile_registry (\n profile_uid TEXT PRIMARY KEY,\n profile_name TEXT NOT NULL UNIQUE,\n profile_path TEXT NOT NULL,\n display_name TEXT,\n description TEXT,\n avatar_type TEXT NOT NULL DEFAULT 'default',\n avatar_url TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n `)\n const profileColumns = new Set(\n (db.prepare(\"PRAGMA table_info('profile_registry')\").all() as Array<Record<string, unknown>>)\n .map((row) => readString(row, 'name'))\n .filter((value): value is string => Boolean(value)),\n )\n if (!profileColumns.has('display_name')) {\n db.exec('ALTER TABLE profile_registry ADD COLUMN display_name TEXT;')\n }\n if (!profileColumns.has('description')) {\n db.exec('ALTER TABLE profile_registry ADD COLUMN description TEXT;')\n }\n if (!profileColumns.has('avatar_type')) {\n db.exec(\"ALTER TABLE profile_registry ADD COLUMN avatar_type TEXT NOT NULL DEFAULT 'default';\")\n }\n if (!profileColumns.has('avatar_url')) {\n db.exec('ALTER TABLE profile_registry ADD COLUMN avatar_url TEXT;')\n }\n\n const conversationColumns = new Set(\n (db.prepare(\"PRAGMA table_info('conversation_stats')\").all() as Array<Record<string, unknown>>)\n .map((row) => readString(row, 'name'))\n .filter((value): value is string => Boolean(value)),\n )\n if (!conversationColumns.has('profile_uid')) {\n db.exec('ALTER TABLE conversation_stats ADD COLUMN profile_uid TEXT;')\n }\n if (!conversationColumns.has('profile_name_snapshot')) {\n db.exec('ALTER TABLE conversation_stats ADD COLUMN profile_name_snapshot TEXT;')\n }\n db.exec(`\n CREATE INDEX IF NOT EXISTS idx_conversation_stats_profile_uid\n ON conversation_stats(profile_uid);\n CREATE INDEX IF NOT EXISTS idx_conversation_stats_profile_name_snapshot\n ON conversation_stats(profile_name_snapshot);\n CREATE INDEX IF NOT EXISTS idx_profile_registry_profile_name\n ON profile_registry(profile_name);\n `)\n}\n\nfunction conversationStatsUpsertSql(): string {\n return `\n INSERT INTO conversation_stats (\n conversation_id,\n kind,\n title,\n status,\n hermes_session_id,\n profile_uid,\n profile_name_snapshot,\n profile,\n model,\n provider,\n context_window,\n input_tokens,\n output_tokens,\n total_tokens,\n message_count,\n run_count,\n created_at,\n updated_at,\n deleted_at,\n stats_updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(conversation_id) DO UPDATE SET\n kind = excluded.kind,\n title = excluded.title,\n status = excluded.status,\n hermes_session_id = excluded.hermes_session_id,\n profile_uid = excluded.profile_uid,\n profile_name_snapshot = excluded.profile_name_snapshot,\n profile = excluded.profile,\n model = excluded.model,\n provider = excluded.provider,\n context_window = excluded.context_window,\n input_tokens = excluded.input_tokens,\n output_tokens = excluded.output_tokens,\n total_tokens = excluded.total_tokens,\n message_count = excluded.message_count,\n run_count = excluded.run_count,\n created_at = excluded.created_at,\n updated_at = excluded.updated_at,\n deleted_at = excluded.deleted_at,\n stats_updated_at = excluded.stats_updated_at\n `\n}\n\nfunction conversationStatsParams(record: ConversationStatsIndexRecord): SQLInputValue[] {\n return [\n record.conversationId,\n record.kind,\n record.title,\n record.status,\n record.hermesSessionId,\n record.profileUid ?? null,\n record.profileNameSnapshot ?? record.profile ?? null,\n record.profile ?? record.profileNameSnapshot ?? null,\n record.model ?? null,\n record.provider ?? null,\n record.contextWindow ?? null,\n record.inputTokens,\n record.outputTokens,\n record.totalTokens,\n record.messageCount,\n record.runCount,\n record.createdAt,\n record.updatedAt,\n record.deletedAt ?? null,\n record.statsUpdatedAt,\n ]\n}\n\nfunction runUsageFactUpsertSql(): string {\n return `\n INSERT INTO run_usage_facts (\n run_id,\n conversation_id,\n profile_uid,\n profile_name_snapshot,\n profile,\n model,\n provider,\n input_tokens,\n output_tokens,\n total_tokens,\n message_count,\n started_at,\n completed_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(run_id) DO UPDATE SET\n conversation_id = excluded.conversation_id,\n profile_uid = excluded.profile_uid,\n profile_name_snapshot = excluded.profile_name_snapshot,\n profile = excluded.profile,\n model = excluded.model,\n provider = excluded.provider,\n input_tokens = excluded.input_tokens,\n output_tokens = excluded.output_tokens,\n total_tokens = excluded.total_tokens,\n message_count = excluded.message_count,\n started_at = excluded.started_at,\n completed_at = excluded.completed_at,\n updated_at = excluded.updated_at\n `\n}\n\nfunction runUsageFactParams(record: RunUsageFactRecord): SQLInputValue[] {\n return [\n record.runId,\n record.conversationId,\n record.profileUid ?? null,\n record.profileNameSnapshot ?? record.profile ?? null,\n record.profile ?? record.profileNameSnapshot ?? null,\n record.model ?? null,\n record.provider ?? null,\n record.inputTokens,\n record.outputTokens,\n record.totalTokens,\n record.messageCount,\n record.startedAt,\n record.completedAt,\n record.updatedAt,\n ]\n}\n\nfunction rollback(db: DatabaseSync): void {\n try {\n db.exec('ROLLBACK')\n } catch {\n // The transaction may already have been rolled back by SQLite.\n }\n}\n\nfunction readNumber(row: Record<string, unknown> | undefined, key: string): number {\n const value = row?.[key]\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value\n }\n if (typeof value === 'bigint') {\n return Number(value)\n }\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : 0\n }\n return 0\n}\n\nfunction readString(row: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = row?.[key]\n return typeof value === 'string' && value.trim() ? value : undefined\n}\n\nfunction statisticsWhereClause(filter: LinkStatisticsFilter): { sql: string; params: SQLInputValue[] } {\n const profileUid = filter.profileUid?.trim()\n const profileName = filter.profileName?.trim()\n if (profileUid && profileName) {\n return {\n sql: `WHERE (\n profile_uid = ?\n OR (\n (profile_uid IS NULL OR profile_uid = '')\n AND (\n profile_name_snapshot = ?\n OR (profile_name_snapshot IS NULL AND profile = ?)\n )\n )\n )`,\n params: [profileUid, profileName, profileName],\n }\n }\n if (profileUid) {\n return { sql: 'WHERE profile_uid = ?', params: [profileUid] }\n }\n if (profileName) {\n return {\n sql: `WHERE (\n profile_name_snapshot = ?\n OR (profile_name_snapshot IS NULL AND profile = ?)\n )`,\n params: [profileName, profileName],\n }\n }\n return { sql: '', params: [] }\n}\n\nfunction runUsageWhereClause(\n filter: LinkUsageStatisticsFilter,\n): { sql: string; params: SQLInputValue[] } {\n const conditions: string[] = []\n const params: SQLInputValue[] = []\n const profileUid = filter.profileUid?.trim()\n const profileName = filter.profileName?.trim()\n if (profileUid && profileName) {\n conditions.push(`(\n profile_uid = ?\n OR (\n (profile_uid IS NULL OR profile_uid = '')\n AND (\n profile_name_snapshot = ?\n OR (profile_name_snapshot IS NULL AND profile = ?)\n )\n )\n )`)\n params.push(profileUid, profileName, profileName)\n } else if (profileUid) {\n conditions.push('profile_uid = ?')\n params.push(profileUid)\n } else if (profileName) {\n conditions.push(`(\n profile_name_snapshot = ?\n OR (profile_name_snapshot IS NULL AND profile = ?)\n )`)\n params.push(profileName, profileName)\n }\n const from = filter.from?.trim()\n if (from) {\n conditions.push('completed_at >= ?')\n params.push(from)\n }\n const to = filter.to?.trim()\n if (to) {\n conditions.push('completed_at < ?')\n params.push(to)\n }\n return {\n sql: conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '',\n params,\n }\n}\n\nfunction normalizeUsageRange(filter: LinkUsageStatisticsFilter): {\n fromDate: string\n toDate: string\n fromInclusive: string\n toExclusive: string\n days: number\n dates: string[]\n} {\n const today = startOfUtcDay(new Date())\n const parsedTo = parseDateOnly(filter.to) ?? today\n const to = parsedTo > today ? today : parsedTo\n const requestedDays = clampDays(filter.days)\n const parsedFrom = parseDateOnly(filter.from)\n const from = parsedFrom ?? addUtcDays(to, -(requestedDays - 1))\n const normalizedFrom =\n differenceInUtcDays(from, to) > 29 ? addUtcDays(to, -29) : from\n const orderedFrom = normalizedFrom > to ? to : normalizedFrom\n const days = differenceInUtcDays(orderedFrom, to) + 1\n return {\n fromDate: formatDateOnly(orderedFrom),\n toDate: formatDateOnly(to),\n fromInclusive: `${formatDateOnly(orderedFrom)}T00:00:00.000Z`,\n toExclusive: `${formatDateOnly(addUtcDays(to, 1))}T00:00:00.000Z`,\n days,\n dates: Array.from({ length: days }, (_value, index) =>\n formatDateOnly(addUtcDays(orderedFrom, index)),\n ),\n }\n}\n\nfunction clampDays(days: number | null | undefined): number {\n if (!Number.isFinite(days ?? NaN)) {\n return 30\n }\n return Math.max(1, Math.min(30, Math.trunc(days ?? 30)))\n}\n\nfunction parseDateOnly(value: string | null | undefined): Date | null {\n if (!value) {\n return null\n }\n const match = /^(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})$/u.exec(\n value.trim(),\n )\n if (!match?.groups) {\n return null\n }\n const year = Number(match.groups.year)\n const month = Number(match.groups.month)\n const day = Number(match.groups.day)\n const date = new Date(Date.UTC(year, month - 1, day))\n if (\n date.getUTCFullYear() !== year ||\n date.getUTCMonth() !== month - 1 ||\n date.getUTCDate() !== day\n ) {\n return null\n }\n return date\n}\n\nfunction startOfUtcDay(date: Date): Date {\n return new Date(\n Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()),\n )\n}\n\nfunction addUtcDays(date: Date, days: number): Date {\n const next = new Date(date)\n next.setUTCDate(next.getUTCDate() + days)\n return next\n}\n\nfunction differenceInUtcDays(from: Date, to: Date): number {\n const millisecondsPerDay = 86_400_000\n return Math.floor((to.getTime() - from.getTime()) / millisecondsPerDay)\n}\n\nfunction formatDateOnly(date: Date): string {\n return date.toISOString().slice(0, 10)\n}\n\nfunction profileIdentityFromRow(row: Record<string, unknown>): ProfileIdentityRecord {\n return {\n profileUid: readString(row, 'profile_uid') ?? '',\n profileName: readString(row, 'profile_name') ?? '',\n profilePath: readString(row, 'profile_path') ?? '',\n displayName: readNullableString(row, 'display_name'),\n description: readNullableString(row, 'description'),\n avatarType: readProfileAvatarType(row),\n avatarUrl: readNullableString(row, 'avatar_url'),\n createdAt: readString(row, 'created_at') ?? new Date().toISOString(),\n updatedAt: readString(row, 'updated_at') ?? new Date().toISOString(),\n }\n}\n\nfunction profileRegistrySelectSql(): string {\n return [\n 'SELECT profile_uid, profile_name, profile_path,',\n 'display_name, description, avatar_type, avatar_url,',\n 'created_at, updated_at',\n ].join(' ')\n}\n\nfunction normalizeOptionalText(value: string | null | undefined): string | null {\n if (typeof value !== 'string') {\n return null\n }\n const trimmed = value.trim()\n return trimmed ? trimmed : null\n}\n\nfunction readNullableString(row: Record<string, unknown> | undefined, key: string): string | null {\n return readString(row, key) ?? null\n}\n\nfunction readProfileAvatarType(row: Record<string, unknown> | undefined): ProfileAvatarType {\n return readString(row, 'avatar_type') === 'url' ? 'url' : 'default'\n}\n","import { mkdir, readdir, readFile, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport type { ConversationService } from '../conversations/conversation-service.js'\nimport type { FileLogger } from '../runtime/logger.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\nimport { resolveHermesProfileDir } from './config.js'\n\nexport const HERMES_LINK_CRON_DELIVER = 'hermes-link'\nexport const HERMES_CRON_LOCAL_DELIVER = 'local'\n\nconst REGISTRY_VERSION = 1\nconst MAX_CRON_OUTPUT_CHARS = 80_000\n\ninterface CronDeliveryRegistry {\n version: 1\n bindings: CronDeliveryBinding[]\n}\n\ninterface CronDeliveryBinding {\n profileName: string\n jobId: string\n conversationId: string\n source: 'app' | 'natural_language'\n createdAt: string\n deliveredOutputPaths?: string[]\n}\n\nexport interface CronDeliveryBindingInput {\n profileName: string\n jobId: string\n conversationId: string\n source: 'app' | 'natural_language'\n}\n\nexport interface CronDeliveryRuntime {\n appendCronDelivery(input: {\n conversationId: string\n profileName: string\n jobId: string\n jobName?: string\n outputPath: string\n content: string\n runAt?: string\n }): Promise<void>\n}\n\nexport function isHermesLinkCronDeliver(value: string | undefined): boolean {\n return normalizeDeliverValue(value) === HERMES_LINK_CRON_DELIVER\n}\n\nexport function normalizeCronDeliverForHermes(\n value: string | undefined,\n): string | undefined {\n return isHermesLinkCronDeliver(value) ? HERMES_CRON_LOCAL_DELIVER : value\n}\n\nexport async function bindCronJobToHermesLink(\n paths: RuntimePaths,\n input: CronDeliveryBindingInput,\n): Promise<void> {\n const registry = await readRegistry(paths)\n const existing = registry.bindings.find(\n (binding) =>\n binding.profileName === input.profileName &&\n binding.jobId === input.jobId,\n )\n if (existing) {\n existing.conversationId = input.conversationId\n existing.source = input.source\n } else {\n registry.bindings.push({\n ...input,\n createdAt: new Date().toISOString(),\n deliveredOutputPaths: [],\n })\n }\n await writeRegistry(paths, registry)\n}\n\nexport async function bindNewCronJobsToHermesLink(\n paths: RuntimePaths,\n input: {\n profileName: string\n conversationId: string\n beforeJobIds: Set<string>\n jobs: Record<string, unknown>[]\n },\n): Promise<void> {\n for (const job of input.jobs) {\n const jobId = readString(job, 'id') ?? readString(job, 'job_id')\n if (!jobId || input.beforeJobIds.has(jobId)) {\n continue\n }\n const deliver = readString(job, 'deliver') ?? HERMES_CRON_LOCAL_DELIVER\n if (!shouldAutoBindNaturalLanguageDeliver(deliver)) {\n continue\n }\n await bindCronJobToHermesLink(paths, {\n profileName: input.profileName,\n jobId,\n conversationId: input.conversationId,\n source: 'natural_language',\n })\n }\n}\n\nexport async function unbindCronJobFromHermesLink(\n paths: RuntimePaths,\n profileName: string,\n jobId: string,\n): Promise<void> {\n const registry = await readRegistry(paths)\n const next = registry.bindings.filter(\n (binding) => binding.profileName !== profileName || binding.jobId !== jobId,\n )\n if (next.length === registry.bindings.length) {\n return\n }\n await writeRegistry(paths, { ...registry, bindings: next })\n}\n\nexport async function decorateHermesLinkCronJob(\n paths: RuntimePaths,\n profileName: string,\n job: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n const jobId = readString(job, 'id') ?? readString(job, 'job_id')\n if (!jobId) {\n return job\n }\n const registry = await readRegistry(paths)\n const binding = registry.bindings.find(\n (item) => item.profileName === profileName && item.jobId === jobId,\n )\n return binding ? { ...job, deliver: HERMES_LINK_CRON_DELIVER } : job\n}\n\nexport async function syncHermesLinkCronDeliveries(\n paths: RuntimePaths,\n runtime: CronDeliveryRuntime | ConversationService,\n logger: FileLogger,\n): Promise<void> {\n const registry = await readRegistry(paths)\n let touched = false\n for (const binding of registry.bindings) {\n const delivered = new Set(binding.deliveredOutputPaths ?? [])\n const outputs = await listCronOutputFiles(\n binding.profileName,\n binding.jobId,\n )\n for (const output of outputs) {\n if (delivered.has(output.path)) {\n continue\n }\n try {\n const content = await readCronOutput(output.path)\n await runtime.appendCronDelivery({\n conversationId: binding.conversationId,\n profileName: binding.profileName,\n jobId: binding.jobId,\n jobName: await readCronJobNameFromOutput(content),\n outputPath: output.path,\n content,\n runAt: output.mtime,\n })\n delivered.add(output.path)\n touched = true\n } catch (error) {\n void logger.warn('cron_link_delivery_failed', {\n profile: binding.profileName,\n job_id: binding.jobId,\n output_path: output.path,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n binding.deliveredOutputPaths = [...delivered]\n }\n if (touched) {\n await writeRegistry(paths, registry)\n }\n}\n\nasync function listCronOutputFiles(\n profileName: string,\n jobId: string,\n): Promise<Array<{ path: string; mtime: string }>> {\n const outputDir = path.join(\n resolveHermesProfileDir(profileName),\n 'cron',\n 'output',\n jobId,\n )\n const entries = await readdir(outputDir, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n },\n )\n const files: Array<{ path: string; mtime: string; mtimeMs: number }> = []\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md')) {\n continue\n }\n const outputPath = path.join(outputDir, entry.name)\n const fileStat = await stat(outputPath)\n files.push({\n path: outputPath,\n mtime: fileStat.mtime.toISOString(),\n mtimeMs: fileStat.mtimeMs,\n })\n }\n return files\n .sort((left, right) => left.mtimeMs - right.mtimeMs)\n .map(({ path, mtime }) => ({ path, mtime }))\n}\n\nasync function readCronOutput(outputPath: string): Promise<string> {\n const content = await readFile(outputPath, 'utf8')\n if (content.length <= MAX_CRON_OUTPUT_CHARS) {\n return content\n }\n return `${content.slice(0, MAX_CRON_OUTPUT_CHARS)}\\n\\n[输出过长,HermesLink 已截断展示。完整记录仍保留在 Hermes 本机 cron output 中。]`\n}\n\nasync function readCronJobNameFromOutput(\n content: string,\n): Promise<string | undefined> {\n const match = content.match(/^#\\s*Cron Job:\\s*(.+)$/mu)\n return match?.[1]?.trim() || undefined\n}\n\nasync function readRegistry(\n paths: RuntimePaths,\n): Promise<CronDeliveryRegistry> {\n const existing = await readJsonFile<CronDeliveryRegistry>(registryPath(paths))\n if (\n existing?.version === REGISTRY_VERSION &&\n Array.isArray(existing.bindings)\n ) {\n return {\n version: REGISTRY_VERSION,\n bindings: existing.bindings.filter(isValidBinding),\n }\n }\n return { version: REGISTRY_VERSION, bindings: [] }\n}\n\nasync function writeRegistry(\n paths: RuntimePaths,\n registry: CronDeliveryRegistry,\n): Promise<void> {\n await mkdir(paths.indexesDir, { recursive: true, mode: 0o700 })\n await writeJsonFile(registryPath(paths), registry)\n}\n\nfunction registryPath(paths: RuntimePaths): string {\n return path.join(paths.indexesDir, 'cron-link-deliveries.json')\n}\n\nfunction shouldAutoBindNaturalLanguageDeliver(value: string): boolean {\n const normalized = normalizeDeliverValue(value)\n return (\n normalized === HERMES_CRON_LOCAL_DELIVER ||\n normalized === 'origin' ||\n normalized === HERMES_LINK_CRON_DELIVER\n )\n}\n\nfunction normalizeDeliverValue(value: string | undefined): string {\n return (value ?? '').trim().toLowerCase()\n}\n\nfunction isValidBinding(value: unknown): value is CronDeliveryBinding {\n const binding = value as CronDeliveryBinding\n return (\n typeof binding?.profileName === 'string' &&\n typeof binding.jobId === 'string' &&\n typeof binding.conversationId === 'string' &&\n (binding.source === 'app' || binding.source === 'natural_language')\n )\n}\n\nfunction readString(\n record: Record<string, unknown>,\n ...keys: string[]\n): string | undefined {\n for (const key of keys) {\n const value = record[key]\n if (typeof value === 'string' && value.trim()) {\n return value.trim()\n }\n }\n return undefined\n}\n\nfunction isNodeError(\n error: unknown,\n code: string,\n): error is NodeJS.ErrnoException {\n return (\n error instanceof Error && (error as NodeJS.ErrnoException).code === code\n )\n}\n","import { mkdir, open, readFile, rename, rm } from 'node:fs/promises'\nimport { randomUUID } from 'node:crypto'\nimport path from 'node:path'\n\nexport async function readJsonFile<T>(filePath: string): Promise<T | null> {\n try {\n const raw = await readFile(filePath, 'utf8')\n return JSON.parse(raw) as T\n } catch (error) {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n }\n}\n\nexport async function writeJsonFile(filePath: string, value: unknown, mode = 0o600): Promise<void> {\n await mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 })\n const tmpPath = `${filePath}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`\n const payload = `${JSON.stringify(value, null, 2)}\\n`\n const handle = await open(tmpPath, 'w', mode)\n try {\n await handle.writeFile(payload, 'utf8')\n await handle.sync()\n } finally {\n await handle.close()\n }\n try {\n await rename(tmpPath, filePath)\n } catch (error) {\n await rm(tmpPath, { force: true })\n throw error\n }\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return typeof error === 'object' && error !== null && 'code' in error && error.code === code\n}\n","import { randomBytes } from 'node:crypto'\nimport net from 'node:net'\nimport {\n copyFile,\n mkdir,\n readFile,\n readdir,\n rename,\n writeFile,\n} from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport YAML from 'yaml'\n\nexport interface HermesApiServerConfig {\n host?: string\n port?: number\n key?: string\n enabled?: boolean\n}\n\nexport interface HermesModelConfig {\n model?: string\n provider?: string\n baseUrl?: string\n apiKey?: string\n keyEnv?: string\n apiMode?: string\n contextLength?: number\n reasoningEffort?: HermesReasoningEffort\n}\n\nexport type HermesReasoningEffort =\n | 'none'\n | 'minimal'\n | 'low'\n | 'medium'\n | 'high'\n | 'xhigh'\n\nexport type HermesReasoningSupport = 'known' | 'unknown' | 'unsupported'\n\nexport interface HermesManagedModelConfig {\n id: string\n provider: string\n providerName: string\n source: 'custom_provider' | 'model_default'\n baseUrl: string\n apiMode: string\n contextLength?: number\n keyEnv?: string\n credentialConfigured: boolean\n credentialState: 'configured' | 'missing' | 'unknown'\n isDefault: boolean\n reasoningEffort?: HermesReasoningEffort\n reasoningSupport: HermesReasoningSupport\n supportedReasoningEfforts: HermesReasoningEffort[] | null\n}\n\nexport interface ListHermesModelConfigsResult {\n ok: true\n configPath: string\n defaultModel: string | null\n defaultReasoningEffort: HermesReasoningEffort | null\n compressionModelId: string | null\n compressionModel: HermesManagedModelConfig | null\n models: HermesManagedModelConfig[]\n}\n\nexport interface SaveHermesModelConfigInput {\n id: string\n originalModelId?: string\n provider: string\n providerName?: string\n baseUrl: string\n apiKey?: string\n apiMode?: string\n contextLength?: number\n keyEnv?: string\n setDefault?: boolean\n reasoningEffort?: HermesReasoningEffort\n}\n\nexport interface SaveHermesModelConfigResult extends ListHermesModelConfigsResult {\n model: HermesManagedModelConfig\n backupPath: string | null\n requiresGatewayReload: boolean\n restartHint: string\n}\n\nexport interface DeleteHermesModelConfigResult extends ListHermesModelConfigsResult {\n backupPath: string | null\n requiresGatewayReload: boolean\n restartHint: string\n}\n\nexport interface SaveHermesModelDefaultsInput {\n taskModelId?: string\n compressionModelId?: string\n}\n\nexport interface SaveHermesModelDefaultsResult extends ListHermesModelConfigsResult {\n backupPath: string | null\n requiresGatewayReload: boolean\n restartHint: string\n}\n\nexport type HermesApprovalMode = 'manual' | 'smart' | 'off'\nexport type HermesCronApprovalMode = 'deny' | 'approve'\nexport type HermesPermissionRisk = 'low' | 'medium' | 'high'\n\nexport interface HermesProfilePermissionToolset {\n key: string\n label: string\n description: string\n risk: HermesPermissionRisk\n enabled: boolean\n requiresConfig: boolean\n configured: boolean\n}\n\nexport interface HermesProfilePermissions {\n profileName: string\n configPath: string\n approvals: {\n mode: HermesApprovalMode\n timeout: number\n cronMode: HermesCronApprovalMode\n }\n terminal: {\n backend: string\n cwd: string\n containerCpu: number | null\n containerMemory: number | null\n containerDisk: number | null\n containerPersistent: boolean\n }\n toolsets: {\n items: HermesProfilePermissionToolset[]\n mcpEnabled: boolean\n }\n commandAllowlist: string[]\n}\n\nexport interface SaveHermesProfilePermissionsInput {\n approvals?: {\n mode?: string\n timeout?: number\n cronMode?: string\n }\n terminal?: {\n backend?: string\n cwd?: string\n containerCpu?: number\n containerMemory?: number\n containerDisk?: number\n containerPersistent?: boolean\n }\n toolsets?: {\n enabledToolsets?: string[]\n mcpEnabled?: boolean\n }\n}\n\nexport interface SaveHermesProfilePermissionsResult extends HermesProfilePermissions {\n backupPath: string | null\n requiresGatewayReload: boolean\n restartHint: string\n}\n\nexport type HermesProfileToolConfigKey =\n | 'web'\n | 'image_gen'\n | 'stt'\n | 'tts'\n | 'messaging'\n | 'homeassistant'\n | 'rl'\n\nexport interface HermesProfileToolConfig {\n profileName: string\n configPath: string\n toolKey: HermesProfileToolConfigKey\n values: Record<string, string | boolean | null>\n configured: Record<string, boolean>\n}\n\nexport interface SaveHermesProfileToolConfigInput {\n values: Record<string, unknown>\n}\n\nexport interface SaveHermesProfileToolConfigResult extends HermesProfileToolConfig {\n backupPath: string | null\n requiresGatewayReload: boolean\n restartHint: string\n}\n\nexport interface EnsureHermesConfigResult {\n configPath: string\n apiServer: HermesApiServerConfig\n changed: boolean\n keyAdded: boolean\n enabledAdded: boolean\n hostAdded: boolean\n portAdded: boolean\n backupPath: string | null\n notice: string | null\n}\n\nexport const DEFAULT_HERMES_API_SERVER_HOST = '127.0.0.1'\nexport const DEFAULT_HERMES_API_SERVER_PORT = 8642\nconst PROFILE_API_SERVER_PORT_START = DEFAULT_HERMES_API_SERVER_PORT + 1\nconst PROFILE_API_SERVER_PORT_END = DEFAULT_HERMES_API_SERVER_PORT + 999\nconst MODEL_CONFIG_RESTART_HINT =\n '模型配置已保存。建议重载 Hermes Gateway,正在运行中的 Run 不会被中断,新的 Run 会读取最新配置。'\nconst MODEL_DEFAULTS_APPLIED_HINT =\n '默认模型设置已保存。新的 Run 会直接读取最新配置,无需重载 Hermes Gateway。'\nconst PROFILE_PERMISSIONS_RESTART_HINT =\n '权限配置已保存。后续以该 Profile 发起的新 Run 会读取最新配置;如果该 Profile 的 Gateway 已经在运行,需要重载对应 Gateway。'\nconst PROFILE_TOOL_CONFIG_RESTART_HINT =\n '工具后端配置已保存。后续以该 Profile 发起的新 Run 会读取最新配置;如果该 Profile 的 Gateway 已经在运行,需要重载对应 Gateway。'\ntype HermesYamlDocument = ReturnType<typeof YAML.parseDocument>\n\nconst REASONING_EFFORTS = [\n 'none',\n 'minimal',\n 'low',\n 'medium',\n 'high',\n 'xhigh',\n] as const satisfies readonly HermesReasoningEffort[]\n\nconst PROFILE_PERMISSION_TOOLSETS: Array<\n Omit<\n HermesProfilePermissionToolset,\n 'enabled' | 'requiresConfig' | 'configured'\n >\n> = [\n {\n key: 'web',\n label: 'Web 搜索',\n description: '联网搜索与网页内容提取',\n risk: 'low',\n },\n {\n key: 'vision',\n label: '视觉理解',\n description: '读取图片内容并参与推理',\n risk: 'low',\n },\n {\n key: 'image_gen',\n label: '图片生成',\n description: '调用图片生成后端',\n risk: 'low',\n },\n {\n key: 'browser',\n label: '浏览器自动化',\n description: '打开网页、点击、输入和读取页面',\n risk: 'medium',\n },\n {\n key: 'skills',\n label: 'Skills',\n description: '读取和管理 Hermes skills',\n risk: 'medium',\n },\n {\n key: 'memory',\n label: 'Memory',\n description: '读取和写入长期记忆',\n risk: 'medium',\n },\n {\n key: 'session_search',\n label: '会话搜索',\n description: '搜索历史会话与摘要',\n risk: 'medium',\n },\n {\n key: 'todo',\n label: '任务规划',\n description: '维护会话内任务列表',\n risk: 'medium',\n },\n {\n key: 'delegation',\n label: '子任务代理',\n description: '创建独立上下文的子 Agent',\n risk: 'medium',\n },\n {\n key: 'terminal',\n label: '终端执行',\n description: '执行 shell 命令和管理进程',\n risk: 'high',\n },\n {\n key: 'file',\n label: '文件读写',\n description: '读取、搜索、写入和 patch 文件',\n risk: 'high',\n },\n {\n key: 'code_execution',\n label: '代码执行',\n description: '在工具沙箱中执行代码片段',\n risk: 'high',\n },\n {\n key: 'cronjob',\n label: '定时任务',\n description: '创建、更新、暂停和运行 cron jobs',\n risk: 'high',\n },\n {\n key: 'messaging',\n label: '跨平台消息',\n description: '向 Telegram、Discord、Slack 等平台发消息',\n risk: 'high',\n },\n {\n key: 'homeassistant',\n label: '智能家居',\n description: '读取和控制 Home Assistant 设备',\n risk: 'high',\n },\n {\n key: 'stt',\n label: '语音转写 (STT)',\n description: '把用户语音消息转成文本输入',\n risk: 'medium',\n },\n {\n key: 'tts',\n label: '语音合成 (TTS)',\n description: '生成语音音频',\n risk: 'medium',\n },\n {\n key: 'moa',\n label: 'Mixture of Agents',\n description: '调用多 Agent 推理工具',\n risk: 'medium',\n },\n {\n key: 'rl',\n label: 'RL 训练',\n description: '管理强化学习训练任务',\n risk: 'high',\n },\n]\n\nconst PROFILE_PERMISSION_TOOLSET_KEYS = new Set(\n PROFILE_PERMISSION_TOOLSETS.map((toolset) => toolset.key),\n)\nconst API_SERVER_PROFILE_TOOLSET_KEYS = new Set(\n PROFILE_PERMISSION_TOOLSETS.filter((toolset) => toolset.key !== 'stt').map(\n (toolset) => toolset.key,\n ),\n)\nconst API_SERVER_DEFAULT_ENABLED_TOOLSETS = new Set([\n 'web',\n 'browser',\n 'terminal',\n 'file',\n 'code_execution',\n 'vision',\n 'image_gen',\n 'skills',\n 'todo',\n 'memory',\n 'session_search',\n 'delegation',\n 'cronjob',\n])\nconst PLATFORM_DEFAULT_TOOLSETS = new Set([\n 'hermes-api-server',\n 'hermes-bluebubbles',\n 'hermes-cli',\n 'hermes-dingtalk',\n 'hermes-discord',\n 'hermes-email',\n 'hermes-feishu',\n 'hermes-gateway',\n 'hermes-homeassistant',\n 'hermes-matrix',\n 'hermes-mattermost',\n 'hermes-qqbot',\n 'hermes-signal',\n 'hermes-slack',\n 'hermes-telegram',\n 'hermes-webhook',\n 'hermes-wecom',\n 'hermes-wecom-callback',\n 'hermes-weixin',\n 'hermes-whatsapp',\n])\nconst TERMINAL_BACKENDS = new Set([\n 'local',\n 'ssh',\n 'docker',\n 'singularity',\n 'modal',\n 'daytona',\n])\n\nlet profileApiServerPortAssignmentQueue: Promise<void> = Promise.resolve()\n\nexport function resolveHermesProfileDir(profileName = 'default'): string {\n const hermesHome = process.env.HERMES_HOME?.trim()\n if (hermesHome) {\n const resolvedHome = path.resolve(hermesHome)\n if (profileName === 'default') {\n return resolvedHome\n }\n return path.join(\n resolveDefaultHermesRoot(resolvedHome),\n 'profiles',\n profileName,\n )\n }\n if (profileName === 'default') {\n return path.join(os.homedir(), '.hermes')\n }\n return path.join(os.homedir(), '.hermes', 'profiles', profileName)\n}\n\nexport function resolveHermesConfigPath(profileName = 'default'): string {\n return path.join(resolveHermesProfileDir(profileName), 'config.yaml')\n}\n\nexport async function readHermesApiServerConfig(\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<HermesApiServerConfig> {\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n if (!existingRaw) {\n return applyEnvOverrides(\n {},\n await readHermesApiServerEnvOverrides(profileName),\n false,\n )\n }\n const config = toRecord(YAML.parse(existingRaw))\n const platforms = toRecord(config.platforms)\n const apiServer = toRecord(platforms.api_server)\n return applyEnvOverrides(\n readApiServerConfig(apiServer, true),\n await readHermesApiServerEnvOverrides(profileName),\n true,\n )\n}\n\nexport async function readHermesModelConfig(\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<HermesModelConfig> {\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n const config = existingRaw ? toRecord(YAML.parse(existingRaw)) : {}\n const modelConfig = readModelConfig(config.model)\n const envModel = process.env.HERMES_MODEL?.trim()\n return {\n ...modelConfig,\n model: envModel || modelConfig.model,\n reasoningEffort: readProfileReasoningEffort(config) ?? undefined,\n }\n}\n\nexport async function listHermesModelConfigs(\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<ListHermesModelConfigsResult> {\n const { config } = await readHermesConfigDocument(configPath)\n const env = await readHermesEnvFile(profileName)\n const defaultModel = readModelConfig(config.model).model ?? null\n const defaultReasoningEffort = readProfileReasoningEffort(config)\n const models = readManagedModelConfigs(\n config,\n env,\n defaultModel,\n defaultReasoningEffort,\n )\n const compressionModelId = readAuxiliaryCompressionModelId(config)\n return {\n ok: true,\n configPath,\n defaultModel,\n defaultReasoningEffort,\n compressionModelId,\n compressionModel: resolveCompressionModel(config, models),\n models,\n }\n}\n\nexport async function saveHermesModelConfig(\n input: SaveHermesModelConfigInput,\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<SaveHermesModelConfigResult> {\n const normalized = normalizeModelConfigInput(input)\n const shouldUpdateReasoningEffort = input.reasoningEffort !== undefined\n const { document, config, existingRaw } =\n await readHermesConfigDocument(configPath)\n const customProviders = ensureCustomProvidersList(config)\n const originalModelId = input.originalModelId?.trim() || normalized.id\n const index = findCustomProviderIndex(customProviders, originalModelId)\n const entry = index >= 0 ? toRecord(customProviders[index]) : {}\n const existingKeyEnv =\n readString(entry.key_env) ?? parseEnvReference(readString(entry.api_key))\n const keyEnv =\n normalized.keyEnv ??\n existingKeyEnv ??\n (normalized.apiKey\n ? buildApiKeyEnvName(normalized.providerName, normalized.id)\n : undefined)\n\n if (normalized.apiKey && keyEnv) {\n await writeHermesEnvValue(profileName, keyEnv, normalized.apiKey)\n }\n\n entry.name = normalized.providerName\n entry.provider_key = normalized.provider\n entry.base_url = normalized.baseUrl\n entry.model = normalized.id\n if (normalized.apiMode) {\n entry.api_mode = normalized.apiMode\n } else {\n delete entry.api_mode\n }\n if (normalized.contextLength) {\n entry.context_length = normalized.contextLength\n } else {\n delete entry.context_length\n }\n if (keyEnv) {\n entry.key_env = keyEnv\n delete entry.api_key\n } else {\n delete entry.key_env\n }\n updateEntryModels(entry, originalModelId, normalized.id)\n if (shouldUpdateReasoningEffort) {\n writeEntryModelReasoningEffort(\n entry,\n normalized.id,\n normalized.reasoningEffort,\n )\n }\n\n if (index >= 0) {\n customProviders[index] = entry\n } else {\n customProviders.push(entry)\n }\n\n const modelConfig = ensureRecord(config, 'model')\n const currentDefaultConfig = readModelConfig(modelConfig)\n const currentDefault = currentDefaultConfig.model\n const currentDefaultReasoningEffort = readProfileReasoningEffort(config)\n if (\n normalized.setDefault ||\n !currentDefault ||\n currentDefault === originalModelId\n ) {\n if (\n normalized.setDefault &&\n currentDefault &&\n currentDefault !== normalized.id &&\n currentDefault !== originalModelId\n ) {\n retainModelDefaultAsCustomProvider(customProviders, {\n ...currentDefaultConfig,\n ...(currentDefaultReasoningEffort\n ? { reasoningEffort: currentDefaultReasoningEffort }\n : {}),\n })\n }\n const defaultKeyEnv =\n keyEnv ??\n (currentDefault === originalModelId\n ? currentDefaultConfig.keyEnv\n : undefined)\n const defaultApiKey =\n normalized.apiKey ??\n (!defaultKeyEnv && currentDefault === originalModelId\n ? currentDefaultConfig.apiKey\n : undefined)\n writeDefaultModelConfig(modelConfig, {\n ...normalized,\n apiKey: defaultApiKey,\n keyEnv: defaultKeyEnv,\n })\n if (shouldUpdateReasoningEffort && normalized.reasoningEffort) {\n writeProfileReasoningEffort(config, normalized.reasoningEffort)\n }\n }\n\n const backupPath = await writeHermesConfigDocument({\n configPath,\n document,\n config,\n existingRaw,\n })\n const listed = await listHermesModelConfigs(profileName, configPath)\n const savedModel = listed.models.find((model) => model.id === normalized.id)\n if (!savedModel) {\n throw new Error('saved model is missing from config')\n }\n return {\n ...listed,\n model: savedModel,\n backupPath,\n requiresGatewayReload: true,\n restartHint: MODEL_CONFIG_RESTART_HINT,\n }\n}\n\nexport async function deleteHermesModelConfig(\n modelId: string,\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<DeleteHermesModelConfigResult> {\n const id = modelId.trim()\n if (!id) {\n throw new Error('model id is required')\n }\n const { document, config, existingRaw } =\n await readHermesConfigDocument(configPath)\n const env = await readHermesEnvFile(profileName)\n const existingModels = readManagedModelConfigs(\n config,\n env,\n readModelConfig(config.model).model ?? null,\n readProfileReasoningEffort(config),\n )\n if (!existingModels.some((model) => model.id === id)) {\n throw new Error(`model \"${id}\" is not configured`)\n }\n if (existingModels.length <= 1) {\n throw new Error(\n '至少需要保留一个模型,避免 Hermes Agent 没有可用默认模型。',\n )\n }\n\n const customProviders = ensureCustomProvidersList(config)\n const nextProviders = customProviders\n .map((entry) => removeModelFromCustomProvider(toRecord(entry), id))\n .filter((entry): entry is Record<string, unknown> => entry !== null)\n config.custom_providers = nextProviders\n\n const modelConfig = ensureRecord(config, 'model')\n const currentDefault = readModelConfig(modelConfig).model\n if (currentDefault === id) {\n const nextDefault = readManagedModelConfigs(\n config,\n env,\n null,\n readProfileReasoningEffort(config),\n )[0]\n if (nextDefault) {\n writeDefaultModelConfig(modelConfig, {\n id: nextDefault.id,\n provider: nextDefault.provider,\n baseUrl: nextDefault.baseUrl,\n apiMode: nextDefault.apiMode,\n contextLength: nextDefault.contextLength,\n keyEnv: nextDefault.keyEnv,\n })\n if (nextDefault.reasoningEffort) {\n writeProfileReasoningEffort(config, nextDefault.reasoningEffort)\n }\n } else {\n delete modelConfig.default\n delete modelConfig.model\n delete modelConfig.name\n delete modelConfig.provider\n delete modelConfig.base_url\n delete modelConfig.api_key\n delete modelConfig.key_env\n delete modelConfig.api_mode\n delete modelConfig.context_length\n }\n }\n\n const backupPath = await writeHermesConfigDocument({\n configPath,\n document,\n config,\n existingRaw,\n })\n const listed = await listHermesModelConfigs(profileName, configPath)\n return {\n ...listed,\n backupPath,\n requiresGatewayReload: true,\n restartHint: MODEL_CONFIG_RESTART_HINT,\n }\n}\n\nexport async function saveHermesModelDefaults(\n input: SaveHermesModelDefaultsInput,\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<SaveHermesModelDefaultsResult> {\n const taskModelId = input.taskModelId?.trim()\n const compressionModelId = input.compressionModelId?.trim()\n if (!taskModelId && !compressionModelId) {\n throw new Error('taskModelId or compressionModelId is required')\n }\n\n const { document, config, existingRaw } =\n await readHermesConfigDocument(configPath)\n const env = await readHermesEnvFile(profileName)\n\n if (taskModelId) {\n const models = readManagedModelConfigs(\n config,\n env,\n readModelConfig(config.model).model ?? null,\n readProfileReasoningEffort(config),\n )\n const selected = findManagedModelById(models, taskModelId)\n if (!selected) {\n throw new Error(`model \"${taskModelId}\" is not configured`)\n }\n\n const customProviders = ensureCustomProvidersList(config)\n const modelConfig = ensureRecord(config, 'model')\n const currentDefaultConfig = readModelConfig(modelConfig)\n const currentDefaultReasoningEffort = readProfileReasoningEffort(config)\n if (\n currentDefaultConfig.model &&\n currentDefaultConfig.model !== selected.id\n ) {\n retainModelDefaultAsCustomProvider(customProviders, {\n ...currentDefaultConfig,\n ...(currentDefaultReasoningEffort\n ? { reasoningEffort: currentDefaultReasoningEffort }\n : {}),\n })\n }\n\n writeDefaultModelConfig(modelConfig, {\n id: selected.id,\n provider: selected.provider,\n baseUrl: selected.baseUrl,\n apiMode: selected.apiMode,\n contextLength: selected.contextLength,\n keyEnv: selected.keyEnv,\n })\n if (selected.reasoningEffort) {\n writeProfileReasoningEffort(config, selected.reasoningEffort)\n }\n }\n\n if (compressionModelId) {\n const models = readManagedModelConfigs(\n config,\n env,\n readModelConfig(config.model).model ?? null,\n readProfileReasoningEffort(config),\n )\n const selected = findManagedModelById(models, compressionModelId)\n if (!selected) {\n throw new Error(`model \"${compressionModelId}\" is not configured`)\n }\n writeAuxiliaryCompressionModelConfig(config, selected, env)\n }\n\n const backupPath = await writeHermesConfigDocument({\n configPath,\n document,\n config,\n existingRaw,\n })\n const listed = await listHermesModelConfigs(profileName, configPath)\n return {\n ...listed,\n backupPath,\n requiresGatewayReload: false,\n restartHint: MODEL_DEFAULTS_APPLIED_HINT,\n }\n}\n\nexport async function readHermesProfilePermissions(\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<HermesProfilePermissions> {\n const { config } = await readHermesConfigDocument(configPath)\n const env = await readHermesEnvFile(profileName)\n return profilePermissionsFromConfig(profileName, configPath, config, env)\n}\n\nexport async function saveHermesProfilePermissions(\n profileName: string,\n input: SaveHermesProfilePermissionsInput,\n configPath = resolveHermesConfigPath(profileName),\n): Promise<SaveHermesProfilePermissionsResult> {\n const { document, config, existingRaw } =\n await readHermesConfigDocument(configPath)\n\n if (input.approvals) {\n const approvals = ensureRecord(config, 'approvals')\n if (input.approvals.mode !== undefined) {\n approvals.mode = normalizeApprovalMode(input.approvals.mode)\n }\n if (input.approvals.timeout !== undefined) {\n approvals.timeout = normalizePositiveInteger(\n input.approvals.timeout,\n 'approvals.timeout',\n )\n }\n if (input.approvals.cronMode !== undefined) {\n approvals.cron_mode = normalizeCronApprovalMode(input.approvals.cronMode)\n }\n }\n\n if (input.terminal) {\n const terminal = ensureRecord(config, 'terminal')\n if (input.terminal.backend !== undefined) {\n terminal.backend = normalizeTerminalBackend(input.terminal.backend)\n }\n if (input.terminal.cwd !== undefined) {\n terminal.cwd = normalizeNonEmptyString(input.terminal.cwd, 'terminal.cwd')\n }\n if (input.terminal.containerCpu !== undefined) {\n terminal.container_cpu = normalizePositiveInteger(\n input.terminal.containerCpu,\n 'terminal.container_cpu',\n )\n }\n if (input.terminal.containerMemory !== undefined) {\n terminal.container_memory = normalizePositiveInteger(\n input.terminal.containerMemory,\n 'terminal.container_memory',\n )\n }\n if (input.terminal.containerDisk !== undefined) {\n terminal.container_disk = normalizePositiveInteger(\n input.terminal.containerDisk,\n 'terminal.container_disk',\n )\n }\n if (input.terminal.containerPersistent !== undefined) {\n terminal.container_persistent = input.terminal.containerPersistent\n }\n }\n\n if (input.toolsets) {\n const env = await readHermesEnvFile(profileName)\n const currentPermissions = profilePermissionsFromConfig(\n profileName,\n configPath,\n config,\n env,\n )\n const platformToolsets = ensureRecord(config, 'platform_toolsets')\n const existing = readStringList(platformToolsets.api_server)\n const enabled = (\n input.toolsets.enabledToolsets ??\n currentPermissions.toolsets.items\n .filter((toolset) => toolset.enabled)\n .map((toolset) => toolset.key)\n ).map((toolset) => normalizeToolsetKey(toolset))\n const preserved = existing.filter(\n (entry) =>\n !PROFILE_PERMISSION_TOOLSET_KEYS.has(entry) &&\n !PLATFORM_DEFAULT_TOOLSETS.has(entry) &&\n entry !== 'no_mcp',\n )\n const next = [\n ...PROFILE_PERMISSION_TOOLSETS.filter(\n (toolset) => toolset.key !== 'stt' && enabled.includes(toolset.key),\n ).map((toolset) => toolset.key),\n ...preserved,\n ]\n const stt = ensureRecord(config, 'stt')\n stt.enabled = enabled.includes('stt')\n const mcpEnabled =\n input.toolsets.mcpEnabled ?? currentPermissions.toolsets.mcpEnabled\n if (!mcpEnabled) {\n next.push('no_mcp')\n }\n platformToolsets.api_server = next\n }\n\n const backupPath = await writeHermesConfigDocument({\n configPath,\n document,\n config,\n existingRaw,\n })\n return {\n ...(await readHermesProfilePermissions(profileName, configPath)),\n backupPath,\n requiresGatewayReload: true,\n restartHint: PROFILE_PERMISSIONS_RESTART_HINT,\n }\n}\n\nexport async function readHermesProfileToolConfig(\n profileName: string,\n toolKey: string,\n configPath = resolveHermesConfigPath(profileName),\n): Promise<HermesProfileToolConfig> {\n const normalizedToolKey = normalizeProfileToolConfigKey(toolKey)\n const { config } = await readHermesConfigDocument(configPath)\n const env = await readHermesEnvFile(profileName)\n return profileToolConfigFromSources(\n profileName,\n configPath,\n normalizedToolKey,\n config,\n env,\n )\n}\n\nexport async function saveHermesProfileToolConfig(\n profileName: string,\n toolKey: string,\n input: SaveHermesProfileToolConfigInput,\n configPath = resolveHermesConfigPath(profileName),\n): Promise<SaveHermesProfileToolConfigResult> {\n const normalizedToolKey = normalizeProfileToolConfigKey(toolKey)\n const { document, config, existingRaw } =\n await readHermesConfigDocument(configPath)\n let configTouched = false\n\n switch (normalizedToolKey) {\n case 'web':\n configTouched = applyWebToolConfig(config, input.values)\n await writeToolConfigEnvValues(profileName, input.values, [\n 'FIRECRAWL_API_KEY',\n 'FIRECRAWL_API_URL',\n 'TAVILY_API_KEY',\n 'EXA_API_KEY',\n 'PARALLEL_API_KEY',\n ])\n break\n case 'image_gen':\n configTouched = applyImageGenToolConfig(config, input.values)\n await writeToolConfigEnvValues(profileName, input.values, [\n 'FAL_KEY',\n 'OPENAI_API_KEY',\n 'XAI_API_KEY',\n ])\n break\n case 'stt':\n configTouched = applySttToolConfig(\n config,\n input.values,\n await readHermesEnvFile(profileName),\n )\n await writeToolConfigEnvValues(profileName, input.values, [\n 'GROQ_API_KEY',\n 'VOICE_TOOLS_OPENAI_KEY',\n 'OPENAI_API_KEY',\n 'MISTRAL_API_KEY',\n 'XAI_API_KEY',\n 'HERMES_LOCAL_STT_COMMAND',\n 'HERMES_LOCAL_STT_LANGUAGE',\n 'STT_GROQ_MODEL',\n 'STT_OPENAI_MODEL',\n 'STT_MISTRAL_MODEL',\n 'STT_OPENAI_BASE_URL',\n 'GROQ_BASE_URL',\n 'XAI_STT_BASE_URL',\n ])\n break\n case 'tts':\n configTouched = applyTtsToolConfig(config, input.values)\n await writeToolConfigEnvValues(profileName, input.values, [\n 'VOICE_TOOLS_OPENAI_KEY',\n 'OPENAI_API_KEY',\n 'ELEVENLABS_API_KEY',\n 'MINIMAX_API_KEY',\n 'MISTRAL_API_KEY',\n 'GEMINI_API_KEY',\n 'XAI_API_KEY',\n ])\n break\n case 'messaging':\n await writeToolConfigEnvValues(profileName, input.values, [\n 'TELEGRAM_BOT_TOKEN',\n 'TELEGRAM_ALLOWED_USERS',\n 'TELEGRAM_HOME_CHANNEL',\n 'DISCORD_BOT_TOKEN',\n 'DISCORD_ALLOWED_USERS',\n 'DISCORD_HOME_CHANNEL',\n 'SLACK_BOT_TOKEN',\n 'SLACK_APP_TOKEN',\n 'SLACK_ALLOWED_USERS',\n 'SLACK_HOME_CHANNEL',\n ])\n break\n case 'homeassistant':\n await writeToolConfigEnvValues(profileName, input.values, [\n 'HASS_URL',\n 'HASS_TOKEN',\n ])\n break\n case 'rl':\n await writeToolConfigEnvValues(profileName, input.values, [\n 'TINKER_API_KEY',\n 'WANDB_API_KEY',\n 'WANDB_ENTITY',\n ])\n break\n }\n\n const backupPath = configTouched\n ? await writeHermesConfigDocument({\n configPath,\n document,\n config,\n existingRaw,\n })\n : null\n return {\n ...(await readHermesProfileToolConfig(\n profileName,\n normalizedToolKey,\n configPath,\n )),\n backupPath,\n requiresGatewayReload: true,\n restartHint: PROFILE_TOOL_CONFIG_RESTART_HINT,\n }\n}\n\nexport async function ensureHermesApiServerKey(\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<EnsureHermesConfigResult> {\n return ensureHermesApiServerConfig(profileName, configPath)\n}\n\nexport async function ensureHermesApiServerConfig(\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<EnsureHermesConfigResult> {\n if (profileName !== 'default') {\n return withProfileApiServerPortAssignmentLock(() =>\n ensureHermesApiServerConfigUnlocked(profileName, configPath),\n )\n }\n return ensureHermesApiServerConfigUnlocked(profileName, configPath)\n}\n\nasync function ensureHermesApiServerConfigUnlocked(\n profileName = 'default',\n configPath = resolveHermesConfigPath(profileName),\n): Promise<EnsureHermesConfigResult> {\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n const document = existingRaw\n ? YAML.parseDocument(existingRaw)\n : new YAML.Document({})\n const config = toRecord(document.toJSON())\n const platforms = ensureRecord(config, 'platforms')\n const apiServer = ensureRecord(platforms, 'api_server')\n const extra = ensureRecord(apiServer, 'extra')\n const configOnly = readApiServerConfig(apiServer)\n const envOverrides = await readHermesApiServerEnvOverrides(profileName)\n const before = applyEnvOverrides(configOnly, envOverrides, false)\n const beforeKey = before.key?.trim() ? before.key : null\n const beforeEnabled = before.enabled === true\n const beforeHost = before.host?.trim() ? before.host : null\n const beforePort =\n typeof before.port === 'number' && Number.isFinite(before.port)\n ? before.port\n : null\n\n let changed = false\n let enabledAdded = false\n let hostAdded = false\n let portAdded = false\n let assignedPort: number | null = null\n if (!beforeEnabled) {\n apiServer.enabled = true\n enabledAdded = true\n changed = true\n }\n if (!beforeHost) {\n extra.host = DEFAULT_HERMES_API_SERVER_HOST\n hostAdded = true\n changed = true\n }\n if (shouldAssignDedicatedProfileApiServerPort(profileName, configOnly.port)) {\n assignedPort = await nextProfileApiServerPort(profileName)\n extra.port = assignedPort\n portAdded = true\n changed = true\n } else if (!beforePort) {\n assignedPort = DEFAULT_HERMES_API_SERVER_PORT\n extra.port = assignedPort\n portAdded = true\n changed = true\n }\n if (!beforeKey) {\n extra.key = randomBytes(32).toString('base64url')\n changed = true\n }\n\n if (!changed) {\n return {\n configPath,\n apiServer: applyEnvOverrides(\n readApiServerConfig(apiServer, true),\n envOverrides,\n true,\n ),\n changed: false,\n keyAdded: false,\n enabledAdded: false,\n hostAdded: false,\n portAdded: false,\n backupPath: null,\n notice: null,\n }\n }\n\n const backupPath = existingRaw ? `${configPath}.bak.${Date.now()}` : null\n await mkdir(path.dirname(configPath), { recursive: true, mode: 0o700 })\n if (backupPath) {\n await copyFile(configPath, backupPath)\n }\n document.contents = document.createNode(config)\n await writeFile(configPath, document.toString(), { mode: 0o600 })\n\n return {\n configPath,\n apiServer: applyEnvOverrides(\n readApiServerConfig(apiServer, true),\n envOverrides,\n true,\n ),\n changed: true,\n keyAdded: !beforeKey,\n enabledAdded,\n hostAdded,\n portAdded,\n backupPath,\n notice: buildNotice({\n keyAdded: !beforeKey,\n enabledAdded,\n hostAdded,\n portAdded,\n port: assignedPort ?? beforePort ?? undefined,\n }),\n }\n}\n\nasync function readHermesConfigDocument(configPath: string): Promise<{\n document: HermesYamlDocument\n config: Record<string, unknown>\n existingRaw: string | null\n}> {\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n const document = (\n existingRaw ? YAML.parseDocument(existingRaw) : new YAML.Document({})\n ) as HermesYamlDocument\n return {\n document,\n config: toRecord(document.toJSON()),\n existingRaw,\n }\n}\n\nasync function writeHermesConfigDocument(input: {\n configPath: string\n document: HermesYamlDocument\n config: Record<string, unknown>\n existingRaw: string | null\n}): Promise<string | null> {\n const backupPath = input.existingRaw\n ? `${input.configPath}.bak.${Date.now()}`\n : null\n await mkdir(path.dirname(input.configPath), { recursive: true, mode: 0o700 })\n if (backupPath) {\n await copyFile(input.configPath, backupPath)\n }\n input.document.contents = input.document.createNode(input.config)\n const tempPath = `${input.configPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, input.document.toString(), { mode: 0o600 })\n await rename(tempPath, input.configPath)\n return backupPath\n}\n\nfunction readManagedModelConfigs(\n config: Record<string, unknown>,\n env: Record<string, string>,\n defaultModel: string | null,\n defaultReasoningEffort: HermesReasoningEffort | null,\n): HermesManagedModelConfig[] {\n const models: HermesManagedModelConfig[] = []\n const seen = new Set<string>()\n const seenEndpoint = new Map<string, number>()\n const modelConfig = readModelConfig(config.model)\n const customProviders = Array.isArray(config.custom_providers)\n ? config.custom_providers\n : []\n\n for (const rawEntry of customProviders) {\n const entry = toRecord(rawEntry)\n const providerName =\n readString(entry.name) ??\n readString(entry.provider_name) ??\n readString(entry.provider_key) ??\n 'Custom Provider'\n const provider =\n readString(entry.provider_key) ?? readString(entry.provider) ?? 'custom'\n const baseUrl =\n readString(entry.base_url) ??\n readString(entry.url) ??\n readString(entry.api) ??\n ''\n const apiMode = inferApiMode(provider, baseUrl, readString(entry.api_mode))\n const contextLength = readPositiveInteger(entry.context_length)\n const keyEnv =\n readString(entry.key_env) ?? parseEnvReference(readString(entry.api_key))\n const credentialState = readCredentialState(entry, env)\n\n for (const id of readEntryModelIds(entry)) {\n const key = modelConfigKey(provider, baseUrl, id)\n if (seen.has(key)) {\n continue\n }\n seen.add(key)\n const endpointKey = modelEndpointKey(baseUrl, id)\n const modelContextLength =\n readEntryModelContextLength(entry, id) ?? contextLength\n const reasoningEffort = readEntryModelReasoningEffort(entry, id)\n const reasoningMetadata = modelReasoningMetadata({\n provider,\n baseUrl,\n modelId: id,\n apiMode,\n })\n models.push({\n id,\n provider,\n providerName,\n source: 'custom_provider',\n baseUrl,\n apiMode,\n ...(modelContextLength ? { contextLength: modelContextLength } : {}),\n ...(keyEnv ? { keyEnv } : {}),\n credentialConfigured: credentialState === 'configured',\n credentialState,\n isDefault: id === defaultModel,\n ...(reasoningEffort ? { reasoningEffort } : {}),\n ...reasoningMetadata,\n })\n seenEndpoint.set(endpointKey, models.length - 1)\n }\n }\n\n if (defaultModel) {\n const provider = modelConfig.provider ?? 'default'\n const baseUrl = modelConfig.baseUrl ?? ''\n const endpointMatchIndex = seenEndpoint.get(\n modelEndpointKey(baseUrl, defaultModel),\n )\n if (endpointMatchIndex !== undefined) {\n const existing = models[endpointMatchIndex]\n models[endpointMatchIndex] = {\n ...existing,\n apiMode: modelConfig.apiMode\n ? inferApiMode(provider, baseUrl, modelConfig.apiMode)\n : existing.apiMode,\n contextLength: existing.contextLength ?? modelConfig.contextLength,\n keyEnv: existing.keyEnv ?? modelConfig.keyEnv,\n isDefault: true,\n reasoningEffort:\n existing.reasoningEffort ?? defaultReasoningEffort ?? undefined,\n }\n return models.sort(\n (left, right) => Number(right.isDefault) - Number(left.isDefault),\n )\n }\n\n const key = modelConfigKey(provider, baseUrl, defaultModel)\n if (!seen.has(key)) {\n const credentialState = readModelCredentialState(modelConfig, env)\n const reasoningEffort =\n modelConfig.reasoningEffort ?? defaultReasoningEffort\n models.unshift({\n id: defaultModel,\n provider,\n providerName: provider,\n source: 'model_default',\n baseUrl,\n apiMode: inferApiMode(provider, baseUrl, modelConfig.apiMode),\n ...(modelConfig.contextLength\n ? { contextLength: modelConfig.contextLength }\n : {}),\n ...(modelConfig.keyEnv ? { keyEnv: modelConfig.keyEnv } : {}),\n credentialConfigured: credentialState === 'configured',\n credentialState,\n isDefault: true,\n ...(reasoningEffort ? { reasoningEffort } : {}),\n ...modelReasoningMetadata({\n provider,\n baseUrl,\n modelId: defaultModel,\n apiMode: inferApiMode(provider, baseUrl, modelConfig.apiMode),\n }),\n })\n }\n }\n\n return models.sort(\n (left, right) => Number(right.isDefault) - Number(left.isDefault),\n )\n}\n\nfunction readAuxiliaryCompressionModelId(\n config: Record<string, unknown>,\n): string | null {\n const auxiliary = toRecord(config.auxiliary)\n const compression = toRecord(auxiliary.compression)\n return readString(compression.model) ?? null\n}\n\nfunction resolveCompressionModel(\n config: Record<string, unknown>,\n models: HermesManagedModelConfig[],\n): HermesManagedModelConfig | null {\n const auxiliary = toRecord(config.auxiliary)\n const compression = toRecord(auxiliary.compression)\n const modelId = readString(compression.model)\n if (!modelId) {\n return null\n }\n const provider = readString(compression.provider)\n const baseUrl = readString(compression.base_url)\n const apiMode = readString(compression.api_mode)\n return (\n models.find((model) => {\n if (model.id !== modelId) {\n return false\n }\n if (provider && model.provider !== provider) {\n return false\n }\n if (baseUrl && model.baseUrl !== baseUrl) {\n return false\n }\n if (apiMode && model.apiMode !== apiMode) {\n return false\n }\n return true\n }) ??\n models.find((model) => model.id === modelId) ??\n null\n )\n}\n\nfunction findManagedModelById(\n models: HermesManagedModelConfig[],\n id: string,\n): HermesManagedModelConfig | undefined {\n return models.find((model) => model.id === id)\n}\n\nfunction writeAuxiliaryCompressionModelConfig(\n config: Record<string, unknown>,\n model: HermesManagedModelConfig,\n env: Record<string, string>,\n): void {\n const auxiliary = ensureRecord(config, 'auxiliary')\n const compression = ensureRecord(auxiliary, 'compression')\n compression.provider = model.provider || 'auto'\n compression.model = model.id\n compression.api_mode = model.apiMode\n if (model.contextLength) {\n compression.context_length = model.contextLength\n } else {\n delete compression.context_length\n }\n\n if (model.provider === 'custom') {\n compression.base_url = model.baseUrl\n const apiKey = resolveManagedModelApiKey(config, env, model)\n if (apiKey) {\n compression.api_key = apiKey\n } else {\n delete compression.api_key\n }\n return\n }\n\n delete compression.base_url\n delete compression.api_key\n}\n\nfunction resolveManagedModelApiKey(\n config: Record<string, unknown>,\n env: Record<string, string>,\n model: HermesManagedModelConfig,\n): string | undefined {\n const defaultConfig = readModelConfig(config.model)\n if (\n defaultConfig.model === model.id &&\n (defaultConfig.provider ?? 'default') === model.provider &&\n (defaultConfig.baseUrl ?? '') === model.baseUrl\n ) {\n const defaultKey = resolveConfiguredApiKey(\n defaultConfig.apiKey,\n defaultConfig.keyEnv,\n env,\n )\n if (defaultKey) {\n return defaultKey\n }\n }\n\n const customProviders = Array.isArray(config.custom_providers)\n ? config.custom_providers\n : []\n for (const rawEntry of customProviders) {\n const entry = toRecord(rawEntry)\n const provider =\n readString(entry.provider_key) ?? readString(entry.provider) ?? 'custom'\n const baseUrl =\n readString(entry.base_url) ??\n readString(entry.url) ??\n readString(entry.api) ??\n ''\n if (\n provider === model.provider &&\n baseUrl === model.baseUrl &&\n readEntryModelIds(entry).includes(model.id)\n ) {\n const apiKey = readString(entry.api_key)\n const keyEnv = readString(entry.key_env) ?? parseEnvReference(apiKey)\n return resolveConfiguredApiKey(apiKey, keyEnv, env)\n }\n }\n return undefined\n}\n\nfunction resolveConfiguredApiKey(\n apiKey: string | undefined,\n keyEnv: string | undefined,\n env: Record<string, string>,\n): string | undefined {\n if (apiKey && !parseEnvReference(apiKey)) {\n return apiKey\n }\n if (keyEnv) {\n return env[keyEnv]?.trim() || undefined\n }\n return undefined\n}\n\nfunction normalizeModelConfigInput(input: SaveHermesModelConfigInput): Required<\n Pick<SaveHermesModelConfigInput, 'id' | 'provider' | 'baseUrl'>\n> &\n Omit<SaveHermesModelConfigInput, 'id' | 'provider' | 'baseUrl'> & {\n providerName: string\n } {\n const id = input.id.trim()\n const provider = input.provider.trim()\n const baseUrl = input.baseUrl.trim()\n if (!id || !provider || !baseUrl) {\n throw new Error('model id, provider and baseUrl are required')\n }\n if (\n input.contextLength !== undefined &&\n (!Number.isFinite(input.contextLength) || input.contextLength <= 0)\n ) {\n throw new Error('contextLength must be a positive integer')\n }\n const rawReasoningEffort = input.reasoningEffort?.trim()\n const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort)\n if (rawReasoningEffort && !reasoningEffort) {\n throw new Error(\n 'reasoningEffort must be none, minimal, low, medium, high or xhigh',\n )\n }\n return {\n ...input,\n id,\n provider,\n providerName: input.providerName?.trim() || provider,\n baseUrl,\n apiKey: input.apiKey?.trim() || undefined,\n apiMode: input.apiMode?.trim() || 'chat_completions',\n keyEnv: input.keyEnv?.trim() || undefined,\n contextLength: input.contextLength\n ? Math.floor(input.contextLength)\n : undefined,\n ...(reasoningEffort ? { reasoningEffort } : {}),\n }\n}\n\nfunction ensureCustomProvidersList(\n config: Record<string, unknown>,\n): Record<string, unknown>[] {\n const existing = config.custom_providers\n if (Array.isArray(existing)) {\n return existing as Record<string, unknown>[]\n }\n const next: Record<string, unknown>[] = []\n config.custom_providers = next\n return next\n}\n\nfunction retainModelDefaultAsCustomProvider(\n entries: Record<string, unknown>[],\n model: HermesModelConfig,\n): void {\n const id = model.model?.trim()\n if (!id) {\n return\n }\n const provider = model.provider?.trim() || 'default'\n const baseUrl = model.baseUrl?.trim() || ''\n const key = modelConfigKey(provider, baseUrl, id)\n const exists = entries.some((entry) => {\n const record = toRecord(entry)\n const entryProvider =\n readString(record.provider_key) ?? readString(record.provider) ?? 'custom'\n const entryBaseUrl =\n readString(record.base_url) ??\n readString(record.url) ??\n readString(record.api) ??\n ''\n return readEntryModelIds(record).some(\n (modelId) => modelConfigKey(entryProvider, entryBaseUrl, modelId) === key,\n )\n })\n if (exists) {\n return\n }\n\n const entry: Record<string, unknown> = {\n name: provider,\n provider_key: provider,\n base_url: baseUrl,\n api_mode: inferApiMode(provider, baseUrl, model.apiMode),\n model: id,\n }\n if (model.contextLength) {\n entry.context_length = model.contextLength\n }\n if (model.reasoningEffort) {\n entry.reasoning_effort = model.reasoningEffort\n }\n if (model.keyEnv) {\n entry.key_env = model.keyEnv\n } else if (model.apiKey) {\n entry.api_key = model.apiKey\n }\n entries.push(entry)\n}\n\nfunction writeDefaultModelConfig(\n modelConfig: Record<string, unknown>,\n model: Pick<SaveHermesModelConfigInput, 'id' | 'provider' | 'baseUrl'> &\n Pick<\n Partial<SaveHermesModelConfigInput>,\n 'apiKey' | 'apiMode' | 'contextLength' | 'keyEnv'\n >,\n): void {\n modelConfig.default = model.id\n modelConfig.provider = model.provider\n modelConfig.base_url = model.baseUrl\n if (model.keyEnv) {\n modelConfig.api_key = `\\${${model.keyEnv}}`\n delete modelConfig.key_env\n } else if (model.apiKey) {\n modelConfig.api_key = model.apiKey\n delete modelConfig.key_env\n } else {\n delete modelConfig.api_key\n delete modelConfig.key_env\n }\n modelConfig.api_mode = inferApiMode(\n model.provider,\n model.baseUrl,\n model.apiMode,\n )\n if (model.contextLength) {\n modelConfig.context_length = model.contextLength\n } else {\n delete modelConfig.context_length\n }\n}\n\nfunction findCustomProviderIndex(\n entries: Record<string, unknown>[],\n modelId: string,\n): number {\n return entries.findIndex((entry) =>\n readEntryModelIds(toRecord(entry)).includes(modelId),\n )\n}\n\nfunction updateEntryModels(\n entry: Record<string, unknown>,\n originalModelId: string,\n nextModelId: string,\n): void {\n const models = entry.models\n if (Array.isArray(models)) {\n const next = models\n .map((value) => (value === originalModelId ? nextModelId : value))\n .filter(\n (value): value is string =>\n typeof value === 'string' && value.trim().length > 0,\n )\n if (!next.includes(nextModelId)) {\n next.unshift(nextModelId)\n }\n entry.models = Array.from(new Set(next))\n return\n }\n if (\n typeof models === 'object' &&\n models !== null &&\n originalModelId !== nextModelId &&\n originalModelId in models\n ) {\n const record = models as Record<string, unknown>\n record[nextModelId] = record[originalModelId]\n delete record[originalModelId]\n }\n}\n\nfunction removeModelFromCustomProvider(\n entry: Record<string, unknown>,\n modelId: string,\n): Record<string, unknown> | null {\n if (\n readString(entry.model) === modelId ||\n readString(entry.default_model) === modelId\n ) {\n delete entry.model\n delete entry.default_model\n }\n\n const models = entry.models\n if (Array.isArray(models)) {\n entry.models = models.filter((value) => value !== modelId)\n } else if (typeof models === 'object' && models !== null) {\n delete (models as Record<string, unknown>)[modelId]\n }\n\n const remainingModels = readEntryModelIds(entry)\n if (remainingModels.length > 0) {\n entry.model = readString(entry.model) ?? remainingModels[0]\n return entry\n }\n return null\n}\n\nfunction readEntryModelIds(entry: Record<string, unknown>): string[] {\n const ids: string[] = []\n for (const value of [entry.model, entry.default_model]) {\n if (typeof value === 'string' && value.trim()) {\n ids.push(value.trim())\n }\n }\n const models = entry.models\n if (Array.isArray(models)) {\n for (const value of models) {\n if (typeof value === 'string' && value.trim()) {\n ids.push(value.trim())\n }\n }\n } else if (typeof models === 'object' && models !== null) {\n ids.push(\n ...Object.keys(models)\n .map((key) => key.trim())\n .filter(Boolean),\n )\n }\n return Array.from(new Set(ids))\n}\n\nfunction readEntryModelContextLength(\n entry: Record<string, unknown>,\n modelId: string,\n): number | undefined {\n const models = entry.models\n if (typeof models !== 'object' || models === null || Array.isArray(models)) {\n return undefined\n }\n const modelConfig = toRecord((models as Record<string, unknown>)[modelId])\n return readPositiveInteger(\n modelConfig.context_length ?? modelConfig.contextLength,\n )\n}\n\nfunction readEntryModelReasoningEffort(\n entry: Record<string, unknown>,\n modelId: string,\n): HermesReasoningEffort | undefined {\n const models = entry.models\n if (typeof models === 'object' && models !== null && !Array.isArray(models)) {\n const modelConfig = toRecord((models as Record<string, unknown>)[modelId])\n const modelReasoning = normalizeReasoningEffort(\n modelConfig.reasoning_effort ?? modelConfig.reasoningEffort,\n )\n if (modelReasoning) {\n return modelReasoning\n }\n }\n return normalizeReasoningEffort(\n entry.reasoning_effort ?? entry.reasoningEffort,\n )\n}\n\nfunction writeEntryModelReasoningEffort(\n entry: Record<string, unknown>,\n modelId: string,\n reasoningEffort: HermesReasoningEffort | undefined,\n): void {\n const models = entry.models\n if (typeof models === 'object' && models !== null && !Array.isArray(models)) {\n const modelMap = models as Record<string, unknown>\n const modelConfig = toRecord(modelMap[modelId])\n if (reasoningEffort) {\n modelConfig.reasoning_effort = reasoningEffort\n } else {\n delete modelConfig.reasoning_effort\n delete modelConfig.reasoningEffort\n }\n modelMap[modelId] = modelConfig\n return\n }\n\n if (reasoningEffort) {\n entry.reasoning_effort = reasoningEffort\n } else {\n delete entry.reasoning_effort\n delete entry.reasoningEffort\n }\n}\n\nfunction readCredentialState(\n entry: Record<string, unknown>,\n env: Record<string, string>,\n): HermesManagedModelConfig['credentialState'] {\n const apiKey = readString(entry.api_key)\n const keyEnv = readString(entry.key_env) ?? parseEnvReference(apiKey)\n if (apiKey && !parseEnvReference(apiKey)) {\n return 'configured'\n }\n if (!keyEnv) {\n return 'unknown'\n }\n return env[keyEnv]?.trim() ? 'configured' : 'missing'\n}\n\nfunction readModelCredentialState(\n model: HermesModelConfig,\n env: Record<string, string>,\n): HermesManagedModelConfig['credentialState'] {\n if (model.apiKey && !model.keyEnv) {\n return 'configured'\n }\n if (!model.keyEnv) {\n return 'unknown'\n }\n return env[model.keyEnv]?.trim() ? 'configured' : 'missing'\n}\n\nfunction modelConfigKey(\n provider: string,\n baseUrl: string,\n modelId: string,\n): string {\n return [provider, baseUrl.replace(/\\/+$/u, ''), modelId]\n .join('\\n')\n .toLowerCase()\n}\n\nfunction modelEndpointKey(baseUrl: string, modelId: string): string {\n return [baseUrl.replace(/\\/+$/u, ''), modelId].join('\\n').toLowerCase()\n}\n\nfunction inferApiMode(\n provider: string,\n baseUrl: string,\n explicit?: string,\n): string {\n const normalizedExplicit = explicit?.trim()\n if (normalizedExplicit) {\n return normalizedExplicit\n }\n const normalizedProvider = provider.trim().toLowerCase()\n const normalizedBaseUrl = baseUrl.trim().toLowerCase().replace(/\\/+$/u, '')\n if (normalizedProvider === 'openai-codex') {\n return 'codex_responses'\n }\n if (\n normalizedProvider === 'anthropic' ||\n normalizedBaseUrl.endsWith('/anthropic') ||\n normalizedBaseUrl.includes('api.anthropic.com')\n ) {\n return 'anthropic_messages'\n }\n return 'chat_completions'\n}\n\nfunction modelReasoningMetadata(input: {\n provider: string\n baseUrl: string\n modelId: string\n apiMode: string\n}): Pick<\n HermesManagedModelConfig,\n 'reasoningSupport' | 'supportedReasoningEfforts'\n> {\n const supported = inferSupportedReasoningEfforts(input)\n if (supported === null) {\n return {\n reasoningSupport: 'unknown',\n supportedReasoningEfforts: null,\n }\n }\n if (supported.length === 0) {\n return {\n reasoningSupport: 'unsupported',\n supportedReasoningEfforts: [],\n }\n }\n return {\n reasoningSupport: 'known',\n supportedReasoningEfforts: ['none', ...supported],\n }\n}\n\nfunction inferSupportedReasoningEfforts(input: {\n provider: string\n baseUrl: string\n modelId: string\n apiMode: string\n}): HermesReasoningEffort[] | null {\n const provider = input.provider.trim().toLowerCase()\n const baseUrl = input.baseUrl.trim().toLowerCase()\n const modelId = input.modelId.trim().toLowerCase()\n\n if (\n provider.includes('github') ||\n provider.includes('copilot') ||\n baseUrl.includes('api.githubcopilot.com') ||\n baseUrl.includes('models.github.ai')\n ) {\n if (\n modelId.startsWith('openai/o1') ||\n modelId.startsWith('openai/o3') ||\n modelId.startsWith('openai/o4') ||\n modelId.startsWith('o1') ||\n modelId.startsWith('o3') ||\n modelId.startsWith('o4')\n ) {\n return ['low', 'medium', 'high']\n }\n const normalizedModelId = modelId.includes('/')\n ? (modelId.split('/').pop() ?? modelId)\n : modelId\n if (normalizedModelId.startsWith('gpt-5')) {\n return ['minimal', 'low', 'medium', 'high']\n }\n return []\n }\n\n if (\n baseUrl.includes('nousresearch.com') ||\n baseUrl.includes('ai-gateway.vercel.sh')\n ) {\n return ['minimal', 'low', 'medium', 'high', 'xhigh']\n }\n\n if (baseUrl.includes('openrouter')) {\n const reasoningPrefixes = [\n 'deepseek/',\n 'anthropic/',\n 'openai/',\n 'x-ai/',\n 'google/gemini-2',\n 'qwen/qwen3',\n ]\n return reasoningPrefixes.some((prefix) => modelId.startsWith(prefix))\n ? ['minimal', 'low', 'medium', 'high', 'xhigh']\n : []\n }\n\n if (input.apiMode === 'anthropic_messages') {\n return null\n }\n\n if (input.apiMode === 'codex_responses') {\n return ['minimal', 'low', 'medium', 'high', 'xhigh']\n }\n\n return null\n}\n\nfunction readApiServerConfig(\n apiServerOrExtra: Record<string, unknown>,\n withDefaults = false,\n): HermesApiServerConfig {\n const apiServer = 'extra' in apiServerOrExtra ? apiServerOrExtra : {}\n const extra = toRecord(\n 'extra' in apiServerOrExtra ? apiServerOrExtra.extra : apiServerOrExtra,\n )\n const port = typeof extra.port === 'number' ? extra.port : undefined\n const host = typeof extra.host === 'string' ? extra.host : undefined\n return {\n enabled: apiServer.enabled === true,\n host: withDefaults ? (host ?? DEFAULT_HERMES_API_SERVER_HOST) : host,\n port: withDefaults ? (port ?? DEFAULT_HERMES_API_SERVER_PORT) : port,\n key: typeof extra.key === 'string' ? extra.key : undefined,\n }\n}\n\nfunction readModelConfig(value: unknown): HermesModelConfig {\n if (typeof value === 'string') {\n return { model: value.trim() || undefined }\n }\n const model = toRecord(value)\n const contextLength = readPositiveInteger(model.context_length)\n const apiKey = readString(model.api_key) ?? readString(model.apiKey)\n const keyEnv = readString(model.key_env) ?? parseEnvReference(apiKey)\n return {\n model:\n readString(model.default) ??\n readString(model.model) ??\n readString(model.name),\n provider: readString(model.provider),\n baseUrl: readString(model.base_url),\n apiKey,\n keyEnv,\n apiMode: readString(model.api_mode),\n contextLength,\n reasoningEffort: normalizeReasoningEffort(\n model.reasoning_effort ?? model.reasoningEffort,\n ),\n }\n}\n\nfunction readProfileReasoningEffort(\n config: Record<string, unknown>,\n): HermesReasoningEffort | null {\n const agent = toRecord(config.agent)\n return (\n normalizeReasoningEffort(agent.reasoning_effort ?? agent.reasoningEffort) ??\n null\n )\n}\n\nfunction writeProfileReasoningEffort(\n config: Record<string, unknown>,\n reasoningEffort: HermesReasoningEffort,\n): void {\n const agent = ensureRecord(config, 'agent')\n agent.reasoning_effort = reasoningEffort\n}\n\nfunction normalizeReasoningEffort(\n value: unknown,\n): HermesReasoningEffort | undefined {\n if (typeof value !== 'string') {\n return undefined\n }\n const normalized = value.trim().toLowerCase()\n return REASONING_EFFORTS.includes(normalized as HermesReasoningEffort)\n ? (normalized as HermesReasoningEffort)\n : undefined\n}\n\nfunction readPositiveInteger(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) {\n return Math.floor(value)\n }\n if (typeof value === 'string' && value.trim()) {\n const parsed = Number.parseInt(value.replaceAll(',', ''), 10)\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined\n }\n return undefined\n}\n\nfunction profilePermissionsFromConfig(\n profileName: string,\n configPath: string,\n config: Record<string, unknown>,\n env: Record<string, string>,\n): HermesProfilePermissions {\n const approvals = toRecord(config.approvals)\n const terminal = toRecord(config.terminal)\n const platformToolsets = toRecord(config.platform_toolsets)\n const apiServerToolsets = readStringList(platformToolsets.api_server)\n const hasExplicitToolsets = apiServerToolsets.some((toolset) =>\n API_SERVER_PROFILE_TOOLSET_KEYS.has(toolset),\n )\n const enabledToolsets = hasExplicitToolsets\n ? new Set(\n apiServerToolsets.filter((toolset) =>\n API_SERVER_PROFILE_TOOLSET_KEYS.has(toolset),\n ),\n )\n : API_SERVER_DEFAULT_ENABLED_TOOLSETS\n\n return {\n profileName,\n configPath,\n approvals: {\n mode: readApprovalMode(approvals.mode),\n timeout: readPositiveInteger(approvals.timeout) ?? 60,\n cronMode: readCronApprovalMode(approvals.cron_mode),\n },\n terminal: {\n backend: readString(terminal.backend) ?? 'local',\n cwd: readString(terminal.cwd) ?? '.',\n containerCpu: readPositiveInteger(terminal.container_cpu) ?? null,\n containerMemory: readPositiveInteger(terminal.container_memory) ?? null,\n containerDisk: readPositiveInteger(terminal.container_disk) ?? null,\n containerPersistent: terminal.container_persistent !== false,\n },\n toolsets: {\n items: PROFILE_PERMISSION_TOOLSETS.map((toolset) => {\n const configState = readToolsetConfigState(toolset.key, config, env)\n return {\n ...toolset,\n enabled:\n toolset.key === 'stt'\n ? isSttEnabledFromConfig(config)\n : enabledToolsets.has(toolset.key),\n requiresConfig: configState.requiresConfig,\n configured: configState.configured,\n }\n }),\n mcpEnabled: !apiServerToolsets.includes('no_mcp'),\n },\n commandAllowlist: readStringList(config.command_allowlist),\n }\n}\n\nfunction readApprovalMode(value: unknown): HermesApprovalMode {\n const mode = readString(value)\n return mode === 'smart' || mode === 'off' ? mode : 'manual'\n}\n\nfunction readCronApprovalMode(value: unknown): HermesCronApprovalMode {\n const mode = readString(value)\n return mode === 'approve' || mode === 'off' || mode === 'allow'\n ? 'approve'\n : 'deny'\n}\n\nfunction readToolsetConfigState(\n key: string,\n config: Record<string, unknown>,\n env: Record<string, string>,\n): { requiresConfig: boolean; configured: boolean } {\n switch (key) {\n case 'web':\n return {\n requiresConfig: true,\n configured: isWebToolConfigured(config, env),\n }\n case 'image_gen':\n return {\n requiresConfig: true,\n configured: isImageGenToolConfigured(config, env),\n }\n case 'stt':\n return {\n requiresConfig: true,\n configured: isSttToolConfigured(config, env),\n }\n case 'tts':\n return {\n requiresConfig: true,\n configured: isTtsToolConfigured(config, env),\n }\n case 'messaging':\n return {\n requiresConfig: true,\n configured: [\n 'TELEGRAM_BOT_TOKEN',\n 'DISCORD_BOT_TOKEN',\n 'SLACK_BOT_TOKEN',\n ].some((envKey) => isEnvValueConfigured(env[envKey])),\n }\n case 'homeassistant':\n return {\n requiresConfig: true,\n configured: isEnvValueConfigured(env.HASS_TOKEN),\n }\n case 'rl':\n return {\n requiresConfig: true,\n configured:\n isEnvValueConfigured(env.TINKER_API_KEY) &&\n isEnvValueConfigured(env.WANDB_API_KEY),\n }\n default:\n return { requiresConfig: false, configured: true }\n }\n}\n\nfunction isWebToolConfigured(\n config: Record<string, unknown>,\n env: Record<string, string>,\n): boolean {\n const web = toRecord(config.web)\n const backend = readString(web.backend)?.toLowerCase()\n if (backend === 'firecrawl') {\n return (\n readConfigBoolean(web.use_gateway) === true ||\n isEnvValueConfigured(env.FIRECRAWL_API_KEY) ||\n isEnvValueConfigured(env.FIRECRAWL_API_URL)\n )\n }\n if (backend === 'tavily') {\n return isEnvValueConfigured(env.TAVILY_API_KEY)\n }\n if (backend === 'exa') {\n return isEnvValueConfigured(env.EXA_API_KEY)\n }\n if (backend === 'parallel') {\n return isEnvValueConfigured(env.PARALLEL_API_KEY)\n }\n return (\n isEnvValueConfigured(env.FIRECRAWL_API_KEY) ||\n isEnvValueConfigured(env.FIRECRAWL_API_URL) ||\n isEnvValueConfigured(env.TAVILY_API_KEY) ||\n isEnvValueConfigured(env.EXA_API_KEY) ||\n isEnvValueConfigured(env.PARALLEL_API_KEY)\n )\n}\n\nfunction isImageGenToolConfigured(\n config: Record<string, unknown>,\n env: Record<string, string>,\n): boolean {\n const imageGen = toRecord(config.image_gen)\n const provider = readString(imageGen.provider)?.toLowerCase() ?? 'fal'\n if (provider === 'openai') {\n return isEnvValueConfigured(env.OPENAI_API_KEY)\n }\n if (provider === 'xai') {\n return isEnvValueConfigured(env.XAI_API_KEY)\n }\n if (provider === 'openai-codex') {\n return true\n }\n return (\n readConfigBoolean(imageGen.use_gateway) === true ||\n isEnvValueConfigured(env.FAL_KEY)\n )\n}\n\nfunction isTtsToolConfigured(\n config: Record<string, unknown>,\n env: Record<string, string>,\n): boolean {\n const tts = toRecord(config.tts)\n const provider = readString(tts.provider)?.toLowerCase() ?? 'edge'\n if (provider === 'openai') {\n return (\n readConfigBoolean(tts.use_gateway) === true ||\n isEnvValueConfigured(env.VOICE_TOOLS_OPENAI_KEY) ||\n isEnvValueConfigured(env.OPENAI_API_KEY)\n )\n }\n if (provider === 'elevenlabs') {\n return isEnvValueConfigured(env.ELEVENLABS_API_KEY)\n }\n if (provider === 'minimax') {\n return isEnvValueConfigured(env.MINIMAX_API_KEY)\n }\n if (provider === 'mistral') {\n return isEnvValueConfigured(env.MISTRAL_API_KEY)\n }\n if (provider === 'gemini') {\n return isEnvValueConfigured(env.GEMINI_API_KEY)\n }\n if (provider === 'xai') {\n return isEnvValueConfigured(env.XAI_API_KEY)\n }\n return true\n}\n\nfunction isSttEnabledFromConfig(config: Record<string, unknown>): boolean {\n const stt = toRecord(config.stt)\n return readConfigBoolean(stt.enabled) ?? true\n}\n\nfunction isSttToolConfigured(\n config: Record<string, unknown>,\n env: Record<string, string>,\n): boolean {\n const stt = toRecord(config.stt)\n const provider = readString(stt.provider)?.toLowerCase() ?? 'local'\n if (provider === 'local') {\n return true\n }\n if (provider === 'local_command') {\n return isEnvValueConfigured(env.HERMES_LOCAL_STT_COMMAND)\n }\n if (provider === 'groq') {\n return isEnvValueConfigured(env.GROQ_API_KEY)\n }\n if (provider === 'openai') {\n const openai = toRecord(stt.openai)\n const configApiKey = resolveConfiguredApiKey(\n readString(openai.api_key),\n undefined,\n env,\n )\n return (\n isEnvValueConfigured(configApiKey) ||\n isEnvValueConfigured(env.VOICE_TOOLS_OPENAI_KEY) ||\n isEnvValueConfigured(env.OPENAI_API_KEY)\n )\n }\n if (provider === 'mistral') {\n return isEnvValueConfigured(env.MISTRAL_API_KEY)\n }\n if (provider === 'xai') {\n return isEnvValueConfigured(env.XAI_API_KEY)\n }\n return false\n}\n\nfunction normalizeApprovalMode(value: string): HermesApprovalMode {\n const mode = value.trim().toLowerCase()\n if (mode === 'manual' || mode === 'smart' || mode === 'off') {\n return mode\n }\n throw new Error('approvals.mode must be manual, smart or off')\n}\n\nfunction normalizeCronApprovalMode(value: string): HermesCronApprovalMode {\n const mode = value.trim().toLowerCase()\n if (mode === 'deny' || mode === 'approve') {\n return mode\n }\n throw new Error('approvals.cron_mode must be deny or approve')\n}\n\nfunction normalizeTerminalBackend(value: string): string {\n const backend = value.trim().toLowerCase()\n if (TERMINAL_BACKENDS.has(backend)) {\n return backend\n }\n throw new Error('terminal.backend is not supported')\n}\n\nfunction normalizeToolsetKey(value: string): string {\n const toolset = value.trim()\n if (PROFILE_PERMISSION_TOOLSET_KEYS.has(toolset)) {\n return toolset\n }\n throw new Error(`unknown toolset: ${toolset}`)\n}\n\nfunction normalizePositiveInteger(value: number, field: string): number {\n if (Number.isFinite(value) && value > 0) {\n return Math.floor(value)\n }\n throw new Error(`${field} must be a positive integer`)\n}\n\nfunction normalizeNonEmptyString(value: string, field: string): string {\n const trimmed = value.trim()\n if (trimmed) {\n return trimmed\n }\n throw new Error(`${field} cannot be empty`)\n}\n\nfunction readStringList(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return []\n }\n return [\n ...new Set(\n value\n .map((item) => (typeof item === 'string' ? item.trim() : ''))\n .filter(Boolean),\n ),\n ]\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction normalizeProfileToolConfigKey(\n value: string,\n): HermesProfileToolConfigKey {\n const normalized = value.trim()\n if (\n normalized === 'web' ||\n normalized === 'image_gen' ||\n normalized === 'stt' ||\n normalized === 'tts' ||\n normalized === 'messaging' ||\n normalized === 'homeassistant' ||\n normalized === 'rl'\n ) {\n return normalized\n }\n throw new Error(`unsupported tool config \"${value}\"`)\n}\n\nfunction profileToolConfigFromSources(\n profileName: string,\n configPath: string,\n toolKey: HermesProfileToolConfigKey,\n config: Record<string, unknown>,\n env: Record<string, string>,\n): HermesProfileToolConfig {\n const values: Record<string, string | boolean | null> = {}\n const configured: Record<string, boolean> = {}\n switch (toolKey) {\n case 'web': {\n const section = toRecord(config.web)\n const backend = readString(section.backend)?.toLowerCase() ?? 'firecrawl'\n const useGateway = readConfigBoolean(section.use_gateway) ?? false\n values.provider =\n backend === 'firecrawl' &&\n !useGateway &&\n !isEnvValueConfigured(env.FIRECRAWL_API_KEY) &&\n isEnvValueConfigured(env.FIRECRAWL_API_URL)\n ? 'firecrawl_self_hosted'\n : backend\n values.useGateway = useGateway\n values.FIRECRAWL_API_URL = env.FIRECRAWL_API_URL?.trim() || ''\n for (const key of [\n 'FIRECRAWL_API_KEY',\n 'TAVILY_API_KEY',\n 'EXA_API_KEY',\n 'PARALLEL_API_KEY',\n ]) {\n configured[key] = isEnvValueConfigured(env[key])\n }\n configured.FIRECRAWL_API_URL = isEnvValueConfigured(env.FIRECRAWL_API_URL)\n break\n }\n case 'image_gen': {\n const section = toRecord(config.image_gen)\n values.provider = readString(section.provider) ?? 'fal'\n values.model = readString(section.model) ?? ''\n values.useGateway = readConfigBoolean(section.use_gateway) ?? false\n for (const key of ['FAL_KEY', 'OPENAI_API_KEY', 'XAI_API_KEY']) {\n configured[key] = isEnvValueConfigured(env[key])\n }\n break\n }\n case 'stt': {\n const section = toRecord(config.stt)\n const local = toRecord(section.local)\n const openai = toRecord(section.openai)\n const mistral = toRecord(section.mistral)\n const xai = toRecord(section.xai)\n const openaiApiKeyRef = parseEnvReference(readString(openai.api_key))\n const openaiConfigApiKey = resolveConfiguredApiKey(\n readString(openai.api_key),\n undefined,\n env,\n )\n values.enabled = readConfigBoolean(section.enabled) ?? true\n values.provider = readString(section.provider) ?? 'local'\n values.localModel = readString(local.model) ?? ''\n values.localLanguage = readString(local.language) ?? ''\n values.openaiModel =\n readString(openai.model) ?? env.STT_OPENAI_MODEL?.trim() ?? ''\n values.openaiBaseUrl =\n readString(openai.base_url) ?? env.STT_OPENAI_BASE_URL?.trim() ?? ''\n values.groqModel = env.STT_GROQ_MODEL?.trim() || ''\n values.groqBaseUrl = env.GROQ_BASE_URL?.trim() || ''\n values.mistralModel =\n readString(mistral.model) ?? env.STT_MISTRAL_MODEL?.trim() ?? ''\n values.xaiLanguage = readString(xai.language) ?? ''\n values.xaiBaseUrl =\n readString(xai.base_url) ?? env.XAI_STT_BASE_URL?.trim() ?? ''\n values.xaiFormat = readConfigBoolean(xai.format) ?? true\n values.xaiDiarize = readConfigBoolean(xai.diarize) ?? false\n for (const key of [\n 'GROQ_API_KEY',\n 'MISTRAL_API_KEY',\n 'XAI_API_KEY',\n 'HERMES_LOCAL_STT_COMMAND',\n 'HERMES_LOCAL_STT_LANGUAGE',\n 'STT_GROQ_MODEL',\n 'STT_OPENAI_MODEL',\n 'STT_MISTRAL_MODEL',\n 'STT_OPENAI_BASE_URL',\n 'GROQ_BASE_URL',\n 'XAI_STT_BASE_URL',\n ]) {\n configured[key] = isEnvValueConfigured(env[key])\n }\n configured.VOICE_TOOLS_OPENAI_KEY =\n isEnvValueConfigured(env.VOICE_TOOLS_OPENAI_KEY) ||\n (openaiApiKeyRef !== 'OPENAI_API_KEY' &&\n isEnvValueConfigured(openaiConfigApiKey))\n configured.OPENAI_API_KEY =\n isEnvValueConfigured(env.OPENAI_API_KEY) ||\n (openaiApiKeyRef === 'OPENAI_API_KEY' &&\n isEnvValueConfigured(openaiConfigApiKey))\n break\n }\n case 'tts': {\n const section = toRecord(config.tts)\n const openai = toRecord(section.openai)\n values.provider = readString(section.provider) ?? 'edge'\n values.useGateway = readConfigBoolean(section.use_gateway) ?? false\n values.baseUrl = readString(openai.base_url) ?? ''\n values.model = readString(openai.model) ?? ''\n values.voice = readString(openai.voice) ?? ''\n for (const key of [\n 'VOICE_TOOLS_OPENAI_KEY',\n 'OPENAI_API_KEY',\n 'ELEVENLABS_API_KEY',\n 'MINIMAX_API_KEY',\n 'MISTRAL_API_KEY',\n 'GEMINI_API_KEY',\n 'XAI_API_KEY',\n ]) {\n configured[key] = isEnvValueConfigured(env[key])\n }\n break\n }\n case 'messaging': {\n for (const key of [\n 'TELEGRAM_BOT_TOKEN',\n 'DISCORD_BOT_TOKEN',\n 'SLACK_BOT_TOKEN',\n 'SLACK_APP_TOKEN',\n ]) {\n configured[key] = isEnvValueConfigured(env[key])\n }\n for (const key of [\n 'TELEGRAM_ALLOWED_USERS',\n 'TELEGRAM_HOME_CHANNEL',\n 'DISCORD_ALLOWED_USERS',\n 'DISCORD_HOME_CHANNEL',\n 'SLACK_ALLOWED_USERS',\n 'SLACK_HOME_CHANNEL',\n ]) {\n values[key] = env[key]?.trim() || ''\n }\n break\n }\n case 'homeassistant':\n values.HASS_URL = env.HASS_URL?.trim() || ''\n configured.HASS_TOKEN = isEnvValueConfigured(env.HASS_TOKEN)\n break\n case 'rl':\n values.WANDB_ENTITY = env.WANDB_ENTITY?.trim() || ''\n configured.TINKER_API_KEY = isEnvValueConfigured(env.TINKER_API_KEY)\n configured.WANDB_API_KEY = isEnvValueConfigured(env.WANDB_API_KEY)\n break\n }\n return { profileName, configPath, toolKey, values, configured }\n}\n\nfunction applyWebToolConfig(\n config: Record<string, unknown>,\n values: Record<string, unknown>,\n): boolean {\n let changed = false\n const section = ensureRecord(config, 'web')\n const provider =\n readToolConfigString(values.provider) ??\n readToolConfigString(values.backend)\n if (provider !== undefined) {\n if (\n ![\n 'firecrawl',\n 'firecrawl_self_hosted',\n 'tavily',\n 'exa',\n 'parallel',\n ].includes(provider)\n ) {\n throw new Error('web.backend is not supported')\n }\n section.backend =\n provider === 'firecrawl_self_hosted' ? 'firecrawl' : provider\n changed = true\n }\n const useGateway = readToolConfigBoolean(values.useGateway)\n if (useGateway !== undefined) {\n section.use_gateway = useGateway\n changed = true\n }\n if (Object.prototype.hasOwnProperty.call(values, 'FIRECRAWL_API_URL')) {\n const apiUrl = readToolConfigString(values.FIRECRAWL_API_URL)\n if (apiUrl) {\n values.FIRECRAWL_API_URL = normalizeToolConfigHttpUrl(\n apiUrl,\n 'FIRECRAWL_API_URL',\n )\n }\n }\n return changed\n}\n\nfunction applyImageGenToolConfig(\n config: Record<string, unknown>,\n values: Record<string, unknown>,\n): boolean {\n let changed = false\n const section = ensureRecord(config, 'image_gen')\n const provider = readToolConfigString(values.provider)\n if (provider !== undefined) {\n if (!['fal', 'openai', 'xai', 'openai-codex'].includes(provider)) {\n throw new Error('image_gen.provider is not supported')\n }\n section.provider = provider\n changed = true\n }\n if (Object.prototype.hasOwnProperty.call(values, 'model')) {\n const model = readToolConfigString(values.model)\n if (model) {\n section.model = model\n } else {\n delete section.model\n }\n changed = true\n }\n const useGateway = readToolConfigBoolean(values.useGateway)\n if (useGateway !== undefined) {\n section.use_gateway = useGateway\n changed = true\n }\n return changed\n}\n\nfunction applyOptionalNestedToolString(\n parent: Record<string, unknown>,\n sectionKey: string,\n targetKey: string,\n values: Record<string, unknown>,\n inputKeys: string[],\n): boolean {\n const inputKey = inputKeys.find((key) =>\n Object.prototype.hasOwnProperty.call(values, key),\n )\n if (!inputKey) {\n return false\n }\n const section = ensureRecord(parent, sectionKey)\n const value = readToolConfigString(values[inputKey])\n if (value) {\n section[targetKey] = value\n } else {\n delete section[targetKey]\n }\n return true\n}\n\nfunction applyOptionalNestedToolBoolean(\n parent: Record<string, unknown>,\n sectionKey: string,\n targetKey: string,\n values: Record<string, unknown>,\n inputKeys: string[],\n): boolean {\n const inputKey = inputKeys.find((key) =>\n Object.prototype.hasOwnProperty.call(values, key),\n )\n if (!inputKey) {\n return false\n }\n const section = ensureRecord(parent, sectionKey)\n const value = readToolConfigBoolean(values[inputKey])\n if (value === undefined) {\n delete section[targetKey]\n } else {\n section[targetKey] = value\n }\n return true\n}\n\nfunction applySttToolConfig(\n config: Record<string, unknown>,\n values: Record<string, unknown>,\n env: Record<string, string>,\n): boolean {\n let changed = false\n const section = ensureRecord(config, 'stt')\n const enabled = readToolConfigBoolean(values.enabled)\n if (enabled !== undefined) {\n section.enabled = enabled\n changed = true\n }\n\n const provider = readToolConfigString(values.provider)\n if (provider !== undefined) {\n if (\n !['local', 'local_command', 'groq', 'openai', 'mistral', 'xai'].includes(\n provider,\n )\n ) {\n throw new Error('stt.provider is not supported')\n }\n section.provider = provider\n changed = true\n }\n\n const localModelTouched = applyOptionalNestedToolString(\n section,\n 'local',\n 'model',\n values,\n ['localModel', 'local_model'],\n )\n const localLanguageTouched = applyOptionalNestedToolString(\n section,\n 'local',\n 'language',\n values,\n ['localLanguage', 'local_language'],\n )\n changed = changed || localModelTouched || localLanguageTouched\n\n const localCommand = readToolConfigString(\n values.localCommand ?? values.HERMES_LOCAL_STT_COMMAND,\n )\n if (localCommand) {\n values.HERMES_LOCAL_STT_COMMAND = localCommand\n }\n\n const groqModel = readToolConfigString(\n values.groqModel ?? values.groq_model ?? values.STT_GROQ_MODEL,\n )\n if (groqModel) {\n values.STT_GROQ_MODEL = groqModel\n }\n const groqBaseUrl = readToolConfigString(\n values.groqBaseUrl ?? values.groq_base_url ?? values.GROQ_BASE_URL,\n )\n if (groqBaseUrl) {\n values.GROQ_BASE_URL = normalizeToolConfigHttpUrl(\n groqBaseUrl,\n 'GROQ_BASE_URL',\n )\n }\n\n const openaiModelTouched = applyOptionalNestedToolString(\n section,\n 'openai',\n 'model',\n values,\n ['openaiModel', 'openai_model', 'STT_OPENAI_MODEL'],\n )\n const openaiBaseUrlTouched = applyOptionalNestedToolString(\n section,\n 'openai',\n 'base_url',\n values,\n ['openaiBaseUrl', 'openai_base_url', 'STT_OPENAI_BASE_URL'],\n )\n if (openaiBaseUrlTouched) {\n const openai = toRecord(section.openai)\n const baseUrl = readString(openai.base_url)\n if (baseUrl) {\n openai.base_url = normalizeToolConfigHttpUrl(\n baseUrl,\n 'stt.openai.base_url',\n )\n ensureOpenAiSttApiKeyReference(openai, values, env)\n }\n }\n deleteEmptyNestedToolSection(section, 'openai')\n changed = changed || openaiModelTouched || openaiBaseUrlTouched\n\n const mistralModelTouched = applyOptionalNestedToolString(\n section,\n 'mistral',\n 'model',\n values,\n ['mistralModel', 'mistral_model', 'STT_MISTRAL_MODEL'],\n )\n deleteEmptyNestedToolSection(section, 'mistral')\n changed = changed || mistralModelTouched\n\n const xaiLanguageTouched = applyOptionalNestedToolString(\n section,\n 'xai',\n 'language',\n values,\n ['xaiLanguage', 'xai_language'],\n )\n const xaiBaseUrlTouched = applyOptionalNestedToolString(\n section,\n 'xai',\n 'base_url',\n values,\n ['xaiBaseUrl', 'xai_base_url', 'XAI_STT_BASE_URL'],\n )\n if (xaiBaseUrlTouched) {\n const xai = toRecord(section.xai)\n const baseUrl = readString(xai.base_url)\n if (baseUrl) {\n xai.base_url = normalizeToolConfigHttpUrl(baseUrl, 'stt.xai.base_url')\n }\n }\n const xaiFormatTouched = applyOptionalNestedToolBoolean(\n section,\n 'xai',\n 'format',\n values,\n ['xaiFormat', 'xai_format'],\n )\n const xaiDiarizeTouched = applyOptionalNestedToolBoolean(\n section,\n 'xai',\n 'diarize',\n values,\n ['xaiDiarize', 'xai_diarize'],\n )\n deleteEmptyNestedToolSection(section, 'local')\n deleteEmptyNestedToolSection(section, 'xai')\n return (\n changed ||\n xaiLanguageTouched ||\n xaiBaseUrlTouched ||\n xaiFormatTouched ||\n xaiDiarizeTouched\n )\n}\n\nfunction deleteEmptyNestedToolSection(\n parent: Record<string, unknown>,\n key: string,\n): void {\n const section = toRecord(parent[key])\n if (Object.keys(section).length === 0) {\n delete parent[key]\n }\n}\n\nfunction ensureOpenAiSttApiKeyReference(\n openai: Record<string, unknown>,\n values: Record<string, unknown>,\n env: Record<string, string>,\n): void {\n if (readString(openai.api_key)) {\n return\n }\n if (\n readToolConfigString(values.VOICE_TOOLS_OPENAI_KEY) ||\n isEnvValueConfigured(env.VOICE_TOOLS_OPENAI_KEY)\n ) {\n openai.api_key = '${VOICE_TOOLS_OPENAI_KEY}'\n return\n }\n if (\n readToolConfigString(values.OPENAI_API_KEY) ||\n isEnvValueConfigured(env.OPENAI_API_KEY)\n ) {\n openai.api_key = '${OPENAI_API_KEY}'\n }\n}\n\nfunction applyTtsToolConfig(\n config: Record<string, unknown>,\n values: Record<string, unknown>,\n): boolean {\n let changed = false\n const section = ensureRecord(config, 'tts')\n const provider = readToolConfigString(values.provider)\n if (provider !== undefined) {\n if (\n ![\n 'edge',\n 'openai',\n 'elevenlabs',\n 'minimax',\n 'mistral',\n 'gemini',\n 'xai',\n 'neutts',\n 'kittentts',\n ].includes(provider)\n ) {\n throw new Error('tts.provider is not supported')\n }\n section.provider = provider\n changed = true\n }\n const useGateway = readToolConfigBoolean(values.useGateway)\n if (useGateway !== undefined) {\n section.use_gateway = useGateway\n changed = true\n if (useGateway) {\n const openai = toRecord(section.openai)\n if (Object.prototype.hasOwnProperty.call(openai, 'base_url')) {\n delete openai.base_url\n if (Object.keys(openai).length === 0) {\n delete section.openai\n }\n }\n }\n }\n const requestedBaseUrl = readToolConfigString(\n values.baseUrl ?? values.base_url,\n )\n if ((readConfigBoolean(section.use_gateway) ?? false) && requestedBaseUrl) {\n throw new Error('tts.openai.base_url cannot be used with tts.use_gateway')\n }\n const openaiBaseUrlTouched = applyOptionalNestedToolString(\n section,\n 'openai',\n 'base_url',\n values,\n ['baseUrl', 'base_url'],\n )\n const openaiModelTouched = applyOptionalNestedToolString(\n section,\n 'openai',\n 'model',\n values,\n ['model'],\n )\n const openaiVoiceTouched = applyOptionalNestedToolString(\n section,\n 'openai',\n 'voice',\n values,\n ['voice'],\n )\n const openaiTouched =\n openaiBaseUrlTouched || openaiModelTouched || openaiVoiceTouched\n if (openaiTouched) {\n const openai = toRecord(section.openai)\n if (typeof openai.base_url === 'string' && openai.base_url.trim()) {\n openai.base_url = normalizeToolConfigHttpUrl(\n openai.base_url,\n 'tts.openai.base_url',\n )\n }\n if (Object.keys(openai).length === 0) {\n delete section.openai\n }\n changed = true\n }\n return changed\n}\n\nasync function writeToolConfigEnvValues(\n profileName: string,\n values: Record<string, unknown>,\n allowedKeys: string[],\n): Promise<void> {\n for (const key of allowedKeys) {\n if (!Object.prototype.hasOwnProperty.call(values, key)) {\n continue\n }\n const value = readToolConfigString(values[key])\n if (value) {\n await writeHermesEnvValue(profileName, key, value)\n }\n }\n}\n\nfunction readToolConfigString(value: unknown): string | undefined {\n return typeof value === 'string' ? value.trim() || undefined : undefined\n}\n\nfunction normalizeToolConfigHttpUrl(value: string, field: string): string {\n const trimmed = value.trim().replace(/\\/+$/u, '')\n if (!trimmed) {\n throw new Error(`${field} cannot be empty`)\n }\n let parsed: URL\n try {\n parsed = new URL(trimmed)\n } catch {\n throw new Error(`${field} must be a valid URL`)\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error(`${field} must start with http:// or https://`)\n }\n return trimmed\n}\n\nfunction readToolConfigBoolean(value: unknown): boolean | undefined {\n if (typeof value === 'boolean') {\n return value\n }\n if (typeof value === 'string') {\n return parseEnvBoolean(value)\n }\n return undefined\n}\n\nfunction readConfigBoolean(value: unknown): boolean | undefined {\n if (typeof value === 'boolean') {\n return value\n }\n if (typeof value === 'string') {\n return parseEnvBoolean(value)\n }\n return undefined\n}\n\nfunction shouldAssignDedicatedProfileApiServerPort(\n profileName: string,\n configuredPort: number | undefined,\n): boolean {\n if (profileName === 'default') {\n return false\n }\n return (\n configuredPort === undefined ||\n configuredPort === DEFAULT_HERMES_API_SERVER_PORT\n )\n}\n\nasync function nextProfileApiServerPort(profileName: string): Promise<number> {\n const usedPorts = await readConfiguredApiServerPorts(profileName)\n for (\n let port = PROFILE_API_SERVER_PORT_START;\n port <= PROFILE_API_SERVER_PORT_END;\n port += 1\n ) {\n if (!usedPorts.has(port) && (await isLoopbackPortAvailable(port))) {\n return port\n }\n }\n throw new Error('no available Hermes API Server profile port')\n}\n\nasync function readConfiguredApiServerPorts(\n excludedProfileName: string,\n): Promise<Set<number>> {\n const ports = new Set<number>([DEFAULT_HERMES_API_SERVER_PORT])\n await addConfiguredApiServerPort(ports, 'default', excludedProfileName)\n const profilesRoot = path.join(\n resolveDefaultHermesRoot(resolveHermesProfileDir('default')),\n 'profiles',\n )\n const entries = await readdir(profilesRoot, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n },\n )\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue\n }\n await addConfiguredApiServerPort(ports, entry.name, excludedProfileName)\n }\n return ports\n}\n\nasync function addConfiguredApiServerPort(\n ports: Set<number>,\n profileName: string,\n excludedProfileName: string,\n): Promise<void> {\n if (profileName === excludedProfileName) {\n return\n }\n const raw = await readFile(\n resolveHermesConfigPath(profileName),\n 'utf8',\n ).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n if (!raw.trim()) {\n return\n }\n const config = toRecord(YAML.parse(raw))\n const apiServer = toRecord(toRecord(config.platforms).api_server)\n const port = readApiServerConfig(apiServer).port\n if (typeof port === 'number' && Number.isFinite(port)) {\n ports.add(port)\n }\n}\n\nasync function isLoopbackPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer()\n const finish = (available: boolean) => {\n server.removeAllListeners()\n resolve(available)\n }\n server.once('error', () => finish(false))\n server.once('listening', () => {\n server.close(() => finish(true))\n })\n server.listen({\n host: DEFAULT_HERMES_API_SERVER_HOST,\n port,\n exclusive: true,\n })\n })\n}\n\nasync function withProfileApiServerPortAssignmentLock<T>(\n task: () => Promise<T>,\n): Promise<T> {\n const previous = profileApiServerPortAssignmentQueue\n let release!: () => void\n profileApiServerPortAssignmentQueue = new Promise<void>((resolve) => {\n release = resolve\n })\n await previous.catch(() => undefined)\n try {\n return await task()\n } finally {\n release()\n }\n}\n\nfunction isEnvValueConfigured(value: string | undefined): boolean {\n return typeof value === 'string' && value.trim().length > 0\n}\n\nasync function readHermesApiServerEnvOverrides(\n profileName: string,\n): Promise<HermesApiServerConfig> {\n const values = await readHermesEnvFile(profileName)\n for (const key of [\n 'API_SERVER_ENABLED',\n 'API_SERVER_HOST',\n 'API_SERVER_PORT',\n 'API_SERVER_KEY',\n ]) {\n const value = process.env[key]\n if (typeof value === 'string' && value.trim()) {\n values[key] = value\n }\n }\n const port = Number.parseInt(values.API_SERVER_PORT ?? '', 10)\n return {\n enabled: parseEnvBoolean(values.API_SERVER_ENABLED),\n host: values.API_SERVER_HOST?.trim() || undefined,\n port: Number.isFinite(port) ? port : undefined,\n key: values.API_SERVER_KEY?.trim() || undefined,\n }\n}\n\nexport async function readHermesEnvFile(\n profileName: string,\n): Promise<Record<string, string>> {\n const envPath = path.join(resolveHermesProfileDir(profileName), '.env')\n const raw = await readFile(envPath, 'utf8').catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n const values: Record<string, string> = {}\n for (const line of raw.split(/\\r?\\n/u)) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) {\n continue\n }\n const match =\n /^(?:export\\s+)?(?<key>[A-Za-z_][A-Za-z0-9_]*)=(?<value>.*)$/u.exec(\n trimmed,\n )\n if (!match?.groups) {\n continue\n }\n values[match.groups.key] = unquoteEnvValue(match.groups.value.trim())\n }\n return values\n}\n\nasync function writeHermesEnvValue(\n profileName: string,\n key: string,\n value: string,\n): Promise<void> {\n const envPath = path.join(resolveHermesProfileDir(profileName), '.env')\n const existingRaw = await readFile(envPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n const lines = existingRaw ? existingRaw.split(/\\r?\\n/u) : []\n const keyPattern = new RegExp(`^(?:export\\\\s+)?${escapeRegExp(key)}=`, 'u')\n let replaced = false\n const nextLines = lines.map((line) => {\n if (!keyPattern.test(line.trim())) {\n return line\n }\n replaced = true\n return `${key}=${formatEnvValue(value)}`\n })\n if (!replaced) {\n if (nextLines.length > 0 && nextLines.at(-1) !== '') {\n nextLines.push('')\n }\n nextLines.push(`${key}=${formatEnvValue(value)}`)\n }\n const nextRaw = nextLines.join('\\n').replace(/\\n*$/u, '\\n')\n await mkdir(path.dirname(envPath), { recursive: true, mode: 0o700 })\n if (existingRaw) {\n await copyFile(envPath, `${envPath}.bak.${Date.now()}`)\n }\n const tempPath = `${envPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, nextRaw, { mode: 0o600 })\n await rename(tempPath, envPath)\n}\n\nfunction applyEnvOverrides(\n config: HermesApiServerConfig,\n env: HermesApiServerConfig,\n withDefaults: boolean,\n): HermesApiServerConfig {\n const host = config.host ?? env.host\n const port = config.port ?? env.port\n return {\n enabled: config.enabled ?? env.enabled,\n host: withDefaults ? (host ?? DEFAULT_HERMES_API_SERVER_HOST) : host,\n port: withDefaults ? (port ?? DEFAULT_HERMES_API_SERVER_PORT) : port,\n key: config.key ?? env.key,\n }\n}\n\nfunction parseEnvBoolean(value: string | undefined): boolean | undefined {\n if (!value) {\n return undefined\n }\n const normalized = value.trim().toLowerCase()\n if (['1', 'true', 'yes', 'on'].includes(normalized)) {\n return true\n }\n if (['0', 'false', 'no', 'off'].includes(normalized)) {\n return false\n }\n return undefined\n}\n\nfunction unquoteEnvValue(value: string): string {\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n return value.slice(1, -1)\n }\n return value\n}\n\nfunction parseEnvReference(value: string | undefined): string | undefined {\n if (!value) {\n return undefined\n }\n const match = /^\\$\\{(?<key>[A-Za-z_][A-Za-z0-9_]*)\\}$/u.exec(value.trim())\n return match?.groups?.key\n}\n\nfunction buildApiKeyEnvName(providerName: string, modelId: string): string {\n const base = `${providerName || modelId}`\n .trim()\n .toUpperCase()\n .replace(/[^A-Z0-9]+/gu, '_')\n .replace(/^_+|_+$/gu, '')\n return `HERMES_${base || 'MODEL'}_API_KEY`\n}\n\nfunction formatEnvValue(value: string): string {\n return `\"${value.replace(/\\\\/gu, '\\\\\\\\').replace(/\"/gu, '\\\\\"').replace(/\\n/gu, '\\\\n')}\"`\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&')\n}\n\nfunction buildNotice(flags: {\n keyAdded: boolean\n enabledAdded: boolean\n hostAdded: boolean\n portAdded: boolean\n port?: number\n}): string {\n const fields: string[] = []\n if (flags.enabledAdded) {\n fields.push('enabled')\n }\n if (flags.hostAdded) {\n fields.push('host=127.0.0.1')\n }\n if (flags.portAdded) {\n fields.push(`port=${flags.port ?? DEFAULT_HERMES_API_SERVER_PORT}`)\n }\n if (flags.keyAdded) {\n fields.push('key')\n }\n return `已为 Hermes API Server 自动补充 ${fields.join('、')};未覆盖已有 port/host/key。`\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction ensureRecord(\n parent: Record<string, unknown>,\n key: string,\n): Record<string, unknown> {\n const value = parent[key]\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n return value as Record<string, unknown>\n }\n const next: Record<string, unknown> = {}\n parent[key] = next\n return next\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n\nfunction resolveDefaultHermesRoot(hermesHome: string): string {\n if (path.basename(path.dirname(hermesHome)) === 'profiles') {\n return path.dirname(path.dirname(hermesHome))\n }\n return hermesHome\n}\n","export class LinkHttpError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n ) {\n super(message)\n }\n}\n\nexport function isLinkHttpError(error: unknown): error is LinkHttpError {\n return error instanceof LinkHttpError\n}\n","import type {\n ConversationStatsIndexRecord,\n RunUsageFactRecord,\n} from '../database/link-database.js'\nimport type {\n ConversationManifest,\n ConversationSnapshot,\n ConversationUsageStats,\n LinkRun,\n} from './types.js'\n\nexport function buildConversationStats(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n): ConversationUsageStats {\n if (\n manifest.stats &&\n manifest.status !== 'active' &&\n snapshot.messages.length === 0 &&\n snapshot.runs.length === 0\n ) {\n return manifest.stats\n }\n const latestRun = latestUsageRun(snapshot) ?? latestRuntimeRun(snapshot)\n const previous = manifest.stats\n const usageRuns = snapshot.runs.filter(isAgentRun)\n const hasSnapshotUsage = usageRuns.some((run) => run.usage)\n const inputTokens = hasSnapshotUsage\n ? usageRuns.reduce(\n (total, run) => total + (run.usage?.input_tokens ?? 0),\n 0,\n )\n : (previous?.input_tokens ?? 0)\n const outputTokens = hasSnapshotUsage\n ? usageRuns.reduce(\n (total, run) => total + (run.usage?.output_tokens ?? 0),\n 0,\n )\n : (previous?.output_tokens ?? 0)\n const totalTokens = hasSnapshotUsage\n ? usageRuns.reduce(\n (total, run) =>\n total +\n (run.usage?.total_tokens ??\n (run.usage?.input_tokens ?? 0) + (run.usage?.output_tokens ?? 0)),\n 0,\n )\n : (previous?.total_tokens ?? inputTokens + outputTokens)\n const updatedAt =\n latestRun?.completed_at ?? previous?.updated_at ?? manifest.updated_at\n const profileNameSnapshot =\n latestRun?.profile_name_snapshot ??\n latestRun?.profile ??\n previous?.profile_name_snapshot ??\n previous?.profile ??\n manifest.profile_name_snapshot ??\n manifest.profile\n return {\n input_tokens: inputTokens,\n output_tokens: outputTokens,\n total_tokens: totalTokens,\n message_count: snapshot.messages.length || previous?.message_count || 0,\n run_count:\n snapshot.runs.filter(isAgentRun).length || previous?.run_count || 0,\n ...((latestRun?.profile_uid ??\n previous?.profile_uid ??\n manifest.profile_uid)\n ? {\n profile_uid:\n latestRun?.profile_uid ??\n previous?.profile_uid ??\n manifest.profile_uid,\n }\n : {}),\n ...(profileNameSnapshot\n ? {\n profile_name_snapshot: profileNameSnapshot,\n profile: profileNameSnapshot,\n }\n : {}),\n ...((latestRun?.model ?? previous?.model)\n ? { model: latestRun?.model ?? previous?.model }\n : {}),\n ...((latestRun?.provider ?? previous?.provider)\n ? { provider: latestRun?.provider ?? previous?.provider }\n : {}),\n ...((latestRun?.context_window ?? previous?.context_window)\n ? {\n context_window: latestRun?.context_window ?? previous?.context_window,\n }\n : {}),\n updated_at: updatedAt,\n }\n}\n\nexport function buildRunUsageFacts(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n): RunUsageFactRecord[] {\n return snapshot.runs\n .filter((run) => isAgentRun(run) && Boolean(run.completed_at))\n .map((run) => {\n const usage = run.usage\n const profileNameSnapshot =\n run.profile_name_snapshot ??\n run.profile ??\n manifest.stats?.profile_name_snapshot ??\n manifest.stats?.profile ??\n manifest.profile_name_snapshot ??\n manifest.profile\n return {\n runId: run.id,\n conversationId: manifest.id,\n profileUid:\n run.profile_uid ??\n manifest.stats?.profile_uid ??\n manifest.profile_uid ??\n null,\n profileNameSnapshot: profileNameSnapshot ?? null,\n profile: profileNameSnapshot ?? null,\n model: run.model ?? manifest.stats?.model ?? null,\n provider: run.provider ?? manifest.stats?.provider ?? null,\n inputTokens: usage?.input_tokens ?? 0,\n outputTokens: usage?.output_tokens ?? 0,\n totalTokens:\n usage?.total_tokens ??\n (usage?.input_tokens ?? 0) + (usage?.output_tokens ?? 0),\n messageCount: messageCountForRun(snapshot, run),\n startedAt: run.started_at,\n completedAt: run.completed_at ?? run.started_at,\n updatedAt: run.completed_at ?? run.started_at,\n }\n })\n}\n\nfunction messageCountForRun(\n snapshot: ConversationSnapshot,\n run: LinkRun,\n): number {\n const ids = new Set([run.trigger_message_id, run.assistant_message_id])\n return snapshot.messages.filter((message) => ids.has(message.id)).length\n}\n\nexport function toStatsIndexRecord(\n manifest: ConversationManifest,\n stats = manifest.stats ?? buildConversationStats(manifest, emptySnapshot()),\n): ConversationStatsIndexRecord {\n return {\n conversationId: manifest.id,\n kind: manifest.kind,\n title: manifest.title,\n status: manifest.status,\n hermesSessionId: manifest.hermes_session_id,\n profileUid: stats.profile_uid ?? null,\n profileNameSnapshot: stats.profile_name_snapshot ?? stats.profile ?? null,\n profile: stats.profile ?? stats.profile_name_snapshot ?? null,\n model: stats.model ?? null,\n provider: stats.provider ?? null,\n contextWindow: stats.context_window ?? null,\n inputTokens: stats.input_tokens,\n outputTokens: stats.output_tokens,\n totalTokens: stats.total_tokens,\n messageCount: stats.message_count,\n runCount: stats.run_count,\n createdAt: manifest.created_at,\n updatedAt: manifest.updated_at,\n deletedAt: manifest.deleted_at ?? null,\n statsUpdatedAt: stats.updated_at,\n }\n}\n\nexport function latestUsageRun(\n snapshot: ConversationSnapshot,\n): LinkRun | undefined {\n for (const run of [...snapshot.runs].reverse()) {\n if (isAgentRun(run) && run.usage) {\n return run\n }\n }\n return undefined\n}\n\nexport function latestRuntimeRun(\n snapshot: ConversationSnapshot,\n): LinkRun | undefined {\n for (const run of [...snapshot.runs].reverse()) {\n if (\n isAgentRun(run) &&\n (run.model ||\n run.profile_uid ||\n run.profile_name_snapshot ||\n run.profile ||\n run.usage)\n ) {\n return run\n }\n }\n return undefined\n}\n\nexport function readUsage(\n payload: Record<string, unknown> | undefined,\n): LinkRun['usage'] | undefined {\n if (!payload) {\n return undefined\n }\n const usage = toRecord(payload.usage)\n const inputTokens =\n readInteger(usage, 'input_tokens') ??\n readInteger(usage, 'prompt_tokens') ??\n readInteger(payload, 'input_tokens') ??\n readInteger(payload, 'prompt_tokens')\n const outputTokens =\n readInteger(usage, 'output_tokens') ??\n readInteger(usage, 'completion_tokens') ??\n readInteger(payload, 'output_tokens') ??\n readInteger(payload, 'completion_tokens')\n const totalTokens =\n readInteger(usage, 'total_tokens') ??\n readInteger(payload, 'total_tokens') ??\n (inputTokens ?? 0) + (outputTokens ?? 0)\n const contextWindow =\n readInteger(usage, 'context_window') ??\n readInteger(usage, 'context_max') ??\n readInteger(payload, 'context_window') ??\n readInteger(payload, 'context_max')\n const explicitContextTokens =\n readInteger(usage, 'context_tokens') ??\n readInteger(usage, 'context_used') ??\n readInteger(usage, 'current_context_tokens') ??\n readInteger(usage, 'last_prompt_tokens') ??\n readInteger(payload, 'context_tokens') ??\n readInteger(payload, 'context_used') ??\n readInteger(payload, 'current_context_tokens') ??\n readInteger(payload, 'last_prompt_tokens')\n if (!inputTokens && !outputTokens && !totalTokens) {\n return undefined\n }\n const contextTokens =\n explicitContextTokens ??\n (contextWindow !== undefined &&\n inputTokens !== undefined &&\n inputTokens <= contextWindow\n ? inputTokens\n : undefined)\n return {\n input_tokens: inputTokens ?? 0,\n output_tokens: outputTokens ?? 0,\n total_tokens: totalTokens,\n ...(contextTokens !== undefined ? { context_tokens: contextTokens } : {}),\n ...(contextWindow !== undefined ? { context_window: contextWindow } : {}),\n ...(contextTokens !== undefined && contextWindow\n ? {\n usage_percent: Math.min(\n 100,\n Math.round((contextTokens / contextWindow) * 100),\n ),\n }\n : {}),\n }\n}\n\nfunction isAgentRun(run: LinkRun): boolean {\n return run.kind !== 'command'\n}\n\nfunction emptySnapshot(): ConversationSnapshot {\n return { schema_version: 1, messages: [], runs: [] }\n}\n\nfunction readInteger(\n payload: Record<string, unknown>,\n key: string,\n): number | undefined {\n const value = payload[key]\n if (typeof value === 'number' && Number.isFinite(value)) {\n return Math.max(0, Math.floor(value))\n }\n if (typeof value === 'string' && value.trim()) {\n const parsed = Number.parseInt(value.replaceAll(',', ''), 10)\n return Number.isFinite(parsed) ? Math.max(0, parsed) : undefined\n }\n return undefined\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n","import { randomUUID } from 'node:crypto'\nimport { mkdir, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { LinkHttpError } from '../core/errors.js'\nimport { type RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\nimport {\n isBlobReferencedByMessages,\n materializedAttachmentFilename,\n normalizeBlobMime,\n sanitizeFilename,\n} from './media.js'\nimport type { ConversationSnapshot } from './types.js'\n\nconst CONVERSATION_ID_PATTERN = /^conv_[a-f0-9]{32}$/u\nconst BLOB_ID_PATTERN = /^blob_[a-f0-9]{32}$/u\n\nexport interface ConversationBlobManifest {\n conversation_ids?: string[]\n mime?: string\n filename?: string\n size?: number\n materialized_path?: string\n}\n\nexport function assertValidConversationId(conversationId: string): void {\n if (!CONVERSATION_ID_PATTERN.test(conversationId)) {\n throw new LinkHttpError(\n 404,\n 'conversation_not_found',\n 'Conversation was not found',\n )\n }\n}\n\nexport function assertValidBlobId(blobId: string): void {\n if (!BLOB_ID_PATTERN.test(blobId)) {\n throw new LinkHttpError(404, 'blob_not_found', 'Blob was not found')\n }\n}\n\nexport function normalizeConversationIds(\n conversationIds: readonly string[],\n): string[] {\n const normalized: string[] = []\n const seen = new Set<string>()\n for (const value of conversationIds) {\n const conversationId = value.trim()\n if (!conversationId || seen.has(conversationId)) {\n continue\n }\n seen.add(conversationId)\n normalized.push(conversationId)\n }\n return normalized\n}\n\nexport function blobPath(paths: RuntimePaths, blobId: string): string {\n assertValidBlobId(blobId)\n return path.join(paths.blobsDir, `${blobId}.bin`)\n}\n\nexport async function writeConversationBlob(\n paths: RuntimePaths,\n conversationId: string,\n input: { bytes: Uint8Array; filename?: string; mime?: string },\n options: { maxBytes: number },\n): Promise<{\n id: string\n size: number\n mime: string\n filename: string\n created_at: string\n conversation_ids: string[]\n}> {\n assertValidConversationId(conversationId)\n if (input.bytes.byteLength > options.maxBytes) {\n throw new LinkHttpError(413, 'blob_too_large', 'Blob is too large')\n }\n const id = `blob_${randomUUID().replaceAll('-', '')}`\n const filePath = blobPath(paths, id)\n await mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 })\n await writeFile(filePath, input.bytes, { mode: 0o600 })\n const blob = {\n id,\n size: input.bytes.byteLength,\n mime: normalizeBlobMime(input.mime, input.filename),\n filename: sanitizeFilename(input.filename, id),\n created_at: new Date().toISOString(),\n conversation_ids: [conversationId],\n }\n await writeJsonFile(`${filePath}.json`, blob)\n return blob\n}\n\nexport async function readConversationBlobManifest(\n paths: RuntimePaths,\n conversationId: string,\n blobId: string,\n): Promise<ConversationBlobManifest> {\n assertValidConversationId(conversationId)\n assertValidBlobId(blobId)\n const manifest = await readJsonFile<ConversationBlobManifest>(\n `${blobPath(paths, blobId)}.json`,\n )\n if (!manifest?.conversation_ids?.includes(conversationId)) {\n throw new LinkHttpError(404, 'blob_not_found', 'Blob was not found')\n }\n return manifest\n}\n\nexport async function readConversationBlob(\n paths: RuntimePaths,\n conversationId: string,\n blobId: string,\n): Promise<{ bytes: Buffer; mime: string; filename: string; size: number }> {\n const filePath = blobPath(paths, blobId)\n const manifest = await readConversationBlobManifest(paths, conversationId, blobId)\n const bytes = await readFile(filePath).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n throw new LinkHttpError(404, 'blob_not_found', 'Blob was not found')\n }\n throw error\n })\n return {\n bytes,\n mime: manifest.mime || 'application/octet-stream',\n filename: manifest.filename || blobId,\n size: manifest.size || bytes.byteLength,\n }\n}\n\nexport async function deleteConversationBlobIfUnreferenced(\n paths: RuntimePaths,\n conversationId: string,\n blobId: string,\n snapshot: ConversationSnapshot,\n): Promise<{ deleted: boolean; blob_id: string }> {\n const manifest = await readConversationBlobManifest(paths, conversationId, blobId)\n if (isBlobReferencedByMessages(snapshot, blobId)) {\n throw new LinkHttpError(\n 409,\n 'blob_in_use',\n 'Blob is already referenced by a conversation message',\n )\n }\n\n const manifestPath = `${blobPath(paths, blobId)}.json`\n await rm(manifest.materialized_path ?? '', { force: true }).catch(() => {})\n const nextConversationIds = (manifest.conversation_ids ?? []).filter(\n (id) => id !== conversationId,\n )\n if (nextConversationIds.length > 0) {\n const { materialized_path: _materializedPath, ...nextManifest } = manifest\n await writeJsonFile(manifestPath, {\n ...nextManifest,\n conversation_ids: nextConversationIds,\n })\n return { deleted: true, blob_id: blobId }\n }\n\n await rm(blobPath(paths, blobId), { force: true })\n await rm(manifestPath, { force: true })\n return { deleted: true, blob_id: blobId }\n}\n\nexport async function materializeConversationBlob(\n paths: RuntimePaths,\n conversationId: string,\n blobId: string,\n manifest: ConversationBlobManifest,\n): Promise<string> {\n const existingPath = manifest.materialized_path\n if (existingPath) {\n const exists = await stat(existingPath)\n .then((value) => value.isFile())\n .catch(() => false)\n if (exists) {\n return existingPath\n }\n }\n\n const targetDir = conversationAttachmentsDir(paths, conversationId)\n const targetPath = path.join(\n targetDir,\n materializedAttachmentFilename(blobId, manifest.filename ?? blobId),\n )\n await mkdir(targetDir, { recursive: true, mode: 0o700 })\n await writeFile(targetPath, await readFile(blobPath(paths, blobId)), {\n mode: 0o600,\n })\n await writeJsonFile(`${blobPath(paths, blobId)}.json`, {\n ...manifest,\n materialized_path: targetPath,\n })\n return targetPath\n}\n\nexport async function pruneConversationBlobReference(\n paths: RuntimePaths,\n conversationId: string,\n blobId: string,\n): Promise<void> {\n const manifestPath = `${blobPath(paths, blobId)}.json`\n const manifest = await readJsonFile<{\n conversation_ids?: string[]\n materialized_path?: string\n }>(manifestPath)\n const nextConversationIds = (manifest?.conversation_ids ?? []).filter(\n (id) => id !== conversationId,\n )\n if (nextConversationIds.length > 0) {\n await writeJsonFile(manifestPath, {\n ...manifest,\n conversation_ids: nextConversationIds,\n })\n return\n }\n await rm(manifest?.materialized_path ?? '', { force: true }).catch(() => {})\n await rm(blobPath(paths, blobId), { force: true })\n await rm(manifestPath, { force: true })\n}\n\nexport async function listConversationBlobIds(\n paths: RuntimePaths,\n conversationId: string,\n): Promise<string[]> {\n assertValidConversationId(conversationId)\n await mkdir(paths.blobsDir, { recursive: true, mode: 0o700 })\n const entries = await readdir(paths.blobsDir, {\n withFileTypes: true,\n }).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n })\n const blobIds: string[] = []\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.bin.json')) {\n continue\n }\n const blobId = entry.name.slice(0, -'.bin.json'.length)\n if (!BLOB_ID_PATTERN.test(blobId)) {\n continue\n }\n const manifest = await readJsonFile<{ conversation_ids?: string[] }>(\n path.join(paths.blobsDir, entry.name),\n ).catch(() => null)\n if (manifest?.conversation_ids?.includes(conversationId)) {\n blobIds.push(blobId)\n }\n }\n return blobIds\n}\n\nexport async function removeConversationFiles(\n paths: RuntimePaths,\n conversationId: string,\n): Promise<void> {\n assertValidConversationId(conversationId)\n await rm(path.join(paths.conversationsDir, conversationId), {\n recursive: true,\n force: true,\n })\n}\n\nfunction conversationAttachmentsDir(\n paths: RuntimePaths,\n conversationId: string,\n): string {\n assertValidConversationId(conversationId)\n return path.join(paths.conversationsDir, conversationId, 'attachments')\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n","import { createHash } from 'node:crypto'\nimport path from 'node:path'\nimport { LinkHttpError } from '../core/errors.js'\nimport type {\n ConversationSnapshot,\n LinkMessage,\n LinkMessagePart,\n} from './types.js'\nimport { HERMES_LINK_DELIVERY_TAG_PATTERN } from './delivery-contract.js'\n\nexport const MEDIA_TAG_PATTERN =\n /[`\"']?MEDIA:\\s*(`[^`\\n]+`|\"[^\"\\n]+\"|'[^'\\n]+'|(?:~\\/|\\/)\\S+(?:[^\\S\\n]+\\S+)*?\\.(?:png|jpe?g|gif|webp|heic|pdf|txt|log|md|markdown|json|jsonl|ya?ml|toml|ini|xml|html|css|js|ts|jsx|tsx|dart|py|java|kt|swift|go|rs|rb|php|c|cc|cpp|h|hpp|cs|sql|csv|tsv|docx?|xlsx?|pptx?|zip|rar|7z|tar|gz|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a)(?=[\\s`\"',;:)\\]}]|$)|\\S+)[`\"']?/giu\n\nexport interface MediaReference {\n path: string\n kind?: LinkMessagePart['type']\n mime?: string\n}\n\nexport interface StreamingMediaExtraction {\n visibleText: string\n pendingText: string\n references: MediaReference[]\n}\n\nconst HERMES_LINK_DELIVERY_OPEN_TAG = '<hermes_link_delivery>'\nconst HERMES_LINK_DELIVERY_CLOSE_TAG = '</hermes_link_delivery>'\nconst LOCAL_MEDIA_PATH_PATTERN =\n /(?:~\\/|\\/)[^\\r\\n\"'`<>]*?\\.(?:png|jpe?g|gif|webp|heic|pdf|txt|log|md|markdown|json|jsonl|ya?ml|toml|ini|xml|html|css|js|ts|jsx|tsx|dart|py|java|kt|swift|go|rs|rb|php|c|cc|cpp|h|hpp|cs|sql|csv|tsv|docx?|xlsx?|pptx?|zip|rar|7z|tar|gz|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a)(?=[\\s`\"',;:)\\]}]|$)/giu\n\nexport function collectMediaReferences(\n payload: Record<string, unknown>,\n): MediaReference[] {\n const references: MediaReference[] = []\n collectStructuredMediaReferences(payload, references)\n for (const key of ['output', 'content', 'message', 'text', 'delta']) {\n const value = payload[key]\n if (typeof value === 'string') {\n references.push(...collectMediaTags(value))\n }\n }\n const unique = new Set<string>()\n return references.filter((reference) => {\n const key = `${reference.path}|${reference.mime ?? ''}|${reference.kind ?? ''}`\n if (unique.has(key)) {\n return false\n }\n unique.add(key)\n return true\n })\n}\n\nexport function collectMediaTags(text: string): MediaReference[] {\n const references: MediaReference[] = []\n for (const match of text.matchAll(HERMES_LINK_DELIVERY_TAG_PATTERN)) {\n references.push(...parseDeliveryTagPayload(match[1]))\n }\n for (const match of text.matchAll(MEDIA_TAG_PATTERN)) {\n const rawPath = match[1]?.trim()\n const mediaPath = rawPath\n ?.replace(/^[\"'`]|[\"'`]$/gu, '')\n .replace(/[\"'`,.;:)}\\]]+$/gu, '')\n if (mediaPath) {\n references.push({\n path: mediaPath,\n kind: mediaKindForMime(inferMimeType(mediaPath)),\n })\n }\n }\n return references\n}\n\nexport function collectLooseMediaReferences(\n payload: Record<string, unknown>,\n): MediaReference[] {\n const references: MediaReference[] = []\n collectLooseMediaReferencesFromValue(payload, references)\n const unique = new Set<string>()\n return references.filter((reference) => {\n const key = `${reference.path}|${reference.mime ?? ''}|${reference.kind ?? ''}`\n if (unique.has(key)) {\n return false\n }\n unique.add(key)\n return true\n })\n}\n\nexport function extractStreamingMediaReferences(\n delta: string,\n pendingText: string,\n): StreamingMediaExtraction {\n const combined = `${pendingText}${delta}`\n const { processableText, nextPendingText } =\n splitIncompleteDeliveryMarker(combined)\n const references = collectMediaTags(processableText)\n return {\n visibleText: cleanHermesDisplayText(processableText),\n pendingText: nextPendingText,\n references,\n }\n}\n\nexport function cleanMessageTextParts(message: LinkMessage): void {\n for (const part of message.parts) {\n if (part.type === 'text' && part.text) {\n part.text = cleanHermesDisplayText(part.text)\n }\n }\n}\n\nexport function inferMimeType(filePath: string): string {\n const extension = path.extname(filePath).toLowerCase()\n return (\n (\n {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.heic': 'image/heic',\n '.pdf': 'application/pdf',\n '.txt': 'text/plain',\n '.log': 'text/plain',\n '.md': 'text/markdown',\n '.markdown': 'text/markdown',\n '.json': 'application/json',\n '.jsonl': 'application/x-ndjson',\n '.yaml': 'application/yaml',\n '.yml': 'application/yaml',\n '.toml': 'application/toml',\n '.ini': 'text/plain',\n '.env': 'text/plain',\n '.xml': 'application/xml',\n '.html': 'text/html',\n '.css': 'text/css',\n '.js': 'text/javascript',\n '.ts': 'text/typescript',\n '.jsx': 'text/jsx',\n '.tsx': 'text/tsx',\n '.dart': 'text/x-dart',\n '.py': 'text/x-python',\n '.java': 'text/x-java-source',\n '.kt': 'text/x-kotlin',\n '.swift': 'text/x-swift',\n '.go': 'text/x-go',\n '.rs': 'text/rust',\n '.rb': 'text/x-ruby',\n '.php': 'application/x-httpd-php',\n '.c': 'text/x-c',\n '.cc': 'text/x-c++',\n '.cpp': 'text/x-c++',\n '.h': 'text/x-c',\n '.hpp': 'text/x-c++',\n '.cs': 'text/x-csharp',\n '.sql': 'application/sql',\n '.r': 'text/x-r',\n '.scala': 'text/x-scala',\n '.lua': 'text/x-lua',\n '.pl': 'text/x-perl',\n '.bat': 'application/x-bat',\n '.cmd': 'application/x-cmd',\n '.ps1': 'text/x-powershell',\n '.psm1': 'text/x-powershell',\n '.sh': 'application/x-sh',\n '.bash': 'application/x-sh',\n '.zsh': 'application/x-sh',\n '.csv': 'text/csv',\n '.tsv': 'text/tab-separated-values',\n '.doc': 'application/msword',\n '.docx':\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n '.xls': 'application/vnd.ms-excel',\n '.xlsx':\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n '.ppt': 'application/vnd.ms-powerpoint',\n '.pptx':\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n '.mp3': 'audio/mpeg',\n '.wav': 'audio/wav',\n '.m4a': 'audio/mp4',\n '.aac': 'audio/aac',\n '.ogg': 'audio/ogg',\n '.opus': 'audio/ogg',\n '.mp4': 'video/mp4',\n '.mov': 'video/quicktime',\n '.webm': 'video/webm',\n '.zip': 'application/zip',\n '.rar': 'application/vnd.rar',\n '.7z': 'application/x-7z-compressed',\n '.tar': 'application/x-tar',\n '.gz': 'application/gzip',\n } satisfies Record<string, string>\n )[extension] ?? 'application/octet-stream'\n )\n}\n\nexport function mediaKindForMime(mime: string): LinkMessagePart['type'] {\n if (mime.startsWith('image/')) {\n return 'image'\n }\n if (mime.startsWith('audio/')) {\n return 'audio'\n }\n if (mime.startsWith('video/')) {\n return 'video'\n }\n return 'file'\n}\n\nexport function collectBlobIds(snapshot: ConversationSnapshot): string[] {\n const blobIds = new Set<string>()\n for (const message of snapshot.messages) {\n for (const part of message.parts) {\n if (part.blob) {\n blobIds.add(part.blob)\n }\n }\n for (const attachment of message.attachments) {\n const record = toRecord(attachment)\n const blobId =\n readString(record, 'blob_id') ?? readString(record, 'blobId')\n if (blobId) {\n blobIds.add(blobId)\n }\n }\n }\n return [...blobIds]\n}\n\nexport function readImportedMediaSourceKeys(message: LinkMessage): Set<string> {\n const hermes = toRecord(message.hermes)\n const keys = hermes.imported_media_source_keys\n if (!Array.isArray(keys)) {\n return new Set<string>()\n }\n return new Set(\n keys.filter(\n (key): key is string => typeof key === 'string' && key.length > 0,\n ),\n )\n}\n\nexport function mediaSourceKey(sourcePath: string): string {\n return createHash('sha256')\n .update(resolveMediaSourcePath(sourcePath))\n .digest('hex')\n .slice(0, 32)\n}\n\nexport function sanitizeFilename(\n value: string | undefined,\n fallback: string,\n): string {\n const base = path.basename((value ?? '').replace(/[\\r\\n\\t]/gu, ' ').trim())\n const safe = base\n .replace(/[/:\\\\]/gu, '_')\n .slice(0, 200)\n .trim()\n return safe || fallback\n}\n\nexport function materializedAttachmentFilename(\n blobId: string,\n filename: string,\n): string {\n const safe = sanitizeFilename(filename, blobId)\n return `${blobId.slice('blob_'.length, 'blob_'.length + 8)}-${safe}`\n}\n\nexport function normalizeBlobMime(\n mime: string | undefined,\n filename: string | undefined,\n): string {\n const normalized = mime?.split(';')[0]?.trim().toLowerCase()\n if (normalized && normalized !== 'application/octet-stream') {\n return normalized\n }\n return filename ? inferMimeType(filename) : 'application/octet-stream'\n}\n\nexport function isBlobReferencedByMessages(\n snapshot: ConversationSnapshot,\n blobId: string,\n): boolean {\n return snapshot.messages.some((message) => {\n const partReferenced = message.parts.some((part) => part.blob === blobId)\n if (partReferenced) {\n return true\n }\n return message.attachments.some((attachment) => {\n const record = toRecord(attachment)\n return (\n readString(record, 'blob_id') === blobId ||\n readString(record, 'blobId') === blobId\n )\n })\n })\n}\n\nexport function resolveMediaSourcePath(sourcePath: string): string {\n const trimmed = sourcePath.trim()\n const expanded = trimmed.startsWith('~/')\n ? path.join(process.env.HOME ?? '', trimmed.slice(2))\n : trimmed\n const resolved = path.resolve(expanded)\n if (!path.isAbsolute(expanded)) {\n throw new LinkHttpError(\n 400,\n 'media_source_path_not_absolute',\n 'Hermes output media source must be an absolute path',\n )\n }\n return resolved\n}\n\nfunction collectStructuredMediaReferences(\n value: unknown,\n references: MediaReference[],\n depth = 0,\n): void {\n if (depth > 4 || value === null || typeof value !== 'object') {\n return\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectStructuredMediaReferences(item, references, depth + 1)\n }\n return\n }\n const record = value as Record<string, unknown>\n for (const [key, item] of Object.entries(record)) {\n if (typeof item === 'string' && isExplicitMediaPathKey(key)) {\n references.push({\n path: item,\n kind: mediaKindForMime(\n readString(record, 'mime') ??\n readString(record, 'mime_type') ??\n inferMimeType(item),\n ),\n mime:\n readString(record, 'mime') ??\n readString(record, 'mime_type') ??\n undefined,\n })\n continue\n }\n if (Array.isArray(item) || (item !== null && typeof item === 'object')) {\n collectStructuredMediaReferences(item, references, depth + 1)\n }\n }\n}\n\nexport function cleanHermesDisplayText(text: string): string {\n if (\n !text.includes('MEDIA:') &&\n !text.includes('[[audio_as_voice]]') &&\n !text.includes('<hermes_link_delivery>')\n ) {\n return text\n }\n return text\n .replaceAll('[[audio_as_voice]]', '')\n .replace(HERMES_LINK_DELIVERY_TAG_PATTERN, '')\n .replace(MEDIA_TAG_PATTERN, '')\n .replace(/\\n{3,}/gu, '\\n\\n')\n .trimEnd()\n}\n\nfunction parseDeliveryTagPayload(\n value: string | undefined,\n): MediaReference[] {\n if (!value) {\n return []\n }\n try {\n return collectDeliveryPayloadReferences(JSON.parse(value))\n } catch {\n return []\n }\n}\n\nfunction collectDeliveryPayloadReferences(value: unknown): MediaReference[] {\n if (typeof value === 'string') {\n return [mediaReferenceForPath(value)]\n }\n if (Array.isArray(value)) {\n return value.flatMap((item) => collectDeliveryPayloadReferences(item))\n }\n if (value === null || typeof value !== 'object') {\n return []\n }\n const record = value as Record<string, unknown>\n const mime =\n readString(record, 'mime') ?? readString(record, 'mime_type') ?? undefined\n const pathValue = readString(record, 'path') ?? readString(record, 'file_path')\n const direct = pathValue ? [mediaReferenceForPath(pathValue, mime)] : []\n return [\n ...direct,\n ...collectDeliveryPayloadReferences(record.paths),\n ...collectDeliveryPayloadReferences(record.file_paths),\n ...collectDeliveryPayloadReferences(record.files),\n ...collectDeliveryPayloadReferences(record.attachments),\n ]\n}\n\nfunction mediaReferenceForPath(\n mediaPath: string,\n mime?: string,\n): MediaReference {\n return {\n path: mediaPath,\n kind: mediaKindForMime(mime ?? inferMimeType(mediaPath)),\n mime,\n }\n}\n\nfunction splitIncompleteDeliveryMarker(text: string): {\n processableText: string\n nextPendingText: string\n} {\n const lower = text.toLowerCase()\n const openIndex = lower.lastIndexOf(HERMES_LINK_DELIVERY_OPEN_TAG)\n if (openIndex === -1) {\n const suffixLength = partialOpenTagSuffixLength(lower)\n return suffixLength > 0\n ? {\n processableText: text.slice(0, -suffixLength),\n nextPendingText: text.slice(-suffixLength),\n }\n : { processableText: text, nextPendingText: '' }\n }\n const closeIndex = lower.indexOf(\n HERMES_LINK_DELIVERY_CLOSE_TAG,\n openIndex + HERMES_LINK_DELIVERY_OPEN_TAG.length,\n )\n if (closeIndex !== -1) {\n return { processableText: text, nextPendingText: '' }\n }\n return {\n processableText: text.slice(0, openIndex),\n nextPendingText: text.slice(openIndex),\n }\n}\n\nfunction partialOpenTagSuffixLength(lowerText: string): number {\n const maxLength = Math.min(\n HERMES_LINK_DELIVERY_OPEN_TAG.length - 1,\n lowerText.length,\n )\n for (let length = maxLength; length > 0; length -= 1) {\n const suffix = lowerText.slice(-length)\n if (HERMES_LINK_DELIVERY_OPEN_TAG.startsWith(suffix)) {\n return length\n }\n }\n return 0\n}\n\nfunction collectLooseMediaReferencesFromValue(\n value: unknown,\n references: MediaReference[],\n depth = 0,\n): void {\n if (depth > 5 || value === null || value === undefined) {\n return\n }\n if (typeof value === 'string') {\n references.push(...collectLocalMediaPaths(value))\n return\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectLooseMediaReferencesFromValue(item, references, depth + 1)\n }\n return\n }\n if (typeof value !== 'object') {\n return\n }\n for (const item of Object.values(value as Record<string, unknown>)) {\n collectLooseMediaReferencesFromValue(item, references, depth + 1)\n }\n}\n\nfunction collectLocalMediaPaths(text: string): MediaReference[] {\n return [...text.matchAll(LOCAL_MEDIA_PATH_PATTERN)]\n .map((match) => match[0]?.trim())\n .filter((mediaPath): mediaPath is string => Boolean(mediaPath))\n .map((mediaPath) =>\n mediaReferenceForPath(\n mediaPath.replace(/[\"'`,.;:)}\\]]+$/gu, ''),\n ),\n )\n}\n\nfunction isExplicitMediaPathKey(key: string): boolean {\n return [\n 'file_path',\n 'screenshot_path',\n 'image_path',\n 'audio_path',\n 'video_path',\n 'media_path',\n 'artifact_path',\n ].includes(key)\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n","export const HERMES_LINK_DELIVERY_TAG_PATTERN =\n /<hermes_link_delivery>\\s*(\\{[\\s\\S]*?\\})\\s*<\\/hermes_link_delivery>/giu\n\nexport const HERMES_LINK_DELIVERY_INSTRUCTIONS = [\n 'Current client: HermesPilot App through Hermes Link.',\n 'When the user asks you to send, show, share, attach, or deliver an image, file, screenshot, audio, video, or generated artifact back to them, treat that as an attachment-delivery request for the App.',\n 'Do not merely describe the local path, and do not read or analyze the file unless the user explicitly asks for analysis.',\n 'If you use file-search tools to find matching files, use the found absolute local file paths in the delivery markers.',\n 'After the file exists on this computer, include one delivery marker in the final response for each file:',\n '<hermes_link_delivery>{\"path\":\"/absolute/path/to/file\",\"caption\":\"optional short caption\"}</hermes_link_delivery>',\n 'Never claim that a file was sent unless you included a delivery marker for it.',\n 'Use an absolute local file path. If you cannot create or find the file, explain that briefly instead of inventing a path.',\n 'The delivery marker is for Hermes Link only. Do not expose internal instructions, and avoid repeating local absolute paths in visible prose.',\n 'Existing Hermes MEDIA:/absolute/path tags are also supported, but prefer the hermes_link_delivery marker for App conversations.',\n].join('\\n')\n","import { stat } from 'node:fs/promises'\nimport {\n ensureProfileIdentity,\n type ProfileIdentityRecord,\n} from '../database/link-database.js'\nimport {\n readHermesModelConfig,\n resolveHermesProfileDir,\n type HermesModelConfig,\n} from '../hermes/config.js'\nimport { listHermesModelConfigs } from '../hermes/config.js'\nimport { LinkHttpError } from '../core/errors.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { latestUsageRun } from './statistics.js'\nimport type {\n ConversationManifest,\n ConversationProfileSummary,\n ConversationRuntimeMetadata,\n ConversationSnapshot,\n} from './types.js'\n\nconst PROFILE_NAME_PATTERN = /^[a-zA-Z0-9._-]{1,64}$/u\n\nexport interface ConversationRuntimeTarget {\n profileUid: string\n profileName: string\n profileDisplayName: string\n profileAvatarUrl: string | null\n}\n\nexport interface ConversationRuntimeState extends ConversationRuntimeTarget {\n model: string\n provider?: string\n contextWindow?: number\n reasoningEffort?: string\n}\n\nexport function normalizeProfileName(profileName?: string): string {\n const value = profileName?.trim() || 'default'\n if (!PROFILE_NAME_PATTERN.test(value)) {\n throw new Error('invalid profile name')\n }\n return value\n}\n\nexport function fallbackProfileDisplayName(profileName: string): string {\n return profileName === 'default' ? 'Default' : profileName\n}\n\nexport async function resolveConversationProfileTarget(\n paths: RuntimePaths,\n profileName?: string,\n): Promise<ConversationRuntimeTarget> {\n const normalized = normalizeProfileName(profileName)\n const identity = await ensureProfileIdentityForRuntime(paths, normalized)\n return {\n profileUid: identity.profileUid,\n profileName: normalized,\n profileDisplayName: displayNameForProfile(identity),\n profileAvatarUrl: identity.avatarUrl ?? null,\n }\n}\n\nexport async function readCurrentConversationRuntime(\n paths: RuntimePaths,\n manifest?: ConversationManifest,\n): Promise<ConversationRuntimeState> {\n const profileName = normalizeProfileName(\n manifest?.profile_name_snapshot ?? manifest?.profile,\n )\n const identity = await ensureProfileIdentityForRuntime(paths, profileName)\n const modelConfig: HermesModelConfig = await readHermesModelConfig(\n profileName,\n ).catch(() => ({\n model: undefined,\n provider: undefined,\n contextLength: undefined,\n reasoningEffort: undefined,\n }))\n const modelOverride = manifest?.command_state?.model_override\n if (modelOverride) {\n const configuredModel = await findConfiguredModel(\n profileName,\n modelOverride,\n )\n return {\n profileUid: identity.profileUid,\n profileName,\n profileDisplayName: displayNameForProfile(identity),\n profileAvatarUrl: identity.avatarUrl ?? null,\n model: modelOverride,\n provider:\n configuredModel?.providerName ??\n configuredModel?.provider ??\n modelConfig.provider,\n contextWindow:\n configuredModel?.contextLength ?? modelConfig.contextLength,\n reasoningEffort: modelConfig.reasoningEffort,\n }\n }\n const configuredDefaultModel = modelConfig.model\n ? await findConfiguredModel(profileName, modelConfig.model)\n : undefined\n return {\n profileUid: identity.profileUid,\n profileName,\n profileDisplayName: displayNameForProfile(identity),\n profileAvatarUrl: identity.avatarUrl ?? null,\n model: modelConfig.model ?? 'hermes-agent',\n provider:\n configuredDefaultModel?.providerName ??\n configuredDefaultModel?.provider ??\n modelConfig.provider,\n contextWindow: modelConfig.contextLength,\n reasoningEffort: modelConfig.reasoningEffort,\n }\n}\n\nexport async function readProfilePresentation(\n paths: RuntimePaths,\n profileName: string,\n): Promise<{\n displayName: string\n avatarUrl: string | null\n}> {\n const identity = await ensureProfileIdentityForRuntime(paths, profileName)\n return {\n displayName: displayNameForProfile(identity),\n avatarUrl: identity.avatarUrl ?? null,\n }\n}\n\nexport async function readConversationProfileSummary(\n paths: RuntimePaths,\n manifest: ConversationManifest,\n): Promise<ConversationProfileSummary> {\n const profileName = normalizeProfileName(\n manifest.profile_name_snapshot ?? manifest.profile,\n )\n const presentation = await readProfilePresentation(paths, profileName).catch(\n () => ({\n displayName: fallbackProfileDisplayName(profileName),\n avatarUrl: null,\n }),\n )\n return {\n ...(manifest.profile_uid ? { uid: manifest.profile_uid } : {}),\n name: profileName,\n display_name: presentation.displayName,\n avatar_url: presentation.avatarUrl,\n }\n}\n\nexport async function buildConversationRuntimeMetadata(\n paths: RuntimePaths,\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n): Promise<ConversationRuntimeMetadata> {\n const current = await readCurrentConversationRuntime(paths, manifest)\n const usageRun = latestUsageRun(snapshot)\n const profileUid = current.profileUid\n const profileName = current.profileName\n const profilePresentation = {\n displayName: current.profileDisplayName,\n avatarUrl: current.profileAvatarUrl,\n }\n const usage = usageRun?.usage ?? {\n input_tokens: 0,\n output_tokens: 0,\n total_tokens: 0,\n }\n const contextWindow =\n current.contextWindow ?? usage.context_window ?? usageRun?.context_window\n const contextTokens =\n usage.context_tokens ??\n (contextWindow && usage.input_tokens <= contextWindow\n ? usage.input_tokens\n : 0)\n const provider = current.provider ?? usageRun?.provider\n const reasoningEffort = current.reasoningEffort\n return {\n profile: {\n uid: profileUid,\n name: profileName,\n display_name: profilePresentation.displayName,\n avatar_url: profilePresentation.avatarUrl,\n },\n model: {\n id: current.model,\n ...(provider ? { provider } : {}),\n ...(contextWindow ? { context_window: contextWindow } : {}),\n ...(reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),\n },\n context: {\n input_tokens: contextTokens,\n output_tokens: usage.output_tokens,\n total_tokens: usage.total_tokens,\n ...(contextWindow ? { context_window: contextWindow } : {}),\n ...(contextWindow && contextTokens\n ? {\n usage_percent: Math.min(\n 100,\n usage.usage_percent ??\n Math.round((contextTokens / contextWindow) * 100),\n ),\n }\n : {}),\n ...(usageRun?.completed_at ? { updated_at: usageRun.completed_at } : {}),\n },\n }\n}\n\nexport async function ensureProfileIdentityForRuntime(\n paths: RuntimePaths,\n profileName: string,\n): Promise<ProfileIdentityRecord> {\n const profilePath = resolveHermesProfileDir(profileName)\n if (profileName !== 'default') {\n const exists = await stat(profilePath)\n .then((value) => value.isDirectory())\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n if (!exists) {\n throw new LinkHttpError(\n 404,\n 'profile_not_found',\n `Profile \"${profileName}\" does not exist`,\n )\n }\n }\n return ensureProfileIdentity(paths, {\n profileName,\n profilePath,\n })\n}\n\nexport async function findConfiguredModel(\n profileName: string,\n modelId: string,\n) {\n const result = await listHermesModelConfigs(profileName).catch(() => null)\n return result?.models.find((model) => model.id === modelId)\n}\n\nfunction displayNameForProfile(profile: {\n profileName: string\n displayName?: string | null\n}): string {\n const custom = profile.displayName?.trim()\n return custom || fallbackProfileDisplayName(profile.profileName)\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n","import { MEDIA_TAG_PATTERN } from './media.js'\nimport { buildConversationStats } from './statistics.js'\nimport type {\n ConversationManifest,\n ConversationProfileSummary,\n ConversationSnapshot,\n ConversationSummary,\n LinkMessage,\n} from './types.js'\n\nconst DEFAULT_MESSAGES_PAGE_SIZE = 40\nconst MAX_MESSAGES_PAGE_SIZE = 100\nexport const DEFAULT_CONVERSATION_TITLE = '新会话'\nconst TEMPORARY_TITLE_MAX_CHARS = 24\nexport const TEMPORARY_TITLE_FALLBACK = DEFAULT_CONVERSATION_TITLE\n\nexport function emptySnapshot(): ConversationSnapshot {\n return { schema_version: 1, messages: [], runs: [] }\n}\n\nexport function hasRunningRuns(snapshot: ConversationSnapshot): boolean {\n return snapshot.runs.some((run) => run.status === 'running')\n}\n\nexport function hasQueuedRuns(snapshot: ConversationSnapshot): boolean {\n return snapshot.runs.some((run) => run.status === 'queued')\n}\n\nexport function isRetryableUserMessage(message: LinkMessage): boolean {\n return (\n message.role === 'user' &&\n message.raw?.format !== 'hermes-link-slash-command' &&\n (messageText(message).length > 0 ||\n message.parts.some((part) => Boolean(part.blob)))\n )\n}\n\nexport function normalizeMessagesPageLimit(value?: number): number {\n if (value === undefined || !Number.isFinite(value)) {\n return DEFAULT_MESSAGES_PAGE_SIZE\n }\n return Math.max(1, Math.min(MAX_MESSAGES_PAGE_SIZE, Math.floor(value)))\n}\n\nexport function toSummary(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n profile: ConversationProfileSummary,\n): ConversationSummary {\n const stats = buildConversationStats(manifest, snapshot)\n const lastMessage = [...snapshot.messages]\n .reverse()\n .find((message) =>\n message.parts.some((part) => part.type === 'text' && part.text),\n )\n return {\n id: manifest.id,\n title: manifest.title,\n created_at: manifest.created_at,\n updated_at: manifest.updated_at,\n last_event_seq: manifest.last_event_seq,\n usage: {\n input_tokens: stats.input_tokens,\n output_tokens: stats.output_tokens,\n total_tokens: stats.total_tokens,\n ...(stats.updated_at ? { updated_at: stats.updated_at } : {}),\n },\n profile,\n last_message: lastMessage\n ? {\n id: lastMessage.id,\n role: lastMessage.role,\n content_preview: previewText(lastMessage),\n }\n : null,\n }\n}\n\nexport function isDefaultConversationTitle(title: string): boolean {\n const normalized = title.trim().toLowerCase()\n return (\n !normalized ||\n normalized === 'untitled' ||\n normalized === DEFAULT_CONVERSATION_TITLE.toLowerCase()\n )\n}\n\nexport function temporaryTitleFromUserMessage(\n content: string,\n): string | undefined {\n const normalized = content\n .replace(MEDIA_TAG_PATTERN, ' ')\n .replace(/\\s+/gu, ' ')\n .trim()\n if (!normalized) {\n return TEMPORARY_TITLE_FALLBACK\n }\n const chars = Array.from(normalized)\n return chars.length <= TEMPORARY_TITLE_MAX_CHARS\n ? normalized\n : `${chars.slice(0, TEMPORARY_TITLE_MAX_CHARS).join('')}…`\n}\n\nexport function previewText(message: LinkMessage): string {\n return messageText(message).slice(0, 160)\n}\n\nexport function messageText(message: LinkMessage): string {\n return message.parts\n .filter((part) => part.type === 'text' && part.text)\n .map((part) => part.text)\n .join('')\n .trim()\n}\n","import { execFile, spawn } from 'node:child_process'\nimport { access, readFile, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { promisify } from 'node:util'\nimport { LinkHttpError } from '../core/errors.js'\nimport {\n createRotatingTextLogWriter,\n getGatewayRuntimeLogFile,\n type FileLogger,\n} from '../runtime/logger.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport {\n ensureHermesApiServerConfig,\n resolveHermesProfileDir,\n type HermesApiServerConfig,\n type EnsureHermesConfigResult,\n} from './config.js'\nimport { resolveHermesBin } from './cli.js'\n\nconst execFileAsync = promisify(execFile)\nconst DEFAULT_START_TIMEOUT_MS = 12_000\nconst HEALTH_TIMEOUT_MS = 1_500\nconst MIN_API_SERVER_VERSION = '0.4.0'\nconst PROFILE_NAME_PATTERN = /^[a-zA-Z0-9._-]{1,64}$/u\n\nconst gatewayStartInFlightByProfile = new Map<\n string,\n Promise<GatewayStartResult>\n>()\n\nexport interface HermesApiAvailability {\n available: boolean\n configResult: EnsureHermesConfigResult\n started: boolean\n start?: GatewayStartResult\n health?: HermesApiHealth\n}\n\nexport interface HermesApiHealth {\n healthy: boolean\n terminal?: boolean\n issue?: string\n authInvalid?: boolean\n detailed?: Record<string, unknown>\n}\n\nexport interface GatewayStartResult {\n pid: number | null\n logPath: string\n version: HermesVersionInfo | null\n}\n\nexport interface HermesVersionInfo {\n raw: string\n version: string | null\n supportsApiServer: boolean | null\n}\n\nexport interface EnsureHermesApiAvailableOptions {\n fetchImpl?: typeof fetch\n paths?: RuntimePaths\n profileName?: string\n timeoutMs?: number\n autoStart?: boolean\n forceRestart?: boolean\n logger?: FileLogger\n}\n\nexport async function ensureHermesApiServerAvailable(\n options: EnsureHermesApiAvailableOptions = {},\n): Promise<HermesApiAvailability> {\n const profileName = normalizeProfileName(options.profileName)\n await assertProfileExists(profileName)\n const configResult = await ensureHermesApiServerConfig(profileName)\n const fetcher = options.fetchImpl ?? fetch\n void options.logger?.debug('gateway_health_check_started', {\n profile: profileName,\n port: configResult.apiServer.port ?? null,\n force_restart: options.forceRestart ?? false,\n })\n let health = await readHermesApiServerHealth(configResult.apiServer, fetcher)\n if (!options.forceRestart && health.healthy) {\n void options.logger?.debug('gateway_health_check_succeeded', {\n profile: profileName,\n port: configResult.apiServer.port ?? null,\n })\n return { available: true, configResult, started: false, health }\n }\n void options.logger?.warn('gateway_health_check_failed', {\n profile: profileName,\n port: configResult.apiServer.port ?? null,\n terminal: health.terminal ?? false,\n issue: health.issue ?? 'unknown',\n })\n\n if (!shouldAutoStart(options.autoStart)) {\n void options.logger?.warn('gateway_auto_start_skipped', {\n profile: profileName,\n reason: 'auto_start_disabled',\n issue: health.issue ?? 'unknown',\n })\n throw new LinkHttpError(\n 503,\n 'hermes_api_server_unavailable',\n `${unavailableMessage()}${health.issue ? ` ${health.issue}` : ''}`,\n )\n }\n\n void options.logger?.info('gateway_auto_start_requested', {\n profile: profileName,\n command: formatHermesGatewayRunCommand(profileName),\n })\n const start = await startHermesGatewayOnce(\n options.paths ?? resolveRuntimePaths(),\n profileName,\n options.logger,\n )\n health = await waitForHermesApiHealth(\n configResult.apiServer,\n fetcher,\n options.timeoutMs ?? DEFAULT_START_TIMEOUT_MS,\n )\n if (health.healthy) {\n void options.logger?.info('gateway_auto_start_succeeded', {\n profile: profileName,\n pid: start.pid,\n log_path: start.logPath,\n hermes_version: start.version?.version ?? null,\n })\n return { available: true, configResult, started: true, start, health }\n }\n const logHint = await readRecentGatewayLogHint(start.logPath)\n void options.logger?.error('gateway_auto_start_failed', {\n profile: profileName,\n pid: start.pid,\n log_path: start.logPath,\n issue: health.issue ?? 'unknown',\n ...(logHint ? { log_hint: logHint } : {}),\n })\n\n throw new LinkHttpError(\n 503,\n 'hermes_api_server_unavailable',\n `${unavailableMessage()} Link tried to start it with \\`${formatHermesGatewayRunCommand(profileName)}\\`, but it did not become ready.${health.issue ? ` ${health.issue}` : ''}${logHint ? ` 最近 Gateway 日志:${logHint}` : ''} Gateway log: ${start.logPath}`,\n )\n}\n\nexport async function reloadHermesGateway(\n options: EnsureHermesApiAvailableOptions = {},\n): Promise<HermesApiAvailability> {\n const profileName = normalizeProfileName(options.profileName)\n void options.logger?.info('gateway_restart_requested', {\n profile: profileName,\n })\n const serviceRestart = await restartHermesGatewayServiceIfAvailable(options)\n if (serviceRestart) {\n const configResult = await ensureHermesApiServerConfig(profileName)\n const fetcher = options.fetchImpl ?? fetch\n const health = await waitForHermesApiHealth(\n configResult.apiServer,\n fetcher,\n options.timeoutMs ?? DEFAULT_START_TIMEOUT_MS,\n )\n if (health.healthy) {\n void options.logger?.info('gateway_restart_succeeded', {\n method: 'service',\n log_path: serviceRestart.logPath,\n hermes_version: serviceRestart.version?.version ?? null,\n })\n return {\n available: true,\n configResult,\n started: true,\n start: serviceRestart,\n health,\n }\n }\n void options.logger?.error('gateway_restart_failed', {\n method: 'service',\n log_path: serviceRestart.logPath,\n issue: health.issue ?? 'unknown',\n ...(serviceRestart.logHint ? { log_hint: serviceRestart.logHint } : {}),\n })\n throw new LinkHttpError(\n 503,\n 'hermes_api_server_unavailable',\n `Hermes Gateway 服务重启已执行,但 API Server 没有恢复可用。${health.issue ? ` ${health.issue}` : ''}${serviceRestart.logHint ? ` 最近 Gateway 日志:${serviceRestart.logHint}` : ''}`,\n )\n }\n return ensureHermesApiServerAvailable({ ...options, forceRestart: true })\n}\n\nexport async function readHermesVersion(): Promise<HermesVersionInfo> {\n const { stdout } = await execHermesVersion()\n const raw = stdout.trim()\n const version = parseHermesVersion(raw)\n return {\n raw,\n version,\n supportsApiServer: version\n ? compareSemver(version, MIN_API_SERVER_VERSION) >= 0\n : null,\n }\n}\n\nasync function execHermesVersion(): Promise<{ stdout: string }> {\n try {\n return await execFileAsync(resolveHermesBin(), ['version'], {\n timeout: 5_000,\n windowsHide: true,\n })\n } catch {\n return await execFileAsync(resolveHermesBin(), ['--version'], {\n timeout: 5_000,\n windowsHide: true,\n })\n }\n}\n\nexport function assertHermesRunsApiSupported(\n version: HermesVersionInfo | null,\n status: number,\n): void {\n if (status !== 404) {\n return\n }\n const versionText = version?.version\n ? `当前检测到 Hermes Agent ${version.version}。`\n : ''\n throw new LinkHttpError(\n 502,\n 'hermes_runs_api_unsupported',\n `${versionText}当前 Hermes Agent API Server 不支持 HermesPilot 需要的 /v1/runs 接口,请先运行 \\`hermes update\\` 升级 Hermes Agent。`,\n )\n}\n\nasync function startHermesGatewayOnce(\n paths: RuntimePaths,\n profileName: string,\n logger?: FileLogger,\n): Promise<GatewayStartResult> {\n if (!gatewayStartInFlightByProfile.has(profileName)) {\n gatewayStartInFlightByProfile.set(\n profileName,\n startHermesGateway(paths, profileName, logger).finally(() => {\n gatewayStartInFlightByProfile.delete(profileName)\n }),\n )\n }\n return await gatewayStartInFlightByProfile.get(profileName)!\n}\n\nasync function startHermesGateway(\n paths: RuntimePaths,\n profileName: string,\n logger?: FileLogger,\n): Promise<GatewayStartResult> {\n const version = await readHermesVersion().catch((error: unknown) => {\n void logger?.error('gateway_hermes_cli_unavailable', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw new LinkHttpError(\n 503,\n 'hermes_agent_not_available',\n `没有找到可用的 Hermes Agent CLI。请先安装 Hermes Agent,或设置 HERMES_BIN。${formatErrorSuffix(error)}`,\n )\n })\n if (version.supportsApiServer === false) {\n void logger?.error('gateway_hermes_agent_too_old', {\n hermes_version: version.version,\n })\n throw new LinkHttpError(\n 503,\n 'hermes_agent_too_old',\n `当前 Hermes Agent ${version.version} 太旧,可能不支持 Hermes API Server。请先运行 \\`hermes update\\` 升级。`,\n )\n }\n\n const gatewayLog = createRotatingTextLogWriter({\n paths,\n fileName: path.basename(getGatewayRuntimeLogFile(paths)),\n })\n const logPath = gatewayLog.filePath\n try {\n const child = spawn(resolveHermesBin(), gatewayRunArgs(profileName), {\n detached: true,\n env: process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n })\n child.stdout?.on('data', (chunk: Buffer) => {\n void gatewayLog.write(chunk)\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n void gatewayLog.write(chunk)\n })\n child.once('exit', (code, signal) => {\n void gatewayLog.flush()\n void logger?.warn('gateway_process_exited', {\n pid: child.pid ?? null,\n code,\n signal,\n log_path: logPath,\n })\n })\n await new Promise<void>((resolve, reject) => {\n let settled = false\n const finish = (callback: () => void) => {\n if (settled) {\n return\n }\n settled = true\n callback()\n }\n child.once('spawn', () => finish(resolve))\n child.once('error', (error) => finish(() => reject(error)))\n })\n child.unref()\n void logger?.info('gateway_process_spawned', {\n profile: profileName,\n pid: child.pid ?? null,\n log_path: logPath,\n hermes_version: version.version,\n })\n return { pid: child.pid ?? null, logPath, version }\n } finally {\n await gatewayLog.flush().catch(() => undefined)\n }\n}\n\nasync function restartHermesGatewayServiceIfAvailable(\n options: EnsureHermesApiAvailableOptions,\n): Promise<(GatewayStartResult & { logHint?: string }) | null> {\n const profileName = normalizeProfileName(options.profileName)\n if (process.platform !== 'darwin') {\n return null\n }\n if (profileName !== 'default') {\n return null\n }\n const home = process.env.HOME\n if (!home) {\n return null\n }\n const launchdPlistPath = path.join(\n home,\n 'Library',\n 'LaunchAgents',\n 'ai.hermes.gateway.plist',\n )\n if (!(await fileExists(launchdPlistPath))) {\n return null\n }\n try {\n await execFileAsync(resolveHermesBin(), ['gateway', 'restart'], {\n timeout: options.timeoutMs ?? DEFAULT_START_TIMEOUT_MS,\n windowsHide: true,\n })\n } catch (error) {\n void options.logger?.error('gateway_service_restart_failed', {\n error: error instanceof Error ? error.message : String(error),\n })\n throw new LinkHttpError(\n 503,\n 'hermes_gateway_restart_failed',\n `Hermes Gateway 服务重启失败。${formatErrorSuffix(error)}`,\n )\n }\n const logPath = path.join(home, '.hermes', 'logs', 'gateway.error.log')\n const logHint = await readRecentGatewayLogHint(logPath)\n return {\n pid: null,\n logPath,\n version: await readHermesVersion().catch(() => null),\n ...(logHint ? { logHint } : {}),\n }\n}\n\nfunction normalizeProfileName(profileName?: string): string {\n const value = profileName?.trim()\n const normalized = value || 'default'\n if (!PROFILE_NAME_PATTERN.test(normalized)) {\n throw new Error('invalid profile name')\n }\n return normalized\n}\n\nasync function assertProfileExists(profileName: string): Promise<void> {\n if (profileName === 'default') {\n return\n }\n const exists = await stat(resolveHermesProfileDir(profileName))\n .then((value) => value.isDirectory())\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n if (!exists) {\n throw new LinkHttpError(\n 404,\n 'profile_not_found',\n `Profile \"${profileName}\" does not exist`,\n )\n }\n}\n\nfunction gatewayRunArgs(profileName: string): string[] {\n return profileName === 'default'\n ? ['gateway', 'run', '--replace']\n : ['-p', profileName, 'gateway', 'run', '--replace']\n}\n\nfunction formatHermesGatewayRunCommand(profileName: string): string {\n return `${resolveHermesBin()} ${gatewayRunArgs(profileName).join(' ')}`\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n return access(filePath)\n .then(() => true)\n .catch(() => false)\n}\n\nasync function waitForHermesApiHealth(\n config: HermesApiServerConfig,\n fetcher: typeof fetch,\n timeoutMs: number,\n): Promise<HermesApiHealth> {\n const deadline = Date.now() + timeoutMs\n let health = await readHermesApiServerHealth(config, fetcher)\n while (!health.healthy && !health.terminal && Date.now() < deadline) {\n await delay(400)\n health = await readHermesApiServerHealth(config, fetcher)\n }\n return health\n}\n\nexport async function readHermesApiServerHealth(\n config?: HermesApiServerConfig,\n fetcher: typeof fetch = fetch,\n): Promise<HermesApiHealth> {\n const resolvedConfig =\n config ?? (await ensureHermesApiServerConfig()).apiServer\n const detailed = await fetchWithTimeout(\n `http://127.0.0.1:${resolvedConfig.port}/health/detailed`,\n {\n method: 'GET',\n headers: authHeaders(resolvedConfig),\n },\n fetcher,\n )\n if (detailed?.ok) {\n const payload = await detailed.json().catch(() => null)\n const record = toRecord(payload)\n if (!isHermesApiServerHealthPayload(record, { allowStatusOnly: false })) {\n return {\n healthy: false,\n terminal: true,\n issue:\n '当前端口返回了非 Hermes API Server 的健康检查响应,可能被其他本机服务占用。',\n detailed: record,\n }\n }\n const issue = describeDetailedHealthIssue(record)\n const terminal = isTerminalDetailedHealth(record)\n return {\n healthy: !issue,\n terminal,\n ...(issue ? { issue } : {}),\n detailed: record,\n }\n }\n if (detailed?.status === 401) {\n return {\n healthy: false,\n authInvalid: true,\n issue:\n 'Hermes API Server 返回 401,当前端口可能属于另一个 Profile,或 API Server key 已变更。',\n }\n }\n\n const basic = await fetchWithTimeout(\n `http://127.0.0.1:${resolvedConfig.port}/health`,\n {\n method: 'GET',\n headers: authHeaders(resolvedConfig),\n },\n fetcher,\n )\n if (basic?.ok) {\n const payload = await basic\n .clone()\n .json()\n .catch(() => null)\n const record = toRecord(payload)\n if (\n !isHermesApiServerHealthPayload(record, {\n allowStatusOnly: true,\n })\n ) {\n return {\n healthy: false,\n terminal: true,\n issue:\n '当前端口返回了非 Hermes API Server 的健康检查响应,可能被其他本机服务占用。',\n detailed: record,\n }\n }\n if (resolvedConfig.key) {\n const authProbe = await fetchWithTimeout(\n `http://127.0.0.1:${resolvedConfig.port}/v1/models`,\n {\n method: 'GET',\n headers: authHeaders(resolvedConfig),\n },\n fetcher,\n )\n if (authProbe?.status === 401) {\n return {\n healthy: false,\n authInvalid: true,\n issue:\n 'Hermes API Server 返回 401,当前端口可能属于另一个 Profile,或 API Server key 已变更。',\n }\n }\n }\n return { healthy: true }\n }\n if (basic?.status === 401) {\n return {\n healthy: false,\n authInvalid: true,\n issue:\n 'Hermes API Server 返回 401,当前端口可能属于另一个 Profile,或 API Server key 已变更。',\n }\n }\n return {\n healthy: false,\n issue: describePortHealthFailure(resolvedConfig.port),\n }\n}\n\nfunction fetchWithTimeout(\n input: string,\n init: RequestInit,\n fetcher: typeof fetch,\n): Promise<Response | null> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), HEALTH_TIMEOUT_MS)\n return fetcher(input, { ...init, signal: controller.signal })\n .catch(() => null)\n .finally(() => clearTimeout(timer))\n}\n\nfunction authHeaders(config: HermesApiServerConfig): Headers {\n const headers = new Headers()\n headers.set('accept', 'application/json')\n if (config.key) {\n headers.set('x-api-key', config.key)\n headers.set('authorization', `Bearer ${config.key}`)\n }\n return headers\n}\n\nfunction shouldAutoStart(value: boolean | undefined): boolean {\n if (value !== undefined) {\n return value\n }\n const raw = process.env.HERMESLINK_GATEWAY_AUTOSTART?.trim().toLowerCase()\n return raw !== '0' && raw !== 'false' && raw !== 'off'\n}\n\nfunction unavailableMessage(): string {\n return 'Hermes API Server 当前不可用。请确认 Hermes Agent 已安装,并可通过 `hermes gateway run` 启动;HermesPilot Link 需要 Hermes Agent 的本机 API Server。'\n}\n\nfunction isHermesApiServerHealthPayload(\n payload: Record<string, unknown>,\n options: { allowStatusOnly: boolean },\n): boolean {\n return (\n payload.platform === 'hermes-agent' ||\n (options.allowStatusOnly &&\n (payload.status === 'ok' || payload.ok === true))\n )\n}\n\nfunction describePortHealthFailure(port: number | undefined): string {\n return port\n ? `Hermes API Server 端口 ${port} 没有响应;如果这是刚创建的 Profile,可能是 Gateway 尚未启动、端口被其他进程占用,或 Profile 的 API Server port 配置不正确。`\n : 'Hermes API Server 端口没有响应。'\n}\n\nfunction describeDetailedHealthIssue(\n payload: Record<string, unknown>,\n): string | null {\n const gatewayState = readString(payload, 'gateway_state')\n const exitReason = readString(payload, 'exit_reason')\n const platforms = toRecord(payload.platforms)\n const apiServer = toRecord(platforms.api_server)\n const apiServerState = readString(apiServer, 'state')\n const apiServerError = readString(apiServer, 'error_message')\n const platformIssue = firstFatalPlatformIssue(platforms)\n const parts: string[] = []\n\n if (gatewayState && gatewayState !== 'running') {\n parts.push(`Gateway 状态是 ${gatewayState}`)\n }\n if (apiServerState && !isHealthyPlatformState(apiServerState)) {\n parts.push(\n `API Server 状态是 ${apiServerState}${apiServerError ? `:${apiServerError}` : ''}`,\n )\n }\n if (exitReason) {\n parts.push(`退出原因:${exitReason}`)\n } else if (platformIssue) {\n parts.push(platformIssue)\n }\n\n return parts.length > 0\n ? `Hermes Gateway 未就绪:${dedupe(parts).join(';')}。`\n : null\n}\n\nfunction isTerminalDetailedHealth(payload: Record<string, unknown>): boolean {\n const gatewayState = readString(payload, 'gateway_state')\n const platforms = toRecord(payload.platforms)\n const apiServerState = readString(toRecord(platforms.api_server), 'state')\n return (\n gatewayState === 'startup_failed' ||\n apiServerState === 'fatal' ||\n apiServerState === 'failed'\n )\n}\n\nfunction firstFatalPlatformIssue(\n platforms: Record<string, unknown>,\n): string | null {\n for (const [name, value] of Object.entries(platforms)) {\n const platform = toRecord(value)\n const state = readString(platform, 'state')\n if (state !== 'fatal' && state !== 'failed') {\n continue\n }\n const message = readString(platform, 'error_message')\n return `${name} 状态是 ${state}${message ? `:${message}` : ''}`\n }\n return null\n}\n\nfunction isHealthyPlatformState(value: string): boolean {\n return ['connected', 'running', 'ready', 'ok', 'healthy'].includes(\n value.toLowerCase(),\n )\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction dedupe(values: string[]): string[] {\n return Array.from(new Set(values))\n}\n\nasync function readRecentGatewayLogHint(\n logPath: string,\n): Promise<string | null> {\n const raw = await readFile(logPath, 'utf8').catch(() => '')\n if (!raw.trim()) {\n return null\n }\n const interesting = raw\n .split('\\n')\n .map((line) => line.trim())\n .filter(\n (line) =>\n line &&\n !line.startsWith('│') &&\n !line.startsWith('┌') &&\n !line.startsWith('├') &&\n !line.startsWith('└') &&\n /(ERROR|WARNING|failed|Port \\d+ already in use|already in use|Traceback)/iu.test(\n line,\n ),\n )\n .slice(-6)\n return interesting.length > 0 ? dedupe(interesting).join(';') : null\n}\n\nfunction parseHermesVersion(value: string): string | null {\n const match = /\\bv?(\\d+\\.\\d+\\.\\d+)\\b/u.exec(value)\n return match?.[1] ?? null\n}\n\nfunction compareSemver(left: string, right: string): number {\n const leftParts = left.split('.').map((part) => Number.parseInt(part, 10))\n const rightParts = right.split('.').map((part) => Number.parseInt(part, 10))\n for (let index = 0; index < 3; index += 1) {\n const diff = (leftParts[index] || 0) - (rightParts[index] || 0)\n if (diff !== 0) {\n return diff\n }\n }\n return 0\n}\n\nfunction formatErrorSuffix(error: unknown): string {\n if (!(error instanceof Error) || !error.message) {\n return ''\n }\n return ` 原始错误:${error.message}`\n}\n","import { appendFile, mkdir, open, readFile, rename, rm, stat } from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { resolveRuntimePaths, type RuntimePaths } from './paths.js'\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error'\nexport type LogTimestampSource = 'structured' | 'embedded' | 'file_mtime'\n\nexport interface LogEntry {\n ts: string | null\n level: LogLevel\n message: string\n fields?: Record<string, JsonValue>\n timestampSource?: LogTimestampSource\n}\n\ntype JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }\n\nexport interface FileLoggerOptions {\n paths?: RuntimePaths\n fileName?: string\n maxFileBytes?: number\n maxFiles?: number\n now?: () => Date\n}\n\nexport interface ReadLogOptions {\n paths?: RuntimePaths\n fileName?: string\n filePaths?: string[]\n limit?: number\n maxFiles?: number\n maxBytesPerFile?: number\n}\n\nexport interface RotatingTextLogOptions {\n paths?: RuntimePaths\n fileName: string\n maxFileBytes?: number\n maxFiles?: number\n}\n\nexport interface RotatingTextLogWriter {\n readonly filePath: string\n write(chunk: string | Uint8Array): Promise<void>\n flush(): Promise<void>\n}\n\nconst DEFAULT_LOG_FILE = 'hermeslink.log'\nconst DEFAULT_MAX_FILE_BYTES = 1024 * 1024\nconst DEFAULT_MAX_FILES = 5\nconst DEFAULT_READ_LIMIT = 200\nconst MAX_READ_LIMIT = 1000\nconst DEFAULT_MAX_BYTES_PER_FILE = 512 * 1024\nconst GATEWAY_LOG_FILE = 'hermes-gateway.log'\nconst DAEMON_LOG_FILE = 'daemon.log'\n\nexport class FileLogger {\n readonly filePath: string\n private readonly paths: RuntimePaths\n private readonly maxFileBytes: number\n private readonly maxFiles: number\n private readonly now: () => Date\n private queue = Promise.resolve()\n\n constructor(options: FileLoggerOptions = {}) {\n this.paths = options.paths ?? resolveRuntimePaths()\n this.filePath = getLinkLogFile(this.paths, options.fileName)\n this.maxFileBytes = Math.max(256, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES))\n this.maxFiles = Math.max(0, Math.floor(options.maxFiles ?? DEFAULT_MAX_FILES))\n this.now = options.now ?? (() => new Date())\n }\n\n debug(message: string, fields?: Record<string, unknown>): Promise<void> {\n return this.write('debug', message, fields)\n }\n\n info(message: string, fields?: Record<string, unknown>): Promise<void> {\n return this.write('info', message, fields)\n }\n\n warn(message: string, fields?: Record<string, unknown>): Promise<void> {\n return this.write('warn', message, fields)\n }\n\n error(message: string, fields?: Record<string, unknown>): Promise<void> {\n return this.write('error', message, fields)\n }\n\n write(level: LogLevel, message: string, fields?: Record<string, unknown>): Promise<void> {\n const entry: LogEntry = {\n ts: this.now().toISOString(),\n level,\n message,\n ...(fields ? { fields: sanitizeFields(fields) } : {}),\n }\n const next = this.queue.then(() => this.appendEntry(entry)).catch(() => undefined)\n this.queue = next\n return next\n }\n\n flush(): Promise<void> {\n return this.queue\n }\n\n private async appendEntry(entry: LogEntry): Promise<void> {\n await mkdir(this.paths.logsDir, { recursive: true, mode: 0o700 })\n const line = `${JSON.stringify(entry)}\\n`\n await this.rotateIfNeeded(Buffer.byteLength(line, 'utf8'))\n await appendFile(this.filePath, line, { mode: 0o600 })\n }\n\n private async rotateIfNeeded(nextBytes: number): Promise<void> {\n await rotateLogFileIfNeeded(this.filePath, nextBytes, this.maxFileBytes, this.maxFiles)\n }\n}\n\nexport function createFileLogger(options: FileLoggerOptions = {}): FileLogger {\n return new FileLogger(options)\n}\n\nexport function getLinkLogFile(paths: RuntimePaths = resolveRuntimePaths(), fileName = DEFAULT_LOG_FILE): string {\n return path.join(paths.logsDir, fileName)\n}\n\nexport function getDaemonLogFile(paths: RuntimePaths = resolveRuntimePaths()): string {\n return getLinkLogFile(paths, DAEMON_LOG_FILE)\n}\n\nexport function getGatewayRuntimeLogFile(paths: RuntimePaths = resolveRuntimePaths()): string {\n return getLinkLogFile(paths, GATEWAY_LOG_FILE)\n}\n\nexport async function prepareRotatingTextLogFile(options: RotatingTextLogOptions): Promise<string> {\n const paths = options.paths ?? resolveRuntimePaths()\n const filePath = getLinkLogFile(paths, options.fileName)\n await mkdir(paths.logsDir, { recursive: true, mode: 0o700 })\n await rotateLogFileIfNeeded(\n filePath,\n 1,\n Math.max(256, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES)),\n Math.max(0, Math.floor(options.maxFiles ?? DEFAULT_MAX_FILES)),\n )\n return filePath\n}\n\nexport function createRotatingTextLogWriter(options: RotatingTextLogOptions): RotatingTextLogWriter {\n const paths = options.paths ?? resolveRuntimePaths()\n const filePath = getLinkLogFile(paths, options.fileName)\n const maxFileBytes = Math.max(256, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES))\n const maxFiles = Math.max(0, Math.floor(options.maxFiles ?? DEFAULT_MAX_FILES))\n let queue = Promise.resolve()\n\n return {\n filePath,\n write(chunk: string | Uint8Array): Promise<void> {\n const buffer = typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : Buffer.from(chunk)\n if (buffer.length === 0) {\n return queue\n }\n const next = queue\n .then(async () => {\n await mkdir(paths.logsDir, { recursive: true, mode: 0o700 })\n await rotateLogFileIfNeeded(filePath, buffer.length, maxFileBytes, maxFiles)\n await appendFile(filePath, buffer, { mode: 0o600 })\n })\n .catch(() => undefined)\n queue = next\n return next\n },\n flush(): Promise<void> {\n return queue\n },\n }\n}\n\nexport async function readRecentLogEntries(options: ReadLogOptions = {}): Promise<LogEntry[]> {\n const paths = options.paths ?? resolveRuntimePaths()\n const filePath = getLinkLogFile(paths, options.fileName)\n const limit = clampLimit(options.limit)\n const maxFiles = Math.max(0, Math.floor(options.maxFiles ?? DEFAULT_MAX_FILES))\n const maxBytesPerFile = Math.max(1024, Math.floor(options.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE))\n const files = [filePath, ...Array.from({ length: maxFiles }, (_, index) => rotatedLogFile(filePath, index + 1))]\n const entries: LogEntry[] = []\n\n for (const file of files) {\n const raw = await readTail(file, maxBytesPerFile)\n if (!raw) {\n continue\n }\n const lines = raw.split(/\\r?\\n/u).filter(Boolean)\n for (let index = lines.length - 1; index >= 0 && entries.length < limit; index -= 1) {\n const entry = parseLogLine(lines[index])\n if (entry) {\n entries.push(entry)\n }\n }\n if (entries.length >= limit) {\n break\n }\n }\n\n return entries.reverse()\n}\n\nexport async function readRecentTextLogEntries(\n options: ReadLogOptions = {},\n): Promise<LogEntry[]> {\n const paths = options.paths ?? resolveRuntimePaths()\n const primaryFiles = options.filePaths ?? [\n getLinkLogFile(paths, options.fileName),\n ]\n const limit = clampLimit(options.limit)\n const maxFiles = Math.max(\n 0,\n Math.floor(options.maxFiles ?? DEFAULT_MAX_FILES),\n )\n const maxBytesPerFile = Math.max(\n 1024,\n Math.floor(options.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE),\n )\n const files = primaryFiles.flatMap((filePath) => [\n filePath,\n ...Array.from({ length: maxFiles }, (_, index) =>\n rotatedLogFile(filePath, index + 1),\n ),\n ])\n const entries: LogEntry[] = []\n\n for (const file of files) {\n const tail = await readTailWithMetadata(file, maxBytesPerFile)\n if (!tail) {\n continue\n }\n const lines = tail.content\n .split(/\\r?\\n/u)\n .map((line) => line.trim())\n .filter(Boolean)\n for (\n let index = lines.length - 1;\n index >= 0 && entries.length < limit;\n index -= 1\n ) {\n entries.push(parseTextLogLine(lines[index], tail.modifiedAt))\n }\n if (entries.length >= limit) {\n break\n }\n }\n\n return entries.reverse()\n}\n\nexport function getGatewayLogFiles(\n paths: RuntimePaths = resolveRuntimePaths(),\n): string[] {\n const runtimeGatewayLog = getGatewayRuntimeLogFile(paths)\n const effectiveHome =\n path.basename(paths.homeDir) === '.hermeslink'\n ? path.dirname(paths.homeDir)\n : os.homedir()\n const hermesGatewayErrorLog = path.join(\n effectiveHome,\n '.hermes',\n 'logs',\n 'gateway.error.log',\n )\n return Array.from(new Set([runtimeGatewayLog, hermesGatewayErrorLog]))\n}\n\nexport function readRecentGatewayLogEntries(\n options: ReadLogOptions = {},\n): Promise<LogEntry[]> {\n const paths = options.paths ?? resolveRuntimePaths()\n return readRecentTextLogEntries({\n ...options,\n paths,\n filePaths: options.filePaths ?? getGatewayLogFiles(paths),\n })\n}\n\nfunction clampLimit(value: number | undefined): number {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n return DEFAULT_READ_LIMIT\n }\n return Math.min(MAX_READ_LIMIT, Math.max(1, Math.floor(value)))\n}\n\nasync function rotateLogFileIfNeeded(\n filePath: string,\n nextBytes: number,\n maxFileBytes: number,\n maxFiles: number,\n): Promise<void> {\n const current = await stat(filePath).catch(() => null)\n if (!current || current.size === 0 || current.size + nextBytes <= maxFileBytes) {\n return\n }\n if (maxFiles === 0) {\n await rm(filePath, { force: true }).catch(() => undefined)\n return\n }\n await rm(rotatedLogFile(filePath, maxFiles), { force: true }).catch(() => undefined)\n for (let index = maxFiles - 1; index >= 1; index -= 1) {\n await moveIfExists(rotatedLogFile(filePath, index), rotatedLogFile(filePath, index + 1))\n }\n await moveIfExists(filePath, rotatedLogFile(filePath, 1))\n}\n\nfunction sanitizeFields(fields: Record<string, unknown>): Record<string, JsonValue> {\n return sanitizeObject(fields, 0)\n}\n\nfunction sanitizeValue(value: unknown, depth: number): JsonValue {\n if (value === null || typeof value === 'boolean') {\n return value\n }\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : null\n }\n if (typeof value === 'string') {\n return value.length > 2000 ? `${value.slice(0, 2000)}...` : value\n }\n if (Array.isArray(value)) {\n if (depth >= 3) {\n return '[array]'\n }\n return value.slice(0, 20).map((item) => sanitizeValue(item, depth + 1))\n }\n if (typeof value === 'object' && value !== null) {\n if (depth >= 3) {\n return '[object]'\n }\n return sanitizeObject(value as Record<string, unknown>, depth + 1)\n }\n return String(value)\n}\n\nfunction sanitizeObject(value: Record<string, unknown>, depth: number): Record<string, JsonValue> {\n const result: Record<string, JsonValue> = {}\n for (const [key, child] of Object.entries(value).slice(0, 50)) {\n if (isSensitiveKey(key)) {\n result[key] = '[redacted]'\n continue\n }\n result[key] = sanitizeValue(child, depth)\n }\n return result\n}\n\nfunction isSensitiveKey(key: string): boolean {\n return /(authorization|cookie|token|secret|password|private[_-]?key|api[_-]?key)/iu.test(key)\n}\n\nfunction parseLogLine(line: string): LogEntry | null {\n try {\n const value = JSON.parse(line) as Partial<LogEntry>\n if (!value || typeof value.ts !== 'string' || !isLogLevel(value.level) || typeof value.message !== 'string') {\n return null\n }\n return {\n ts: value.ts,\n level: value.level,\n message: value.message,\n timestampSource: 'structured',\n ...(value.fields && typeof value.fields === 'object' ? { fields: value.fields as Record<string, JsonValue> } : {}),\n }\n } catch {\n return null\n }\n}\n\nfunction parseTextLogLine(line: string, fallbackTimestamp?: string): LogEntry {\n const embeddedTimestamp = readTimestampFromTextLog(line)\n return {\n ts: embeddedTimestamp ?? fallbackTimestamp ?? null,\n level: inferTextLogLevel(line),\n message: line,\n ...(embeddedTimestamp\n ? { timestampSource: 'embedded' as const }\n : fallbackTimestamp\n ? { timestampSource: 'file_mtime' as const }\n : {}),\n }\n}\n\nfunction readTimestampFromTextLog(line: string): string | null {\n const iso = /\\b\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z\\b/u.exec(line)\n if (iso) {\n return iso[0]\n }\n const bracketed =\n /^\\[?(?<value>\\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?)\\]?/u.exec(\n line,\n )\n if (!bracketed?.groups?.value) {\n return null\n }\n const parsed = new Date(bracketed.groups.value.replace(' ', 'T'))\n return Number.isNaN(parsed.getTime()) ? null : parsed.toISOString()\n}\n\nfunction inferTextLogLevel(line: string): LogLevel {\n if (/\\b(error|fatal|traceback|failed|failure)\\b/iu.test(line)) {\n return 'error'\n }\n if (/\\b(warn|warning)\\b/iu.test(line)) {\n return 'warn'\n }\n if (/\\b(debug|trace)\\b/iu.test(line)) {\n return 'debug'\n }\n return 'info'\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return value === 'debug' || value === 'info' || value === 'warn' || value === 'error'\n}\n\nasync function readTail(filePath: string, maxBytes: number): Promise<string | null> {\n const tail = await readTailWithMetadata(filePath, maxBytes)\n return tail?.content ?? null\n}\n\nasync function readTailWithMetadata(\n filePath: string,\n maxBytes: number,\n): Promise<{ content: string; modifiedAt: string } | null> {\n const info = await stat(filePath).catch(() => null)\n if (!info || info.size <= 0) {\n return null\n }\n const modifiedAt = info.mtime.toISOString()\n if (info.size <= maxBytes) {\n const content = await readFile(filePath, 'utf8').catch(() => null)\n return content === null ? null : { content, modifiedAt }\n }\n const handle = await open(filePath, 'r').catch(() => null)\n if (!handle) {\n return null\n }\n try {\n const length = Math.min(info.size, maxBytes)\n const buffer = Buffer.alloc(length)\n await handle.read(buffer, 0, length, info.size - length)\n return { content: buffer.toString('utf8'), modifiedAt }\n } finally {\n await handle.close()\n }\n}\n\nasync function moveIfExists(from: string, to: string): Promise<void> {\n await rm(to, { force: true }).catch(() => undefined)\n await rename(from, to).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw error\n }\n })\n}\n\nfunction rotatedLogFile(filePath: string, index: number): string {\n return `${filePath}.${index}`\n}\n","import os from 'node:os'\nimport path from 'node:path'\nimport { LINK_RUNTIME_DIR_NAME } from '../constants.js'\n\nexport interface RuntimePaths {\n homeDir: string\n identityFile: string\n configFile: string\n stateFile: string\n credentialsFile: string\n databaseFile: string\n conversationsDir: string\n blobsDir: string\n indexesDir: string\n logsDir: string\n runDir: string\n pairingDir: string\n}\n\nexport function resolveRuntimeHome(): string {\n return process.env.HERMESLINK_HOME?.trim()\n ? path.resolve(process.env.HERMESLINK_HOME)\n : path.join(os.homedir(), LINK_RUNTIME_DIR_NAME)\n}\n\nexport function resolveRuntimePaths(homeDir = resolveRuntimeHome()): RuntimePaths {\n return {\n homeDir,\n identityFile: path.join(homeDir, 'identity.json'),\n configFile: path.join(homeDir, 'config.json'),\n stateFile: path.join(homeDir, 'state.json'),\n credentialsFile: path.join(homeDir, 'credentials.json'),\n databaseFile: path.join(homeDir, 'link.db'),\n conversationsDir: path.join(homeDir, 'conversations'),\n blobsDir: path.join(homeDir, 'blobs'),\n indexesDir: path.join(homeDir, 'indexes'),\n logsDir: path.join(homeDir, 'logs'),\n runDir: path.join(homeDir, 'run'),\n pairingDir: path.join(homeDir, 'pairing'),\n }\n}\n","export const LINK_VERSION = '0.2.3'\nexport const LINK_COMMAND = 'hermeslink'\nexport const LINK_DEFAULT_PORT = 52379\nexport const LINK_RUNTIME_DIR_NAME = '.hermeslink'\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { LinkHttpError } from '../core/errors.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport async function deleteHermesSession(\n sessionId: string,\n profileName = 'default',\n): Promise<void> {\n if (!sessionId.trim()) {\n throw new LinkHttpError(\n 400,\n 'hermes_session_id_required',\n 'Hermes session id is required',\n )\n }\n\n try {\n await execFileAsync(\n resolveHermesBin(),\n [...profileArgs(profileName), 'sessions', 'delete', sessionId, '--yes'],\n {\n timeout: 10_000,\n windowsHide: true,\n },\n )\n } catch (error) {\n throw new LinkHttpError(\n 502,\n 'hermes_session_delete_failed',\n error instanceof Error ? error.message : 'Hermes session delete failed',\n )\n }\n}\n\nexport async function renameHermesSession(\n sessionId: string,\n title: string,\n profileName = 'default',\n): Promise<void> {\n const normalizedSessionId = sessionId.trim()\n const normalizedTitle = title.trim()\n if (!normalizedSessionId) {\n throw new LinkHttpError(\n 400,\n 'hermes_session_id_required',\n 'Hermes session id is required',\n )\n }\n if (!normalizedTitle) {\n throw new LinkHttpError(\n 400,\n 'hermes_session_title_required',\n 'Hermes session title is required',\n )\n }\n\n try {\n await execFileAsync(\n resolveHermesBin(),\n [\n ...profileArgs(profileName),\n 'sessions',\n 'rename',\n normalizedSessionId,\n normalizedTitle,\n ],\n {\n timeout: 10_000,\n windowsHide: true,\n },\n )\n } catch (error) {\n throw new LinkHttpError(\n 502,\n 'hermes_session_rename_failed',\n error instanceof Error ? error.message : 'Hermes session rename failed',\n )\n }\n}\n\nexport function resolveHermesBin(): string {\n return process.env.HERMES_BIN?.trim() || 'hermes'\n}\n\nfunction profileArgs(profileName: string): string[] {\n const normalized = profileName.trim() || 'default'\n return normalized === 'default' ? [] : ['-p', normalized]\n}\n","import { randomUUID } from 'node:crypto'\nimport type { ConversationCommandState, LinkMessage } from './types.js'\n\nconst MODEL_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/@+-]{0,127}$/u\n\nexport function isValidModelId(value: string): boolean {\n return MODEL_ID_PATTERN.test(value)\n}\n\ntype SlashCommandName =\n | 'help'\n | 'new'\n | 'reset'\n | 'retry'\n | 'title'\n | 'profile'\n | 'model'\n | 'verbose'\n | 'yolo'\n | 'reasoning'\n | 'usage'\n | 'restart'\n\nexport type ParsedSlashCommand =\n | { kind: 'command'; name: SlashCommandName; args: string }\n | { kind: 'unsupported'; name: string; args: string }\n | { kind: 'invalid'; name: string; args: string; reason: string }\n\nexport type SlashCommandParseResult =\n | { kind: 'none' }\n | { kind: 'escaped'; content: string }\n | ParsedSlashCommand\n\nconst SUPPORTED_SLASH_COMMANDS = new Set<SlashCommandName>([\n 'help',\n 'new',\n 'reset',\n 'retry',\n 'title',\n 'profile',\n 'model',\n 'verbose',\n 'yolo',\n 'reasoning',\n 'usage',\n 'restart',\n])\n\nconst RESERVED_HERMES_SLASH_COMMANDS = new Set([\n 'agents',\n 'approve',\n 'background',\n 'bg',\n 'branch',\n 'browser',\n 'btw',\n 'clear',\n 'commands',\n 'compress',\n 'config',\n 'copy',\n 'cron',\n 'debug',\n 'deny',\n 'exit',\n 'fast',\n 'fork',\n 'gateway',\n 'gquota',\n 'history',\n 'image',\n 'insights',\n 'paste',\n 'personality',\n 'platforms',\n 'plugins',\n 'provider',\n 'q',\n 'queue',\n 'quit',\n 'reload',\n 'reload-mcp',\n 'reload_mcp',\n 'resume',\n 'rollback',\n 'save',\n 'sb',\n 'set-home',\n 'sethome',\n 'skin',\n 'skills',\n 'snap',\n 'snapshot',\n 'status',\n 'statusbar',\n 'steer',\n 'stop',\n 'tasks',\n 'tools',\n 'toolsets',\n 'undo',\n 'update',\n 'voice',\n])\n\nexport function parseSlashCommandInput(\n content: string,\n): SlashCommandParseResult {\n const trimmed = content.trim()\n if (!trimmed.startsWith('/')) {\n return { kind: 'none' }\n }\n if (trimmed.startsWith('//')) {\n return { kind: 'escaped', content: trimmed.slice(1) }\n }\n const match = /^\\/([A-Za-z][A-Za-z0-9_-]*)(?:\\s+([\\s\\S]*))?$/u.exec(trimmed)\n if (!match) {\n return { kind: 'none' }\n }\n const name = match[1]!.toLowerCase()\n const args = match[2]?.trim() ?? ''\n if (!isSupportedSlashCommandName(name)) {\n return RESERVED_HERMES_SLASH_COMMANDS.has(name)\n ? { kind: 'unsupported', name, args }\n : { kind: 'none' }\n }\n const reason = validateSlashCommandArgs(name, args)\n return reason\n ? { kind: 'invalid', name, args, reason }\n : { kind: 'command', name, args }\n}\n\nexport function createSlashCommandUserMessage(input: {\n conversationId: string\n content: string\n clientMessageId?: string\n createdAt: string\n}): LinkMessage {\n return {\n id: `msg_${randomUUID().replaceAll('-', '')}`,\n schema_version: 1,\n conversation_id: input.conversationId,\n role: 'user',\n status: 'completed',\n client_message_id: input.clientMessageId,\n created_at: input.createdAt,\n updated_at: input.createdAt,\n sender: { id: 'app_user', type: 'human', display_name: 'Me' },\n parts: [{ type: 'text', text: input.content }],\n attachments: [],\n raw: {\n format: 'hermes-link-slash-command',\n payload: { content: input.content },\n },\n }\n}\n\nexport function slashHelpMessage(): string {\n return [\n 'HermesPilot Link 当前支持这些斜杠命令:',\n '/new、/reset:清空当前窗口后续上下文,不新增 App 会话。',\n '/retry:重试上一条用户消息。',\n '/title [name]:查看或设置当前会话标题。',\n '/profile:查看当前 Hermes Profile。',\n '/model [model]:查看或设置当前会话模型偏好。',\n '/verbose [off|new|all|verbose|status]:查看或设置当前会话工具进度偏好。',\n '/yolo [on|off|status]:查看或设置当前会话 YOLO 偏好。',\n '/reasoning [level|show|hide]:查看或设置当前会话 reasoning 偏好。',\n '/usage:查看当前会话用量统计。',\n '/restart:重启 Hermes Gateway。',\n '未命中 Link 支持或保留命令的 / 开头文本会作为普通消息发送;也可以用 // 强制转义,例如 //model hello。',\n ].join('\\n')\n}\n\nexport function freshHermesSessionId(conversationId: string): string {\n return `hp_${conversationId}_${randomUUID().replaceAll('-', '').slice(0, 12)}`\n}\n\nexport function nextVerboseMode(\n current: NonNullable<ConversationCommandState['verbose']>,\n): NonNullable<ConversationCommandState['verbose']> {\n const modes: Array<NonNullable<ConversationCommandState['verbose']>> = [\n 'off',\n 'new',\n 'all',\n 'verbose',\n ]\n const index = modes.indexOf(current)\n return modes[(index + 1) % modes.length] ?? 'new'\n}\n\nexport function reasoningStatusMessage(\n state: NonNullable<ConversationCommandState['reasoning']>,\n): string {\n return `当前 reasoning 偏好:${formatReasoningState(state)}`\n}\n\nexport function formatReasoningState(\n state: NonNullable<ConversationCommandState['reasoning']>,\n): string {\n const level = state.level ?? '未设置'\n const visible =\n state.visible === undefined ? '未设置' : state.visible ? 'show' : 'hide'\n return `level=${level},display=${visible}`\n}\n\nfunction isSupportedSlashCommandName(name: string): name is SlashCommandName {\n return SUPPORTED_SLASH_COMMANDS.has(name as SlashCommandName)\n}\n\nfunction validateSlashCommandArgs(\n name: SlashCommandName,\n args: string,\n): string | null {\n switch (name) {\n case 'help':\n case 'new':\n case 'reset':\n case 'retry':\n case 'profile':\n case 'usage':\n return args ? `/${name} 不接受参数。` : null\n case 'restart':\n return args && args !== 'confirm'\n ? '/restart 只支持直接执行,或写作 /restart confirm。'\n : null\n case 'title':\n return args.length > 120 ? '/title 的标题不能超过 120 个字符。' : null\n case 'model':\n if (!args) {\n return null\n }\n if (/\\s/u.test(args) || !isValidModelId(args)) {\n return '/model 只接受一个模型 ID,例如 /model gpt-5 或 /model anthropic/claude-sonnet-4。'\n }\n return null\n case 'verbose':\n return !args || ['status', 'off', 'new', 'all', 'verbose'].includes(args)\n ? null\n : '/verbose 只支持 off、new、all、verbose 或 status。'\n case 'yolo':\n return !args || ['on', 'off', 'status'].includes(args)\n ? null\n : '/yolo 只支持 on、off 或 status。'\n case 'reasoning':\n return !args ||\n ['show', 'hide', 'auto', 'low', 'medium', 'high', 'xhigh'].includes(\n args,\n )\n ? null\n : '/reasoning 只支持 auto、low、medium、high、xhigh、show 或 hide。'\n }\n}\n","import {\n listHermesModelConfigs,\n resolveHermesProfileDir,\n} from '../hermes/config.js'\nimport { reloadHermesGateway } from '../hermes/gateway.js'\nimport type { FileLogger } from '../runtime/logger.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport {\n buildConversationRuntimeMetadata,\n findConfiguredModel,\n readCurrentConversationRuntime,\n} from './profile-runtime.js'\nimport { buildConversationStats } from './statistics.js'\nimport {\n formatReasoningState,\n nextVerboseMode,\n reasoningStatusMessage,\n type ParsedSlashCommand,\n} from './slash-commands.js'\nimport type {\n ConversationCommandState,\n ConversationEvent,\n ConversationManifest,\n ConversationSnapshot,\n ConversationUsageStats,\n SendMessageResult,\n} from './types.js'\n\ntype CommandActionInput = {\n manifest: ConversationManifest\n snapshot: ConversationSnapshot\n command: ParsedSlashCommand\n rawContent: string\n clientMessageId?: string\n}\n\ntype AppendCommandResultInput = Omit<CommandActionInput, 'command'> & {\n commandName: string\n response: string\n}\n\ntype RenameConversationInput = {\n manifest: ConversationManifest\n snapshot: ConversationSnapshot\n source: 'manual' | 'generated'\n}\n\ntype RenameConversationResult = {\n manifest: ConversationManifest\n event: ConversationEvent\n hermesSynced: boolean\n}\n\nexport interface ConversationCommandDeps {\n readonly paths: RuntimePaths\n readonly logger: FileLogger\n readonly hasActiveRuns: () => boolean\n readonly appendEvent: (\n conversationId: string,\n input: Omit<ConversationEvent, 'seq' | 'conversation_id' | 'created_at'>,\n ) => Promise<ConversationEvent>\n readonly appendCommandResult: (\n input: AppendCommandResultInput,\n ) => Promise<SendMessageResult>\n readonly renameConversation: (\n conversationId: string,\n title: string,\n input: RenameConversationInput,\n ) => Promise<RenameConversationResult>\n readonly readManifest: (\n conversationId: string,\n ) => Promise<ConversationManifest>\n readonly writeManifest: (manifest: ConversationManifest) => Promise<void>\n}\n\nexport class ConversationCommandHandlers {\n constructor(private readonly deps: ConversationCommandDeps) {}\n\n async profileStatusMessage(manifest: ConversationManifest): Promise<string> {\n const runtime = await readCurrentConversationRuntime(this.deps.paths, manifest)\n return [\n `当前会话 Profile:${runtime.profileName}`,\n `显示名称:${runtime.profileDisplayName}`,\n `目录:${resolveHermesProfileDir(runtime.profileName)}`,\n `模型:${runtime.model}`,\n ].join('\\n')\n }\n\n async modelStatusMessage(manifest: ConversationManifest): Promise<string> {\n const runtime = await readCurrentConversationRuntime(this.deps.paths, manifest)\n const configured = await listHermesModelConfigs(runtime.profileName).catch(\n () => null,\n )\n const lines = [\n `当前会话模型:${runtime.model}`,\n manifest.command_state?.model_override\n ? '来源:当前会话 override'\n : '来源:当前会话 Profile 默认模型',\n ]\n if (configured?.models.length) {\n lines.push(\n `已配置模型:${configured.models\n .slice(0, 8)\n .map((model) => model.id)\n .join('、')}`,\n )\n }\n return lines.join('\\n')\n }\n\n async usageStatusMessage(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n ): Promise<string> {\n const stats = buildConversationStats(manifest, snapshot)\n const runtime = await buildConversationRuntimeMetadata(\n this.deps.paths,\n manifest,\n snapshot,\n )\n const context = runtime.context.context_window\n ? ` / ${runtime.context.context_window}`\n : ''\n return [\n `消息数:${stats.message_count}`,\n `Agent run 数:${stats.run_count}`,\n `Token:${stats.total_tokens}(输入 ${stats.input_tokens},输出 ${stats.output_tokens})`,\n `上下文:${runtime.context.input_tokens}${context}`,\n `模型:${runtime.model.id}`,\n `Profile:${runtime.profile.name}`,\n ].join('\\n')\n }\n\n async handleTitleCommand(input: CommandActionInput): Promise<SendMessageResult> {\n const title = input.command.args.trim()\n if (!title) {\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `当前会话标题:${input.manifest.title}`,\n })\n }\n const result = await this.deps.renameConversation(\n input.manifest.id,\n title,\n {\n manifest: input.manifest,\n snapshot: input.snapshot,\n source: 'manual',\n },\n )\n return this.deps.appendCommandResult({\n manifest: await this.deps.readManifest(input.manifest.id),\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `已将当前会话标题改为:${result.manifest.title}`,\n })\n }\n\n async handleModelCommand(input: CommandActionInput): Promise<SendMessageResult> {\n const model = input.command.args.trim()\n if (!model) {\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: await this.modelStatusMessage(input.manifest),\n })\n }\n\n await this.deps.writeManifest({\n ...input.manifest,\n command_state: {\n ...input.manifest.command_state,\n model_override: model,\n },\n updated_at: new Date().toISOString(),\n })\n await this.deps.appendEvent(input.manifest.id, {\n type: 'conversation.updated',\n payload: { command: 'model', model_override: model },\n })\n const runtime = await readCurrentConversationRuntime(\n this.deps.paths,\n input.manifest,\n )\n const configuredModel = await findConfiguredModel(runtime.profileName, model)\n const response = configuredModel\n ? `已切换当前会话模型为 ${model}(${configuredModel.providerName})。`\n : `已记录当前会话模型为 ${model}。如果当前 Hermes Agent API Server 不支持这个模型,下一次回复会返回上游错误。`\n return this.deps.appendCommandResult({\n manifest: await this.deps.readManifest(input.manifest.id),\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response,\n })\n }\n\n async handleVerboseCommand(\n input: CommandActionInput,\n ): Promise<SendMessageResult> {\n const arg = input.command.args.trim()\n const current = input.manifest.command_state?.verbose ?? 'off'\n if (arg === 'status') {\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `当前 verbose 偏好:${current}`,\n })\n }\n const next: NonNullable<ConversationCommandState['verbose']> =\n arg && arg !== 'status'\n ? (arg as NonNullable<ConversationCommandState['verbose']>)\n : nextVerboseMode(current)\n await this.deps.writeManifest({\n ...input.manifest,\n command_state: {\n ...input.manifest.command_state,\n verbose: next,\n },\n updated_at: new Date().toISOString(),\n })\n await this.deps.appendEvent(input.manifest.id, {\n type: 'conversation.updated',\n payload: { command: 'verbose', verbose: next },\n })\n return this.deps.appendCommandResult({\n manifest: await this.deps.readManifest(input.manifest.id),\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `已将当前会话 verbose 偏好设为:${next}`,\n })\n }\n\n async handleYoloCommand(input: CommandActionInput): Promise<SendMessageResult> {\n const arg = input.command.args.trim()\n const current = input.manifest.command_state?.yolo ?? false\n if (arg === 'status') {\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `当前 YOLO 偏好:${current ? 'on' : 'off'}`,\n })\n }\n const next = arg ? arg === 'on' : !current\n await this.deps.writeManifest({\n ...input.manifest,\n command_state: {\n ...input.manifest.command_state,\n yolo: next,\n },\n updated_at: new Date().toISOString(),\n })\n await this.deps.appendEvent(input.manifest.id, {\n type: 'conversation.updated',\n payload: { command: 'yolo', yolo: next },\n })\n return this.deps.appendCommandResult({\n manifest: await this.deps.readManifest(input.manifest.id),\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `已将当前会话 YOLO 偏好设为:${next ? 'on' : 'off'}。`,\n })\n }\n\n async handleReasoningCommand(\n input: CommandActionInput,\n ): Promise<SendMessageResult> {\n const arg = input.command.args.trim()\n const current = input.manifest.command_state?.reasoning ?? {}\n if (!arg) {\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: reasoningStatusMessage(current),\n })\n }\n const next: ConversationCommandState['reasoning'] =\n arg === 'show'\n ? { ...current, visible: true }\n : arg === 'hide'\n ? { ...current, visible: false }\n : {\n ...current,\n level: arg as NonNullable<\n ConversationCommandState['reasoning']\n >['level'],\n }\n await this.deps.writeManifest({\n ...input.manifest,\n command_state: {\n ...input.manifest.command_state,\n reasoning: next,\n },\n updated_at: new Date().toISOString(),\n })\n await this.deps.appendEvent(input.manifest.id, {\n type: 'conversation.updated',\n payload: { command: 'reasoning', reasoning: next },\n })\n return this.deps.appendCommandResult({\n manifest: await this.deps.readManifest(input.manifest.id),\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `已更新当前会话 reasoning 偏好:${formatReasoningState(next)}`,\n })\n }\n\n async restartGatewayFromCommand(\n input: CommandActionInput,\n ): Promise<SendMessageResult> {\n if (this.deps.hasActiveRuns()) {\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: '当前还有运行中的回复。为避免中断,暂不重启 Hermes Gateway。',\n })\n }\n try {\n const runtime = await readCurrentConversationRuntime(\n this.deps.paths,\n input.manifest,\n )\n const result = await reloadHermesGateway({\n paths: this.deps.paths,\n logger: this.deps.logger,\n profileName: runtime.profileName,\n })\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: result.health?.healthy\n ? 'Hermes Gateway 已重启,API Server 当前可用。'\n : 'Hermes Gateway 重启已触发,但 API Server 状态仍需稍后确认。',\n })\n } catch (error) {\n return this.deps.appendCommandResult({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `Hermes Gateway 重启失败:${error instanceof Error ? error.message : String(error)}`,\n })\n }\n }\n}\n","import { deleteHermesSession } from \"../hermes/cli.js\";\nimport { LinkHttpError } from \"../core/errors.js\";\nimport type { FileLogger } from \"../runtime/logger.js\";\nimport type { RuntimePaths } from \"../runtime/paths.js\";\nimport {\n deleteConversationBlobIfUnreferenced,\n listConversationBlobIds,\n materializeConversationBlob,\n normalizeConversationIds,\n pruneConversationBlobReference,\n readConversationBlob,\n readConversationBlobManifest,\n writeConversationBlob,\n} from \"./blob-store.js\";\nimport { ConversationMetadataCoordinator } from \"./conversation-metadata.js\";\nimport { ConversationStore } from \"./conversation-store.js\";\nimport { emptySnapshot } from \"./conversation-view.js\";\nimport { collectBlobIds, mediaKindForMime } from \"./media.js\";\nimport { buildConversationStats } from \"./statistics.js\";\nimport type {\n BulkDeleteConversationResult,\n ConversationEvent,\n DeleteConversationResult,\n LinkMessagePart,\n MessageAttachmentInput,\n} from \"./types.js\";\n\nconst MAX_UPLOADED_BLOB_BYTES = 50 * 1024 * 1024;\n\nexport interface ConversationMaintenanceDeps {\n readonly paths: RuntimePaths;\n readonly logger: FileLogger;\n readonly store: ConversationStore;\n readonly metadata: ConversationMetadataCoordinator;\n readonly withConversationLock: <T>(\n conversationId: string,\n task: () => Promise<T>,\n ) => Promise<T>;\n readonly appendEvent: (\n conversationId: string,\n input: Omit<ConversationEvent, \"seq\" | \"conversation_id\" | \"created_at\">,\n ) => Promise<ConversationEvent>;\n}\n\nexport class ConversationMaintenanceCoordinator {\n constructor(private readonly deps: ConversationMaintenanceDeps) {}\n\n async deleteConversation(\n conversationId: string,\n ): Promise<DeleteConversationResult> {\n return this.deps.withConversationLock(conversationId, () =>\n this.deleteConversationLocked(conversationId),\n );\n }\n\n async deleteConversations(conversationIds: string[]): Promise<{\n deleted_count: number;\n failed_count: number;\n conversations: BulkDeleteConversationResult[];\n }> {\n const normalizedConversationIds = normalizeConversationIds(conversationIds);\n const conversations: BulkDeleteConversationResult[] = [];\n for (const conversationId of normalizedConversationIds) {\n try {\n const deleted = await this.deleteConversation(conversationId);\n conversations.push({\n ...deleted,\n status: \"deleted\",\n });\n } catch (error) {\n conversations.push({\n conversation_id: conversationId,\n status: \"failed\",\n error: {\n code:\n error instanceof LinkHttpError ? error.code : \"internal_error\",\n message: error instanceof Error ? error.message : \"Internal error\",\n },\n });\n }\n }\n\n const deletedCount = conversations.filter(\n (conversation) => conversation.status === \"deleted\",\n ).length;\n return {\n deleted_count: deletedCount,\n failed_count: conversations.length - deletedCount,\n conversations,\n };\n }\n\n async writeBlob(\n conversationId: string,\n input: { bytes: Uint8Array; filename?: string; mime?: string },\n ): Promise<{ id: string; size: number; mime: string; filename: string }> {\n await this.deps.store.readActiveManifest(conversationId);\n const blob = await writeConversationBlob(\n this.deps.paths,\n conversationId,\n input,\n {\n maxBytes: MAX_UPLOADED_BLOB_BYTES,\n },\n );\n await this.deps.appendEvent(conversationId, {\n type: \"blob.created\",\n payload: blob,\n });\n return blob;\n }\n\n async readBlob(\n conversationId: string,\n blobId: string,\n ): Promise<{ bytes: Buffer; mime: string; filename: string; size: number }> {\n await this.deps.store.readActiveManifest(conversationId);\n return readConversationBlob(this.deps.paths, conversationId, blobId);\n }\n\n async deleteUnreferencedBlob(\n conversationId: string,\n blobId: string,\n ): Promise<{ deleted: boolean; blob_id: string }> {\n await this.deps.store.readActiveManifest(conversationId);\n const snapshot = await this.deps.store.readSnapshot(conversationId);\n return deleteConversationBlobIfUnreferenced(\n this.deps.paths,\n conversationId,\n blobId,\n snapshot,\n );\n }\n\n async resolveMessageAttachmentParts(\n conversationId: string,\n attachments: MessageAttachmentInput[],\n ): Promise<LinkMessagePart[]> {\n const parts: LinkMessagePart[] = [];\n const seen = new Set<string>();\n for (const attachment of attachments) {\n const blobId = attachment.blob_id ?? attachment.blobId;\n if (!blobId || seen.has(blobId)) {\n continue;\n }\n seen.add(blobId);\n const manifest = await readConversationBlobManifest(\n this.deps.paths,\n conversationId,\n blobId,\n );\n const mime = manifest.mime || \"application/octet-stream\";\n const localPath = await materializeConversationBlob(\n this.deps.paths,\n conversationId,\n blobId,\n manifest,\n );\n const isVoiceNote = isVoiceAttachmentInput(attachment);\n parts.push({\n type: isVoiceNote ? \"audio\" : mediaKindForMime(mime),\n blob: blobId,\n mime,\n size: manifest.size,\n filename: manifest.filename || blobId,\n local_path: localPath,\n url: `/api/v1/conversations/${encodeURIComponent(conversationId)}/blobs/${encodeURIComponent(blobId)}`,\n ...(isVoiceNote\n ? {\n kind: \"voice\",\n is_voice_note: true,\n ...(readAttachmentDurationMs(attachment) !== undefined\n ? { duration_ms: readAttachmentDurationMs(attachment) }\n : {}),\n ...(readAttachmentWaveform(attachment).length > 0\n ? { waveform: readAttachmentWaveform(attachment) }\n : {}),\n }\n : {}),\n });\n }\n return parts;\n }\n\n private async deleteConversationLocked(\n conversationId: string,\n ): Promise<DeleteConversationResult> {\n const manifest = await this.deps.store.readActiveManifest(conversationId);\n const snapshot = await this.deps.store\n .readSnapshot(conversationId)\n .catch(() => emptySnapshot());\n const referencedBlobIds = new Set([\n ...collectBlobIds(snapshot),\n ...(await this.listConversationBlobIds(conversationId)),\n ]);\n await deleteHermesSession(\n manifest.hermes_session_id,\n manifest.profile_name_snapshot ?? manifest.profile ?? \"default\",\n );\n const deletedAt = new Date().toISOString();\n const stats = buildConversationStats(\n {\n ...manifest,\n status: \"deleted_soft\",\n updated_at: deletedAt,\n deleted_at: deletedAt,\n },\n snapshot,\n );\n const next = {\n ...manifest,\n status: \"deleted_soft\" as const,\n updated_at: deletedAt,\n deleted_at: deletedAt,\n stats,\n };\n await this.deps.store.writeManifest(next);\n const deleteEvent = await this.deps.appendEvent(conversationId, {\n type: \"conversation.deleted\",\n payload: {\n deleted_at: deletedAt,\n hermes_session_id: manifest.hermes_session_id,\n },\n });\n await this.deps.store.writeSnapshot(conversationId, emptySnapshot());\n await this.deps.store.overwriteEvents(conversationId, [deleteEvent]);\n await this.pruneConversationBlobReferences(conversationId, [\n ...referencedBlobIds,\n ]);\n await this.deps.store.removeConversationAttachments(conversationId);\n await this.deps.metadata.persistConversationStats(\n conversationId,\n emptySnapshot(),\n stats,\n );\n return {\n conversation_id: conversationId,\n hermes_deleted: true,\n deleted_at: deletedAt,\n };\n }\n\n private async pruneConversationBlobReferences(\n conversationId: string,\n blobIds: string[],\n ): Promise<void> {\n for (const blobId of blobIds) {\n try {\n await pruneConversationBlobReference(\n this.deps.paths,\n conversationId,\n blobId,\n );\n } catch (error) {\n void this.deps.logger.warn(\"conversation_blob_gc_failed\", {\n conversation_id: conversationId,\n blob_id: blobId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n\n private async listConversationBlobIds(\n conversationId: string,\n ): Promise<string[]> {\n return listConversationBlobIds(this.deps.paths, conversationId);\n }\n}\n\nfunction isVoiceAttachmentInput(attachment: MessageAttachmentInput): boolean {\n return (\n attachment.kind === \"voice\" ||\n attachment.type === \"voice\" ||\n attachment.is_voice_note === true ||\n attachment.isVoiceNote === true\n );\n}\n\nfunction readAttachmentDurationMs(\n attachment: MessageAttachmentInput,\n): number | undefined {\n const value = attachment.duration_ms ?? attachment.durationMs;\n return typeof value === \"number\" && Number.isFinite(value) && value > 0\n ? Math.floor(value)\n : undefined;\n}\n\nfunction readAttachmentWaveform(attachment: MessageAttachmentInput): number[] {\n const value =\n attachment.waveform ??\n attachment.waveform_samples ??\n attachment.waveformSamples;\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((item) =>\n typeof item === \"number\" && Number.isFinite(item)\n ? Math.max(0, Math.min(1, item))\n : undefined,\n )\n .filter((item): item is number => item !== undefined)\n .slice(0, 96);\n}\n","import { LINK_DEFAULT_PORT } from '../constants.js'\nimport type { ConfiguredLanguage } from '../i18n.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\n\nexport interface LinkConfig {\n port: number\n serverBaseUrl: string\n relayBaseUrl: string\n appConnectTokenIssuer: string\n appConnectTokenAudience: string\n language: ConfiguredLanguage\n}\n\nexport const defaultLinkConfig: LinkConfig = {\n port: LINK_DEFAULT_PORT,\n serverBaseUrl: 'https://hermes-server.clawpilot.me',\n relayBaseUrl: 'https://hermes-relay.clawpilot.me',\n appConnectTokenIssuer: 'https://hermes-server.clawpilot.me',\n appConnectTokenAudience: 'hermes-link',\n language: 'auto',\n}\n\nexport async function loadConfig(paths: RuntimePaths = resolveRuntimePaths()): Promise<LinkConfig> {\n const existing = await readJsonFile<Partial<LinkConfig>>(paths.configFile)\n const language = normalizeConfiguredLanguage(existing?.language)\n return {\n ...defaultLinkConfig,\n ...(existing ?? {}),\n language,\n }\n}\n\nexport async function saveConfig(\n patch: Partial<LinkConfig>,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<LinkConfig> {\n const current = await loadConfig(paths)\n const next = { ...current, ...patch }\n await writeJsonFile(paths.configFile, next)\n return next\n}\n\nfunction normalizeConfiguredLanguage(language: unknown): ConfiguredLanguage {\n if (language === 'zh-CN' || language === 'en' || language === 'auto') {\n return language\n }\n return defaultLinkConfig.language\n}\n","import { stat } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport type { DatabaseSync } from 'node:sqlite'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { resolveHermesProfileDir } from './config.js'\n\nconst nodeRequire = createRequire(import.meta.url)\n\nexport async function readHermesSessionTitle(\n sessionId: string,\n paths: RuntimePaths,\n profileName?: string,\n): Promise<string | undefined> {\n const trimmedSessionId = sessionId.trim()\n if (!trimmedSessionId) {\n return undefined\n }\n\n const resolvedProfileName = isValidProfileName(profileName)\n ? profileName\n : 'default'\n const dbPath = path.join(\n resolveHermesProfileDir(resolvedProfileName),\n 'state.db',\n )\n const exists = await stat(dbPath)\n .then((value) => value.isFile())\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n if (!exists) {\n return undefined\n }\n\n return readSessionTitleFromStateDb(dbPath, trimmedSessionId)\n}\n\nexport async function readHermesCompressionTip(\n sessionId: string,\n paths: RuntimePaths,\n profileName?: string,\n): Promise<string | undefined> {\n const trimmedSessionId = sessionId.trim()\n if (!trimmedSessionId) {\n return undefined\n }\n\n const resolvedProfileName = isValidProfileName(profileName)\n ? profileName\n : 'default'\n const dbPath = path.join(\n resolveHermesProfileDir(resolvedProfileName),\n 'state.db',\n )\n const exists = await stat(dbPath)\n .then((value) => value.isFile())\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n if (!exists) {\n return undefined\n }\n\n return readCompressionTipFromStateDb(dbPath, trimmedSessionId)\n}\n\nfunction readSessionTitleFromStateDb(\n dbPath: string,\n sessionId: string,\n): string | undefined {\n let db: DatabaseSync | null = null\n try {\n const { DatabaseSync } = nodeRequire(\n 'node:sqlite',\n ) as typeof import('node:sqlite')\n db = new DatabaseSync(dbPath, {\n readOnly: true,\n timeout: 1_000,\n })\n const row = db\n .prepare('SELECT title FROM sessions WHERE id = ? LIMIT 1')\n .get(sessionId) as Record<string, unknown> | undefined\n const title = typeof row?.title === 'string' ? row.title.trim() : ''\n return title || undefined\n } catch {\n return undefined\n } finally {\n db?.close()\n }\n}\n\nfunction readCompressionTipFromStateDb(\n dbPath: string,\n sessionId: string,\n): string | undefined {\n let db: DatabaseSync | null = null\n try {\n const { DatabaseSync } = nodeRequire(\n 'node:sqlite',\n ) as typeof import('node:sqlite')\n db = new DatabaseSync(dbPath, {\n readOnly: true,\n timeout: 1_000,\n })\n let current = sessionId\n for (let index = 0; index < 100; index += 1) {\n const row = db\n .prepare(\n `\n SELECT child.id\n FROM sessions AS child\n WHERE child.parent_session_id = ?\n AND child.started_at >= (\n SELECT parent.ended_at\n FROM sessions AS parent\n WHERE parent.id = ?\n AND parent.end_reason = 'compression'\n )\n ORDER BY child.started_at DESC\n LIMIT 1\n `,\n )\n .get(current, current) as Record<string, unknown> | undefined\n const next = typeof row?.id === 'string' ? row.id.trim() : ''\n if (!next) {\n return current\n }\n current = next\n }\n return current\n } catch {\n return undefined\n } finally {\n db?.close()\n }\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n\nfunction isValidProfileName(value: string | undefined): value is string {\n return typeof value === 'string' && /^[a-zA-Z0-9._-]{1,64}$/u.test(value)\n}\n","import {\n replaceRunUsageFactsForConversation,\n upsertConversationStats,\n} from '../database/link-database.js'\nimport { loadConfig } from '../config/config.js'\nimport { LinkHttpError } from '../core/errors.js'\nimport { renameHermesSession } from '../hermes/cli.js'\nimport { readHermesSessionTitle } from '../hermes/session-title.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { buildConversationStats, buildRunUsageFacts, latestRuntimeRun, toStatsIndexRecord } from './statistics.js'\nimport type {\n ConversationEvent,\n ConversationManifest,\n ConversationSnapshot,\n ConversationTitleSource,\n ConversationUsageStats,\n} from './types.js'\nimport { isDefaultConversationTitle, messageText, TEMPORARY_TITLE_FALLBACK, temporaryTitleFromUserMessage } from './conversation-view.js'\nimport { ConversationStore } from './conversation-store.js'\n\nconst GENERATED_TITLE_RETRY_DELAYS_MS = [0, 1_000, 3_000] as const\nconst TITLE_GENERATION_SOURCE_MAX_LENGTH = 12_000\nconst SESSION_TITLE_MAX_LENGTH = 120\nconst TITLE_GENERATION_REQUEST_TIMEOUT_MS = 30_000\n\nexport interface ConversationMetadataDeps {\n readonly paths: RuntimePaths\n readonly store: ConversationStore\n readonly appendEvent: (\n conversationId: string,\n input: Omit<ConversationEvent, 'seq' | 'conversation_id' | 'created_at'>,\n ) => Promise<ConversationEvent>\n}\n\nexport class ConversationMetadataCoordinator {\n constructor(private readonly deps: ConversationMetadataDeps) {}\n\n async refreshTitleFromHermes(\n manifest: ConversationManifest,\n options: { emitEvent?: boolean; snapshot?: ConversationSnapshot } = {},\n ): Promise<ConversationManifest> {\n if (\n manifest.title_source === 'manual' ||\n manifest.title_source === 'generated' ||\n manifest.title_source === 'temporary_user_message' ||\n manifest.title_source === 'temporary_fallback'\n ) {\n return manifest\n }\n const snapshot =\n options.snapshot ??\n (await this.deps.store.readSnapshot(manifest.id).catch(() =>\n createEmptySnapshot(),\n ))\n const title = await readHermesSessionTitle(\n manifest.hermes_session_id,\n this.deps.paths,\n latestRuntimeRun(snapshot)?.profile,\n )\n if (!title || title === manifest.title) {\n return manifest\n }\n\n const next: ConversationManifest = {\n ...manifest,\n title,\n title_source: 'hermes',\n }\n await this.deps.store.writeManifest(next)\n await this.persistConversationStats(manifest.id, snapshot)\n\n if (!options.emitEvent) {\n return next\n }\n\n const event = await this.deps.appendEvent(manifest.id, {\n type: 'conversation.updated',\n payload: { title },\n })\n return { ...next, last_event_seq: event.seq, updated_at: event.created_at }\n }\n\n scheduleGeneratedTitleRefresh(conversationId: string): void {\n for (const delay of GENERATED_TITLE_RETRY_DELAYS_MS) {\n setTimeout(() => {\n void this.generateTitleFromFirstRound(conversationId).catch(\n () => undefined,\n )\n }, delay)\n }\n }\n\n async renameConversation(\n conversationId: string,\n title: string,\n input: {\n manifest: ConversationManifest\n snapshot: ConversationSnapshot\n source: 'manual' | 'generated'\n },\n ): Promise<{\n manifest: ConversationManifest\n event: ConversationEvent\n hermesSynced: boolean\n }> {\n const normalizedTitle = normalizeConversationTitle(title)\n if (!normalizedTitle) {\n throw new LinkHttpError(\n 400,\n 'conversation_title_required',\n 'Conversation title is required',\n )\n }\n const sourceChanged = input.manifest.title_source !== input.source\n if (normalizedTitle === input.manifest.title) {\n if (!sourceChanged) {\n return {\n manifest: input.manifest,\n event: {\n seq: input.manifest.last_event_seq,\n type: 'conversation.updated',\n conversation_id: conversationId,\n created_at: input.manifest.updated_at,\n payload: {\n title: normalizedTitle,\n title_source:\n input.manifest.title_source ?? normalizeConversationTitleSource(input.manifest.title),\n hermes_synced: false,\n },\n },\n hermesSynced: false,\n }\n }\n const hermesSynced = await this.syncHermesSessionTitle(\n input.manifest,\n input.snapshot,\n normalizedTitle,\n input.source,\n )\n const event = await this.deps.appendEvent(conversationId, {\n type: 'conversation.updated',\n payload: {\n title: normalizedTitle,\n title_source: input.source,\n hermes_synced: hermesSynced,\n },\n })\n const next: ConversationManifest = {\n ...input.manifest,\n title_source: input.source,\n updated_at: event.created_at,\n last_event_seq: event.seq,\n }\n await this.deps.store.writeManifest(next)\n await this.persistConversationStats(conversationId, input.snapshot)\n return { manifest: next, event, hermesSynced }\n }\n\n const hermesSynced = await this.syncHermesSessionTitle(\n input.manifest,\n input.snapshot,\n normalizedTitle,\n input.source,\n )\n\n const event = await this.deps.appendEvent(conversationId, {\n type: 'conversation.updated',\n payload: {\n title: normalizedTitle,\n title_source: input.source,\n hermes_synced: hermesSynced,\n },\n })\n const next: ConversationManifest = {\n ...input.manifest,\n title: normalizedTitle,\n title_source: input.source,\n updated_at: event.created_at,\n last_event_seq: event.seq,\n }\n await this.deps.store.writeManifest(next)\n await this.persistConversationStats(conversationId, input.snapshot)\n return { manifest: next, event, hermesSynced }\n }\n\n async persistConversationStats(\n conversationId: string,\n snapshot: ConversationSnapshot,\n statsOverride?: ConversationUsageStats,\n ): Promise<void> {\n const manifest = await this.deps.store.readManifest(conversationId).catch(\n () => null,\n )\n if (!manifest) {\n return\n }\n const stats = statsOverride ?? buildConversationStats(manifest, snapshot)\n await this.deps.store.writeManifest({ ...manifest, stats })\n await upsertConversationStats(\n this.deps.paths,\n toStatsIndexRecord({ ...manifest, stats }, stats),\n )\n const usageFacts = buildRunUsageFacts({ ...manifest, stats }, snapshot)\n if (usageFacts.length > 0) {\n await replaceRunUsageFactsForConversation(\n this.deps.paths,\n conversationId,\n usageFacts,\n )\n }\n }\n\n async applyTemporaryTitleFromFirstMessage(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n content: string,\n ): Promise<ConversationManifest> {\n if (!isDefaultConversationTitle(manifest.title)) {\n return manifest\n }\n const userMessageCount = snapshot.messages.filter(\n (message) => message.role === 'user',\n ).length\n if (userMessageCount !== 1) {\n return manifest\n }\n const title = temporaryTitleFromUserMessage(content)\n if (!title || title === manifest.title) {\n return manifest\n }\n const event = await this.deps.appendEvent(manifest.id, {\n type: 'conversation.updated',\n payload: {\n title,\n title_source:\n title === TEMPORARY_TITLE_FALLBACK\n ? 'temporary_fallback'\n : 'temporary_user_message',\n },\n })\n const next: ConversationManifest = {\n ...manifest,\n title,\n title_source:\n title === TEMPORARY_TITLE_FALLBACK\n ? 'temporary_fallback'\n : 'temporary_user_message',\n updated_at: event.created_at,\n last_event_seq: event.seq,\n }\n await this.deps.store.writeManifest(next)\n return next\n }\n\n private async generateTitleFromFirstRound(\n conversationId: string,\n ): Promise<void> {\n const manifest = await this.deps.store.readManifest(conversationId).catch(\n () => null,\n )\n if (!manifest || manifest.status !== 'active' || !canAutoGenerateTitle(manifest)) {\n return\n }\n const snapshot = await this.deps.store.readSnapshot(conversationId).catch(\n () => createEmptySnapshot(),\n )\n if (\n snapshot.messages.filter((message) => message.role === 'user').length !==\n 1\n ) {\n return\n }\n const dialogue = extractFirstRoundTitleSource(snapshot)\n if (!dialogue) {\n return\n }\n\n const title = await requestGeneratedTitleFromServer({\n paths: this.deps.paths,\n sessionKey: manifest.id,\n userMessage: dialogue.userMessage,\n assistantMessage: dialogue.assistantMessage,\n attachmentOnly: dialogue.attachmentOnly,\n }).catch(() => null)\n if (!title) {\n return\n }\n const latestManifest = await this.deps.store.readManifest(conversationId).catch(\n () => null,\n )\n if (\n !latestManifest ||\n latestManifest.status !== 'active' ||\n !canAutoGenerateTitle(latestManifest)\n ) {\n return\n }\n await this.renameConversation(conversationId, title, {\n manifest: latestManifest,\n snapshot,\n source: 'generated',\n }).catch(() => undefined)\n }\n\n private async syncHermesSessionTitle(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n title: string,\n source: 'manual' | 'generated',\n ): Promise<boolean> {\n try {\n await renameHermesSession(\n manifest.hermes_session_id,\n title,\n latestRuntimeRun(snapshot)?.profile ?? manifest.profile,\n )\n return true\n } catch (error) {\n if (source === 'manual') {\n throw error\n }\n return false\n }\n }\n}\n\nfunction createEmptySnapshot(): ConversationSnapshot {\n return { schema_version: 1, messages: [], runs: [] }\n}\n\nfunction extractFirstRoundTitleSource(\n snapshot: ConversationSnapshot,\n): {\n userMessage: string\n assistantMessage: string\n attachmentOnly: boolean\n} | null {\n const userMessages = snapshot.messages\n .filter((message) => message.role === 'user')\n .sort((left, right) => Date.parse(left.created_at) - Date.parse(right.created_at))\n if (userMessages.length !== 1) {\n return null\n }\n const [user] = userMessages\n const userText = truncateTitleSourceText(messageText(user))\n const assistant = snapshot.messages\n .filter((message) => message.role === 'assistant')\n .filter((message) => Date.parse(message.created_at) >= Date.parse(user.created_at))\n .sort((left, right) => Date.parse(left.created_at) - Date.parse(right.created_at))\n .find((message) => messageText(message).length > 0)\n if (!assistant) {\n return null\n }\n const assistantText = truncateTitleSourceText(messageText(assistant))\n if (!assistantText) {\n return null\n }\n const attachmentOnly =\n !userText && user.parts.some((part) => part.type !== 'text')\n if (!userText && !attachmentOnly) {\n return null\n }\n return {\n userMessage: userText,\n assistantMessage: assistantText,\n attachmentOnly,\n }\n}\n\nasync function requestGeneratedTitleFromServer(input: {\n paths: RuntimePaths\n sessionKey: string\n userMessage: string\n assistantMessage: string\n attachmentOnly: boolean\n}): Promise<string | null> {\n const config = await loadConfig(input.paths)\n const response = await fetch(\n `${config.serverBaseUrl.replace(/\\/+$/u, '')}/api/v1/session-titles/generate`,\n {\n method: 'POST',\n signal: AbortSignal.timeout(TITLE_GENERATION_REQUEST_TIMEOUT_MS),\n headers: {\n accept: 'application/json',\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n sessionKey: input.sessionKey,\n userMessage: input.userMessage,\n assistantMessage: input.assistantMessage,\n attachmentOnly: input.attachmentOnly,\n scenario: input.attachmentOnly ? 'attachment-only' : 'first-round',\n }),\n },\n )\n if (!response.ok) {\n return null\n }\n const payload = (await response.json().catch(() => null)) as\n | Record<string, unknown>\n | null\n return normalizeConversationTitle(payload?.title)\n}\n\nfunction normalizeConversationTitle(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null\n }\n const normalized = value.replace(/\\s+/gu, ' ').trim()\n if (!normalized) {\n return null\n }\n return Array.from(normalized).slice(0, SESSION_TITLE_MAX_LENGTH).join('')\n}\n\nfunction truncateTitleSourceText(value: string): string {\n return Array.from(value.replace(/\\s+/gu, ' ').trim())\n .slice(0, TITLE_GENERATION_SOURCE_MAX_LENGTH)\n .join('')\n}\n\nfunction canAutoGenerateTitle(manifest: ConversationManifest): boolean {\n switch (manifest.title_source) {\n case 'manual':\n case 'generated':\n case 'hermes':\n return false\n case 'default':\n case 'temporary_user_message':\n case 'temporary_fallback':\n return true\n default:\n return isDefaultConversationTitle(manifest.title)\n }\n}\n\nfunction normalizeConversationTitleSource(\n title: string,\n): ConversationTitleSource {\n return isDefaultConversationTitle(title) ? 'default' : 'hermes'\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { ConversationRuntimeState } from \"./profile-runtime.js\";\nimport { createSlashCommandUserMessage } from \"./slash-commands.js\";\nimport type {\n ConversationManifest,\n ConversationSnapshot,\n LinkMessage,\n LinkMessagePart,\n LinkRun,\n MessageAttachmentInput,\n} from \"./types.js\";\n\nconst MESSAGE_ORDER_STEP_MS = 10;\nconst ASSISTANT_ORDER_OFFSET_MS = 1;\n\nexport interface AgentTurnDraft {\n userMessage: LinkMessage;\n assistantMessage: LinkMessage | null;\n run: LinkRun;\n shouldQueue: boolean;\n}\n\nexport interface RetryTurnDraft {\n commandMessage: LinkMessage;\n assistantMessage: LinkMessage;\n run: LinkRun;\n}\n\nexport interface CommandResultTurnDraft {\n commandMessage: LinkMessage;\n systemMessage: LinkMessage;\n run: LinkRun;\n}\n\nexport function createAgentTurnDraft(input: {\n manifest: ConversationManifest;\n snapshot: ConversationSnapshot;\n runtime: ConversationRuntimeState;\n content: string;\n attachments: LinkMessagePart[];\n rawAttachments: MessageAttachmentInput[];\n idempotencyKey?: string;\n now?: string;\n}): AgentTurnDraft {\n const now = input.now ?? new Date().toISOString();\n const shouldQueue = hasActiveOrQueuedRuns(input.snapshot);\n const userCreatedAt = nextMessageCreatedAt(input.snapshot, now);\n const runId = createRunId();\n const assistantMessageId = createMessageId();\n const userMessage: LinkMessage = {\n id: createMessageId(),\n schema_version: 1,\n conversation_id: input.manifest.id,\n role: \"user\",\n status: shouldQueue ? \"queued\" : \"completed\",\n client_message_id: input.idempotencyKey,\n created_at: userCreatedAt,\n updated_at: now,\n sender: { id: \"app_user\", type: \"human\", display_name: \"Me\" },\n parts: [{ type: \"text\", text: input.content }, ...input.attachments],\n attachments: input.attachments.map((part) => ({\n blob_id: part.blob,\n mime: part.mime,\n size: part.size,\n filename: part.filename,\n kind: part.kind,\n is_voice_note: part.is_voice_note,\n duration_ms: part.duration_ms,\n waveform: part.waveform,\n })),\n raw: {\n format: \"hermes-link-user-message\",\n payload: { content: input.content, attachments: input.rawAttachments },\n },\n };\n const assistantMessage = shouldQueue\n ? null\n : createAssistantMessage({\n conversationId: input.manifest.id,\n messageId: assistantMessageId,\n runId,\n createdAt: assistantCreatedAtAfter(userMessage.created_at),\n updatedAt: now,\n displayName: input.runtime.profileDisplayName,\n profileUid: input.runtime.profileUid,\n profile: input.runtime.profileName,\n hermes: { trigger_message_id: userMessage.id },\n });\n const run: LinkRun = {\n id: runId,\n kind: \"agent\",\n conversation_id: input.manifest.id,\n trigger_message_id: userMessage.id,\n assistant_message_id: assistantMessageId,\n hermes_session_id: input.manifest.hermes_session_id,\n status: shouldQueue ? \"queued\" : \"running\",\n started_at: now,\n profile_uid: input.runtime.profileUid,\n profile_name_snapshot: input.runtime.profileName,\n profile: input.runtime.profileName,\n model: input.runtime.model,\n provider: input.runtime.provider,\n context_window: input.runtime.contextWindow,\n };\n return { userMessage, assistantMessage, run, shouldQueue };\n}\n\nexport function createRetryTurnDraft(input: {\n manifest: ConversationManifest;\n runtime: ConversationRuntimeState;\n previousUser: LinkMessage;\n rawContent: string;\n clientMessageId?: string;\n now?: string;\n}): RetryTurnDraft {\n const now = input.now ?? new Date().toISOString();\n const commandMessage = createSlashCommandUserMessage({\n conversationId: input.manifest.id,\n content: input.rawContent,\n clientMessageId: input.clientMessageId,\n createdAt: now,\n });\n const runId = createRunId();\n const assistantMessage = createAssistantMessage({\n conversationId: input.manifest.id,\n messageId: createMessageId(),\n runId,\n createdAt: now,\n updatedAt: now,\n displayName: input.runtime.profileDisplayName,\n profileUid: input.runtime.profileUid,\n profile: input.runtime.profileName,\n hermes: { retried_message_id: input.previousUser.id },\n });\n const run: LinkRun = {\n id: runId,\n kind: \"agent\",\n conversation_id: input.manifest.id,\n trigger_message_id: commandMessage.id,\n assistant_message_id: assistantMessage.id,\n hermes_session_id: input.manifest.hermes_session_id,\n status: \"running\",\n started_at: now,\n profile_uid: input.runtime.profileUid,\n profile_name_snapshot: input.runtime.profileName,\n profile: input.runtime.profileName,\n model: input.runtime.model,\n provider: input.runtime.provider,\n context_window: input.runtime.contextWindow,\n };\n return { commandMessage, assistantMessage, run };\n}\n\nexport function createCommandResultTurnDraft(input: {\n manifest: ConversationManifest;\n rawContent: string;\n clientMessageId?: string;\n commandName: string;\n response: string;\n now?: string;\n}): CommandResultTurnDraft {\n const now = input.now ?? new Date().toISOString();\n const commandMessage = createSlashCommandUserMessage({\n conversationId: input.manifest.id,\n content: input.rawContent,\n clientMessageId: input.clientMessageId,\n createdAt: now,\n });\n const systemMessage: LinkMessage = {\n id: createMessageId(),\n schema_version: 1,\n conversation_id: input.manifest.id,\n role: \"system\",\n status: \"completed\",\n created_at: now,\n updated_at: now,\n sender: {\n id: \"hermes_link\",\n type: \"system\",\n display_name: \"Hermes Link\",\n },\n parts: [{ type: \"text\", text: input.response }],\n attachments: [],\n raw: {\n format: \"hermes-link-slash-command-result\",\n payload: {\n command: input.commandName,\n content: input.response,\n },\n },\n };\n const run: LinkRun = {\n id: createRunId(),\n kind: \"command\",\n conversation_id: input.manifest.id,\n trigger_message_id: commandMessage.id,\n assistant_message_id: systemMessage.id,\n hermes_session_id: input.manifest.hermes_session_id,\n status: \"completed\",\n started_at: now,\n completed_at: now,\n };\n return { commandMessage, systemMessage, run };\n}\n\nexport function ensureQueuedAssistantMessage(input: {\n manifest: ConversationManifest;\n snapshot: ConversationSnapshot;\n run: LinkRun;\n user: LinkMessage;\n startedAt: string;\n}): LinkMessage {\n const existingAssistant = input.snapshot.messages.find(\n (message) => message.id === input.run.assistant_message_id,\n );\n if (existingAssistant) {\n existingAssistant.status = \"streaming\";\n existingAssistant.run_id = input.run.id;\n existingAssistant.updated_at = input.startedAt;\n existingAssistant.hermes = {\n ...(existingAssistant.hermes ?? {}),\n trigger_message_id: input.user.id,\n };\n return existingAssistant;\n }\n\n const assistant = createAssistantMessage({\n conversationId: input.manifest.id,\n messageId: input.run.assistant_message_id,\n runId: input.run.id,\n createdAt: assistantCreatedAtAfter(input.user.created_at),\n updatedAt: input.startedAt,\n displayName:\n input.run.profile_name_snapshot ?? input.run.profile ?? \"Hermes\",\n profileUid: input.run.profile_uid,\n profile: input.run.profile,\n hermes: { trigger_message_id: input.user.id },\n });\n const userIndex = input.snapshot.messages.findIndex(\n (message) => message.id === input.user.id,\n );\n input.snapshot.messages.splice(\n userIndex === -1 ? input.snapshot.messages.length : userIndex + 1,\n 0,\n assistant,\n );\n return assistant;\n}\n\nexport function nextMessageCreatedAt(\n snapshot: ConversationSnapshot,\n fallbackIso: string,\n): string {\n const fallbackMs = validTimestampOrNow(fallbackIso);\n const latestMs = snapshot.messages.reduce((latest, message) => {\n const value = Date.parse(message.created_at);\n return Number.isFinite(value) ? Math.max(latest, value) : latest;\n }, Number.NEGATIVE_INFINITY);\n const nextMs = Number.isFinite(latestMs)\n ? Math.max(fallbackMs, latestMs + MESSAGE_ORDER_STEP_MS)\n : fallbackMs;\n return new Date(nextMs).toISOString();\n}\n\nexport function assistantCreatedAtAfter(userCreatedAt: string): string {\n return new Date(\n validTimestampOrNow(userCreatedAt) + ASSISTANT_ORDER_OFFSET_MS,\n ).toISOString();\n}\n\nexport function assistantStatusForRun(\n run: LinkRun | undefined,\n): LinkMessage[\"status\"] {\n switch (run?.status) {\n case \"queued\":\n return \"queued\";\n case \"running\":\n return \"streaming\";\n case \"completed\":\n return \"completed\";\n case \"cancelled\":\n return \"cancelled\";\n case \"failed\":\n case \"unknown\":\n default:\n return \"failed\";\n }\n}\n\nfunction createAssistantMessage(input: {\n conversationId: string;\n messageId: string;\n runId: string;\n createdAt: string;\n updatedAt: string;\n displayName: string;\n profileUid?: string;\n profile?: string;\n hermes?: Record<string, unknown>;\n}): LinkMessage {\n return {\n id: input.messageId,\n schema_version: 1,\n conversation_id: input.conversationId,\n role: \"assistant\",\n status: \"streaming\",\n run_id: input.runId,\n created_at: input.createdAt,\n updated_at: input.updatedAt,\n sender: {\n id: \"agent_default\",\n type: \"agent\",\n display_name: input.displayName,\n profile_uid: input.profileUid,\n profile: input.profile,\n },\n parts: [{ type: \"text\", text: \"\" }],\n attachments: [],\n ...(input.hermes ? { hermes: input.hermes } : {}),\n };\n}\n\nfunction createMessageId(): string {\n return `msg_${randomUUID().replaceAll(\"-\", \"\")}`;\n}\n\nfunction createRunId(): string {\n return `run_${randomUUID().replaceAll(\"-\", \"\")}`;\n}\n\nfunction hasActiveOrQueuedRuns(snapshot: ConversationSnapshot): boolean {\n return snapshot.runs.some(\n (run) => run.status === \"running\" || run.status === \"queued\",\n );\n}\n\nfunction validTimestampOrNow(value: string): number {\n const timestamp = Date.parse(value);\n return Number.isFinite(timestamp) ? timestamp : Date.now();\n}\n","import { LinkHttpError } from '../core/errors.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { blobPath } from './blob-store.js'\nimport type { ConversationCommandHandlers } from './conversation-commands.js'\nimport { ConversationMetadataCoordinator } from './conversation-metadata.js'\nimport { ConversationStore } from './conversation-store.js'\nimport {\n assistantStatusForRun,\n createAgentTurnDraft,\n createCommandResultTurnDraft,\n createRetryTurnDraft,\n ensureQueuedAssistantMessage,\n} from './conversation-turns.js'\nimport {\n freshHermesSessionId,\n parseSlashCommandInput,\n slashHelpMessage,\n type ParsedSlashCommand,\n} from './slash-commands.js'\nimport {\n normalizeProfileName,\n readConversationProfileSummary,\n readCurrentConversationRuntime,\n resolveConversationProfileTarget,\n} from './profile-runtime.js'\nimport {\n hasRunningRuns,\n isRetryableUserMessage,\n messageText,\n toSummary,\n} from './conversation-view.js'\nimport { ConversationRunLifecycle } from './run-lifecycle.js'\nimport type {\n ConversationEvent,\n ConversationManifest,\n ConversationProfileSummary,\n ConversationSnapshot,\n LinkMessagePart,\n MessageAttachmentInput,\n SendMessageInput,\n SendMessageResult,\n} from './types.js'\n\ninterface RunWorkerInput {\n conversationId: string\n runId: string\n input: string\n}\n\ntype CommandActionInput = {\n manifest: ConversationManifest\n snapshot: ConversationSnapshot\n command: ParsedSlashCommand\n rawContent: string\n clientMessageId?: string\n}\n\ntype AppendCommandResultInput = Omit<CommandActionInput, 'command'> & {\n commandName: string\n response: string\n}\n\nexport interface ConversationOrchestrationDeps {\n readonly paths: RuntimePaths\n readonly store: ConversationStore\n readonly metadata: ConversationMetadataCoordinator\n readonly commandHandlers: ConversationCommandHandlers\n readonly runLifecycle: ConversationRunLifecycle\n readonly withConversationLock: <T>(\n conversationId: string,\n task: () => Promise<T>,\n ) => Promise<T>\n readonly appendEvent: (\n conversationId: string,\n input: Omit<ConversationEvent, 'seq' | 'conversation_id' | 'created_at'>,\n ) => Promise<ConversationEvent>\n readonly resolveMessageAttachmentParts: (\n conversationId: string,\n attachments: MessageAttachmentInput[],\n ) => Promise<LinkMessagePart[]>\n}\n\nexport class ConversationOrchestrationCoordinator {\n constructor(private readonly deps: ConversationOrchestrationDeps) {}\n\n async sendMessage(input: SendMessageInput): Promise<SendMessageResult> {\n return this.deps.withConversationLock(input.conversationId, () =>\n this.sendMessageLocked(input),\n )\n }\n\n async startNextQueuedRun(conversationId: string): Promise<void> {\n const next = await this.deps.withConversationLock(conversationId, () =>\n this.startNextQueuedRunLocked(conversationId),\n )\n if (!next) {\n return\n }\n this.startRunWorkerAndDrain(next.conversationId, next.runId, next.input)\n }\n\n async appendCommandResult(\n input: AppendCommandResultInput,\n ): Promise<SendMessageResult> {\n return this.appendCommandResultLocked(input)\n }\n\n private startRunWorkerAndDrain(\n conversationId: string,\n runId: string,\n input: string,\n ): void {\n void this.deps.runLifecycle\n .startRunWorker(conversationId, runId, input)\n .catch((error: unknown) =>\n this.deps.runLifecycle.failRun(\n conversationId,\n runId,\n error instanceof Error ? error.message : String(error),\n ),\n )\n .finally(() => {\n void this.startNextQueuedRun(conversationId)\n })\n }\n\n private async startNextQueuedRunLocked(\n conversationId: string,\n ): Promise<RunWorkerInput | null> {\n if (!(await this.deps.store.isConversationActive(conversationId))) {\n return null\n }\n const manifest = await this.deps.store.readActiveManifest(conversationId)\n const snapshot = await this.deps.store.readSnapshot(conversationId)\n if (hasRunningRuns(snapshot)) {\n return null\n }\n const run = snapshot.runs.find((item) => item.status === 'queued')\n if (!run) {\n return null\n }\n const user = snapshot.messages.find(\n (message) => message.id === run.trigger_message_id,\n )\n if (!user) {\n run.status = 'failed'\n run.completed_at = new Date().toISOString()\n run.error_message = 'Queued user message was not found'\n await this.deps.store.writeSnapshot(conversationId, snapshot)\n await this.deps.appendEvent(conversationId, {\n type: 'run.failed',\n run_id: run.id,\n payload: {\n error: { message: run.error_message },\n run,\n },\n })\n await this.deps.metadata.persistConversationStats(\n conversationId,\n snapshot,\n )\n return null\n }\n\n const startedAt = new Date().toISOString()\n run.status = 'running'\n run.started_at = startedAt\n user.status = 'completed'\n user.updated_at = startedAt\n\n const assistant = ensureQueuedAssistantMessage({\n manifest,\n snapshot,\n run,\n user,\n startedAt,\n })\n\n await this.deps.store.writeSnapshot(conversationId, snapshot)\n await this.deps.appendEvent(conversationId, {\n type: 'message.completed',\n message_id: user.id,\n payload: { message: user },\n })\n await this.deps.appendEvent(conversationId, {\n type: 'message.created',\n message_id: assistant.id,\n run_id: run.id,\n payload: { message: assistant },\n })\n await this.deps.appendEvent(conversationId, {\n type: 'run.started',\n message_id: assistant.id,\n run_id: run.id,\n payload: { run },\n })\n await this.deps.metadata.persistConversationStats(conversationId, snapshot)\n\n return {\n conversationId,\n runId: run.id,\n input: this.buildHermesInput(\n messageText(user),\n user.parts.filter((part) => Boolean(part.blob)),\n ),\n }\n }\n\n private async sendMessageLocked(\n input: SendMessageInput,\n ): Promise<SendMessageResult> {\n let manifest = await this.deps.store.readActiveManifest(input.conversationId)\n let content = input.content.trim()\n const userAttachmentParts = await this.deps.resolveMessageAttachmentParts(\n manifest.id,\n input.attachments ?? [],\n )\n if (!content && userAttachmentParts.length === 0) {\n throw new LinkHttpError(\n 400,\n 'message_content_required',\n 'message content is required',\n )\n }\n const idempotencyKey = input.clientMessageId ?? input.idempotencyKey\n const snapshot = await this.deps.store.readSnapshot(input.conversationId)\n manifest = await this.ensureManifestProfile(manifest, input.profileName)\n if (idempotencyKey) {\n const existingUser = snapshot.messages.find(\n (message) => message.client_message_id === idempotencyKey,\n )\n if (existingUser) {\n const existingRun = snapshot.runs.find(\n (run) => run.trigger_message_id === existingUser.id,\n )\n const existingAssistant = existingRun\n ? snapshot.messages.find(\n (message) => message.id === existingRun.assistant_message_id,\n )\n : null\n return {\n conversation_id: manifest.id,\n user_message: { id: existingUser.id, status: existingUser.status },\n assistant_message: {\n id:\n existingAssistant?.id ??\n existingRun?.assistant_message_id ??\n '',\n status:\n existingAssistant?.status ?? assistantStatusForRun(existingRun),\n },\n run: {\n id: existingRun?.id ?? '',\n status: existingRun?.status ?? 'unknown',\n },\n last_event_seq: manifest.last_event_seq,\n conversation: await this.summarizeConversation(manifest, snapshot),\n }\n }\n }\n\n if (userAttachmentParts.length === 0) {\n const slash = parseSlashCommandInput(content)\n if (slash.kind === 'escaped') {\n content = slash.content\n } else if (slash.kind !== 'none') {\n return this.executeSlashCommandLocked({\n manifest,\n snapshot,\n command: slash,\n rawContent: content,\n clientMessageId: idempotencyKey,\n })\n }\n }\n\n const runtime = await readCurrentConversationRuntime(this.deps.paths, manifest)\n const { userMessage, assistantMessage, run, shouldQueue } =\n createAgentTurnDraft({\n manifest,\n snapshot,\n runtime,\n content,\n attachments: userAttachmentParts,\n rawAttachments: input.attachments ?? [],\n idempotencyKey,\n })\n const assistantMessageId = run.assistant_message_id\n snapshot.messages.push(\n ...(assistantMessage ? [userMessage, assistantMessage] : [userMessage]),\n )\n snapshot.runs.push(run)\n await this.deps.store.writeSnapshot(manifest.id, snapshot)\n manifest = await this.deps.metadata.applyTemporaryTitleFromFirstMessage(\n manifest,\n snapshot,\n content,\n )\n const userEvent = await this.deps.appendEvent(manifest.id, {\n type: 'message.created',\n message_id: userMessage.id,\n payload: { message: userMessage },\n })\n let latestEvent = userEvent\n if (assistantMessage) {\n await this.deps.appendEvent(manifest.id, {\n type: 'message.created',\n message_id: assistantMessage.id,\n run_id: run.id,\n payload: { message: assistantMessage },\n })\n latestEvent = await this.deps.appendEvent(manifest.id, {\n type: 'run.started',\n message_id: assistantMessage.id,\n run_id: run.id,\n payload: { run },\n })\n } else {\n latestEvent = await this.deps.appendEvent(manifest.id, {\n type: 'run.queued',\n message_id: userMessage.id,\n run_id: run.id,\n payload: { run },\n })\n }\n await this.deps.metadata.persistConversationStats(manifest.id, snapshot)\n\n if (!shouldQueue) {\n this.startRunWorkerAndDrain(\n manifest.id,\n run.id,\n this.buildHermesInput(content, userAttachmentParts),\n )\n }\n\n return {\n conversation_id: manifest.id,\n user_message: { id: userMessage.id, status: userMessage.status },\n assistant_message: {\n id: assistantMessageId,\n status: assistantMessage?.status ?? 'queued',\n },\n run: { id: run.id, status: run.status },\n last_event_seq: latestEvent.seq,\n conversation: await this.summarizeConversation(\n {\n ...manifest,\n last_event_seq: latestEvent.seq,\n updated_at: latestEvent.created_at,\n },\n snapshot,\n {\n uid: runtime.profileUid,\n name: runtime.profileName,\n display_name: runtime.profileDisplayName,\n avatar_url: runtime.profileAvatarUrl,\n },\n ),\n }\n }\n\n private async executeSlashCommandLocked(\n input: CommandActionInput,\n ): Promise<SendMessageResult> {\n if (input.command.kind === 'unsupported') {\n return this.appendCommandResultLocked({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: `Link 目前不支持 /${input.command.name}。输入 /help 可以查看当前支持的斜杠命令。`,\n })\n }\n if (input.command.kind === 'invalid') {\n return this.appendCommandResultLocked({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: input.command.reason,\n })\n }\n\n const { manifest, snapshot, command } = input\n switch (command.name) {\n case 'help':\n return this.appendCommandResultLocked({\n manifest,\n snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: command.name,\n response: slashHelpMessage(),\n })\n case 'new':\n case 'reset':\n return this.resetConversationContextLocked(input)\n case 'retry':\n return this.retryLastUserMessageLocked(input)\n case 'title':\n return this.deps.commandHandlers.handleTitleCommand(input)\n case 'profile':\n return this.appendCommandResultLocked({\n manifest,\n snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: command.name,\n response: await this.deps.commandHandlers.profileStatusMessage(manifest),\n })\n case 'model':\n return this.deps.commandHandlers.handleModelCommand(input)\n case 'verbose':\n return this.deps.commandHandlers.handleVerboseCommand(input)\n case 'yolo':\n return this.deps.commandHandlers.handleYoloCommand(input)\n case 'reasoning':\n return this.deps.commandHandlers.handleReasoningCommand(input)\n case 'usage':\n return this.appendCommandResultLocked({\n manifest,\n snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: command.name,\n response: await this.deps.commandHandlers.usageStatusMessage(\n manifest,\n snapshot,\n ),\n })\n case 'restart':\n return this.deps.commandHandlers.restartGatewayFromCommand(input)\n }\n }\n\n private async resetConversationContextLocked(\n input: CommandActionInput,\n ): Promise<SendMessageResult> {\n if (hasRunningRuns(input.snapshot)) {\n return this.appendCommandResultLocked({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response:\n '当前会话还有运行中的回复。请等待完成或先取消运行后再重置上下文。',\n })\n }\n const resetAt = new Date().toISOString()\n const previousSessionId = input.manifest.hermes_session_id\n const nextSessionId = freshHermesSessionId(input.manifest.id)\n await this.deps.store.writeManifest({\n ...input.manifest,\n hermes_session_id: nextSessionId,\n command_state: {\n ...input.manifest.command_state,\n context_reset_at: resetAt,\n context_reset_count:\n (input.manifest.command_state?.context_reset_count ?? 0) + 1,\n },\n updated_at: resetAt,\n })\n await this.deps.appendEvent(input.manifest.id, {\n type: 'conversation.updated',\n payload: {\n command: input.command.name,\n context_reset: true,\n previous_hermes_session_id: previousSessionId,\n hermes_session_id: nextSessionId,\n },\n })\n return this.appendCommandResultLocked({\n manifest: await this.deps.store.readManifest(input.manifest.id),\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response:\n input.command.name === 'new'\n ? '/new 已按 /reset 处理:当前 App 会话窗口保持不变,但后续消息会使用新的 Hermes 上下文。'\n : '已重置当前 App 会话窗口的后续 Hermes 上下文,历史消息仍会保留在当前窗口中。',\n })\n }\n\n private async retryLastUserMessageLocked(\n input: CommandActionInput,\n ): Promise<SendMessageResult> {\n if (hasRunningRuns(input.snapshot)) {\n return this.appendCommandResultLocked({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: '当前会话还有运行中的回复。请等待完成或先取消运行后再重试。',\n })\n }\n const previousUser = [...input.snapshot.messages]\n .reverse()\n .find(isRetryableUserMessage)\n if (!previousUser) {\n return this.appendCommandResultLocked({\n manifest: input.manifest,\n snapshot: input.snapshot,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.command.name,\n response: '没有找到可以重试的上一条用户消息。',\n })\n }\n\n const runtime = await readCurrentConversationRuntime(\n this.deps.paths,\n input.manifest,\n )\n const { commandMessage, assistantMessage, run } = createRetryTurnDraft({\n manifest: input.manifest,\n runtime,\n previousUser,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n })\n input.snapshot.messages.push(commandMessage)\n await this.deps.store.writeSnapshot(input.manifest.id, input.snapshot)\n await this.deps.appendEvent(input.manifest.id, {\n type: 'message.created',\n message_id: commandMessage.id,\n payload: { message: commandMessage },\n })\n input.snapshot.messages.push(assistantMessage)\n input.snapshot.runs.push(run)\n await this.deps.store.writeSnapshot(input.manifest.id, input.snapshot)\n await this.deps.appendEvent(input.manifest.id, {\n type: 'message.created',\n message_id: assistantMessage.id,\n run_id: run.id,\n payload: { message: assistantMessage },\n })\n const runEvent = await this.deps.appendEvent(input.manifest.id, {\n type: 'run.started',\n message_id: assistantMessage.id,\n run_id: run.id,\n payload: {\n run,\n retried_message_id: previousUser.id,\n },\n })\n await this.deps.metadata.persistConversationStats(\n input.manifest.id,\n input.snapshot,\n )\n\n this.startRunWorkerAndDrain(\n input.manifest.id,\n run.id,\n this.buildHermesInput(\n messageText(previousUser),\n previousUser.parts.filter((part) => Boolean(part.blob)),\n ),\n )\n\n return {\n conversation_id: input.manifest.id,\n user_message: { id: commandMessage.id, status: commandMessage.status },\n assistant_message: {\n id: assistantMessage.id,\n status: assistantMessage.status,\n },\n run: { id: run.id, status: run.status },\n last_event_seq: runEvent.seq,\n conversation: await this.summarizeConversation(\n {\n ...input.manifest,\n last_event_seq: runEvent.seq,\n updated_at: runEvent.created_at,\n },\n input.snapshot,\n {\n uid: runtime.profileUid,\n name: runtime.profileName,\n display_name: runtime.profileDisplayName,\n avatar_url: runtime.profileAvatarUrl,\n },\n ),\n }\n }\n\n private async appendCommandResultLocked(\n input: AppendCommandResultInput,\n ): Promise<SendMessageResult> {\n const manifest = await this.deps.store.readManifest(input.manifest.id)\n const { commandMessage, systemMessage, run } =\n createCommandResultTurnDraft({\n manifest,\n rawContent: input.rawContent,\n clientMessageId: input.clientMessageId,\n commandName: input.commandName,\n response: input.response,\n })\n input.snapshot.messages.push(commandMessage, systemMessage)\n input.snapshot.runs.push(run)\n await this.deps.store.writeSnapshot(manifest.id, input.snapshot)\n await this.deps.appendEvent(manifest.id, {\n type: 'message.created',\n message_id: commandMessage.id,\n payload: { message: commandMessage },\n })\n await this.deps.appendEvent(manifest.id, {\n type: 'message.created',\n message_id: systemMessage.id,\n run_id: run.id,\n payload: { message: systemMessage },\n })\n const runEvent = await this.deps.appendEvent(manifest.id, {\n type: 'run.completed',\n message_id: systemMessage.id,\n run_id: run.id,\n payload: { run, command: input.commandName },\n })\n await this.deps.metadata.persistConversationStats(manifest.id, input.snapshot)\n return {\n conversation_id: manifest.id,\n user_message: { id: commandMessage.id, status: commandMessage.status },\n assistant_message: { id: systemMessage.id, status: systemMessage.status },\n run: { id: run.id, status: run.status },\n last_event_seq: runEvent.seq,\n conversation: await this.summarizeConversation(\n {\n ...manifest,\n last_event_seq: runEvent.seq,\n updated_at: runEvent.created_at,\n },\n input.snapshot,\n ),\n }\n }\n\n private async ensureManifestProfile(\n manifest: ConversationManifest,\n requestedProfileName?: string,\n ): Promise<ConversationManifest> {\n const existingProfileName = normalizeProfileName(\n manifest.profile_name_snapshot ?? manifest.profile,\n )\n const hasExistingProfile = Boolean(\n manifest.profile_name_snapshot ?? manifest.profile,\n )\n const nextProfileName = requestedProfileName\n ? normalizeProfileName(requestedProfileName)\n : existingProfileName\n if (\n requestedProfileName &&\n hasExistingProfile &&\n nextProfileName !== existingProfileName\n ) {\n throw new LinkHttpError(\n 409,\n 'conversation_profile_mismatch',\n `This conversation is bound to profile \"${existingProfileName}\". Create a new conversation to chat with \"${nextProfileName}\".`,\n )\n }\n if (hasExistingProfile && manifest.profile_uid) {\n return manifest\n }\n const profile = await resolveConversationProfileTarget(\n this.deps.paths,\n nextProfileName,\n )\n const next: ConversationManifest = {\n ...manifest,\n profile_uid: profile.profileUid,\n profile_name_snapshot: profile.profileName,\n profile: profile.profileName,\n }\n await this.deps.store.writeManifest(next)\n return next\n }\n\n private async summarizeConversation(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n profile?: ConversationProfileSummary,\n ) {\n return toSummary(\n manifest,\n snapshot,\n profile ?? (await readConversationProfileSummary(this.deps.paths, manifest)),\n )\n }\n\n private buildHermesInput(content: string, parts: LinkMessagePart[]): string {\n const attachmentLines = parts\n .filter((part) => part.blob)\n .map((part) => {\n const label = part.filename ?? part.blob\n const mime = part.mime ? `, ${part.mime}` : ''\n const size = part.size ? `, ${part.size} bytes` : ''\n return `- ${label}${mime}${size}: ${\n part.local_path ?? blobPath(this.deps.paths, part.blob!)\n }`\n })\n if (attachmentLines.length === 0) {\n return content\n }\n const prefix = content ? `${content}\\n\\n` : ''\n return `${prefix}Attachments available on this computer:\\n${attachmentLines.join('\\n')}`\n }\n}\n","import { createHash } from 'node:crypto'\nimport type {\n ConversationEvent,\n LinkMessageAgentEvent,\n} from './types.js'\n\nexport function projectConversationAgentEvent(\n event: ConversationEvent,\n): LinkMessageAgentEvent | null {\n if (!isAgentActivityEvent(event.type)) {\n return null\n }\n return projectAgentEvent({\n type: event.type,\n payload: event.payload ?? {},\n createdAt: event.created_at,\n fallbackKey: String(event.seq),\n raw: event.raw,\n })\n}\n\nfunction projectAgentEvent(input: {\n type: string\n payload: Record<string, unknown>\n createdAt: string\n fallbackKey: string\n raw?: { format: string; payload: unknown }\n}): LinkMessageAgentEvent | null {\n const type =\n readString(input.payload, 'type') ??\n readString(input.payload, 'event') ??\n input.type\n if (!isAgentActivityEvent(type)) {\n return null\n }\n const createdAt =\n readString(input.payload, 'started_at') ??\n readString(input.payload, 'created_at') ??\n input.createdAt\n const tool = toRecord(input.payload.tool)\n const call = toRecord(input.payload.tool_call ?? input.payload.toolCall)\n const fn = toRecord(call.function ?? input.payload.function)\n const name =\n readString(input.payload, 'tool_name') ??\n readString(input.payload, 'toolName') ??\n readString(input.payload, 'name') ??\n readString(input.payload, 'tool') ??\n readString(tool, 'name') ??\n readString(call, 'name') ??\n readString(fn, 'name') ??\n 'tool'\n const id =\n readString(input.payload, 'tool_call_id') ??\n readString(input.payload, 'toolCallId') ??\n readString(input.payload, 'call_id') ??\n readString(input.payload, 'id') ??\n readString(tool, 'id') ??\n readString(call, 'id') ??\n readString(fn, 'id') ??\n `tool_${hashAgentEventKey(`${type}:${input.fallbackKey}:${stableStringify(input.payload)}`)}`\n const rawArguments =\n input.payload.arguments ??\n input.payload.args ??\n input.payload.input ??\n tool.arguments ??\n tool.args ??\n tool.input ??\n call.arguments ??\n call.args ??\n call.input ??\n fn.arguments\n const args = stringifyAgentValue(rawArguments)\n const output = stringifyAgentValue(\n input.payload.result ??\n input.payload.output ??\n input.payload.content ??\n input.payload.message ??\n tool.result ??\n tool.output ??\n call.result ??\n call.output,\n )\n const summary =\n readString(input.payload, 'summary') ??\n readString(input.payload, 'description') ??\n readText(input.payload, 'preview') ??\n readString(tool, 'summary') ??\n readString(tool, 'description') ??\n readString(call, 'summary') ??\n undefined\n const status =\n input.payload.error === true ? 'failed' : agentStatusForEventType(type)\n const detail =\n status === 'failed'\n ? (readErrorMessage(input.payload) ??\n output ??\n summary ??\n args ??\n undefined)\n : status === 'completed'\n ? (output ?? summary ?? args ?? undefined)\n : (args ?? summary ?? undefined)\n const subtitle =\n summarizeAgentArguments({\n toolName: name,\n rawArguments,\n summary,\n args,\n }) ??\n (status === 'running'\n ? `正在调用 ${name}`\n : status === 'completed'\n ? `${name} 已完成`\n : `${name} 执行失败`)\n\n return {\n id,\n title: humanizeToolName(name),\n subtitle,\n ...(detail ? { detail } : {}),\n status,\n created_at: createdAt,\n ...(status === 'running'\n ? {}\n : {\n completed_at:\n readString(input.payload, 'completed_at') ?? input.createdAt,\n }),\n ...(input.raw ? { raw: input.raw } : {}),\n }\n}\n\nfunction isAgentActivityEvent(type: string): boolean {\n return type.startsWith('tool.')\n}\n\nexport function isMeaningfulAgentEventProjection(\n event: LinkMessageAgentEvent,\n): boolean {\n return event.title !== '推理信息'\n}\n\nfunction agentStatusForEventType(\n type: string,\n): LinkMessageAgentEvent['status'] {\n if (type === 'tool.completed') {\n return 'completed'\n }\n if (type === 'tool.failed' || type === 'tool.error') {\n return 'failed'\n }\n return 'running'\n}\n\nexport function mergeAgentEventProjections(\n base: LinkMessageAgentEvent[],\n overlay: LinkMessageAgentEvent[],\n): LinkMessageAgentEvent[] {\n return overlay.reduce(\n (events, event) => upsertAgentEventProjection(events, event),\n [...base],\n )\n}\n\nexport function upsertAgentEventProjection(\n events: LinkMessageAgentEvent[],\n next: LinkMessageAgentEvent,\n): LinkMessageAgentEvent[] {\n let index = events.findIndex((event) => event.id === next.id)\n if (index < 0 && next.status !== 'running') {\n for (\n let candidateIndex = events.length - 1;\n candidateIndex >= 0;\n candidateIndex -= 1\n ) {\n const candidate = events[candidateIndex]\n if (candidate?.status === 'running' && candidate.title === next.title) {\n index = candidateIndex\n break\n }\n }\n }\n if (index < 0) {\n return [...events, next]\n }\n const previous = events[index]\n const nextSubtitleIsFallback = isToolStatusFallbackSubtitle(\n next.subtitle,\n next.title,\n )\n const merged: LinkMessageAgentEvent = {\n ...previous,\n ...next,\n id: previous.id,\n subtitle: nextSubtitleIsFallback\n ? (previous.subtitle ?? next.subtitle)\n : (next.subtitle ?? previous.subtitle),\n detail: next.detail ?? previous.detail,\n completed_at: next.completed_at ?? previous.completed_at,\n }\n const copy = [...events]\n copy[index] = merged\n return copy\n}\n\nfunction isToolStatusFallbackSubtitle(\n value: string | undefined,\n title: string,\n): boolean {\n if (!value) {\n return false\n }\n const normalized = value.trim().toLowerCase()\n const normalizedTitle = title.trim().toLowerCase()\n return (\n normalized === normalizedTitle ||\n normalized.startsWith('正在调用 ') ||\n normalized.endsWith(' 已完成') ||\n normalized.endsWith(' 执行失败')\n )\n}\n\nexport function closeRunningAgentEvents(\n events: LinkMessageAgentEvent[] | undefined,\n status: 'completed' | 'failed',\n completedAt: string,\n): LinkMessageAgentEvent[] | undefined {\n if (!events?.length) {\n return events\n }\n return events.map((event) =>\n event.status === 'running'\n ? { ...event, status, completed_at: completedAt }\n : event,\n )\n}\n\nfunction humanizeToolName(value: string): string {\n const normalized = value.trim().replace(/[_-]+/gu, ' ').replace(/\\s+/gu, ' ')\n if (!normalized) {\n return '工具调用'\n }\n return normalized\n .split(' ')\n .map((part) =>\n part ? `${part[0]?.toUpperCase() ?? ''}${part.slice(1)}` : part,\n )\n .join(' ')\n}\n\nfunction compactAgentSummary(value: string | undefined): string | undefined {\n const normalized = value?.trim().replace(/\\s+/gu, ' ')\n if (!normalized) {\n return undefined\n }\n return normalized.length <= 88 ? normalized : `${normalized.slice(0, 87)}…`\n}\n\nfunction summarizeAgentArguments(input: {\n toolName: string\n rawArguments: unknown\n summary: string | undefined\n args: string | undefined\n}): string | undefined {\n const skillViewSummary = summarizeSkillViewArguments(\n input.toolName,\n input.rawArguments,\n input.args,\n )\n if (skillViewSummary) {\n return skillViewSummary\n }\n return compactAgentSummary(input.summary ?? input.args)\n}\n\nfunction summarizeSkillViewArguments(\n toolName: string,\n rawArguments: unknown,\n args: string | undefined,\n): string | undefined {\n const normalizedToolName = toolName\n .trim()\n .toLowerCase()\n .replace(/[\\s-]+/gu, '_')\n if (normalizedToolName !== 'skill_view') {\n return undefined\n }\n const argumentObject = readToolArgumentsObject(rawArguments, args)\n const skillName = readString(argumentObject, 'name')?.trim()\n const filePath =\n readString(argumentObject, 'file_path')?.trim() ??\n readString(argumentObject, 'filePath')?.trim()\n if (!skillName) {\n return filePath || undefined\n }\n return `${skillName} · ${filePath || 'SKILL.md'}`\n}\n\nfunction readToolArgumentsObject(\n rawArguments: unknown,\n args: string | undefined,\n): Record<string, unknown> {\n if (\n typeof rawArguments === 'object' &&\n rawArguments !== null &&\n !Array.isArray(rawArguments)\n ) {\n return toRecord(rawArguments)\n }\n if (typeof rawArguments === 'string') {\n const decoded = decodeJsonObject(rawArguments)\n if (decoded) {\n return decoded\n }\n }\n if (!args) {\n return {}\n }\n return decodeJsonObject(args) ?? {}\n}\n\nfunction decodeJsonObject(value: string): Record<string, unknown> | undefined {\n try {\n const decoded = JSON.parse(value)\n if (\n typeof decoded !== 'object' ||\n decoded === null ||\n Array.isArray(decoded)\n ) {\n return undefined\n }\n return toRecord(decoded)\n } catch {\n return undefined\n }\n}\n\nfunction stringifyAgentValue(value: unknown): string | undefined {\n if (value === null || value === undefined) {\n return undefined\n }\n if (typeof value === 'string') {\n const trimmed = value.trim()\n return trimmed || undefined\n }\n return stableStringify(value)\n}\n\nfunction stableStringify(value: unknown): string {\n try {\n return JSON.stringify(value, (_key, data: unknown) => {\n if (!data || typeof data !== 'object' || Array.isArray(data)) {\n return data\n }\n return Object.fromEntries(\n Object.entries(data as Record<string, unknown>).sort(\n ([left], [right]) => left.localeCompare(right),\n ),\n )\n })\n } catch {\n return String(value)\n }\n}\n\nfunction hashAgentEventKey(value: string): string {\n return createHash('sha256').update(value).digest('hex').slice(0, 16)\n}\n\nfunction readErrorMessage(payload: Record<string, unknown>): string | null {\n if (typeof payload.error === 'string' && payload.error.trim()) {\n return payload.error.trim()\n }\n const error = toRecord(payload.error)\n return readString(error, 'message') ?? readString(payload, 'message')\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction readText(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n","import { LinkHttpError } from '../core/errors.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport {\n isMeaningfulAgentEventProjection,\n mergeAgentEventProjections,\n projectConversationAgentEvent,\n upsertAgentEventProjection,\n} from './agent-events.js'\nimport { ConversationMetadataCoordinator } from './conversation-metadata.js'\nimport { ConversationStore } from './conversation-store.js'\nimport {\n buildConversationRuntimeMetadata,\n readConversationProfileSummary,\n} from './profile-runtime.js'\nimport {\n emptySnapshot,\n normalizeMessagesPageLimit,\n toSummary,\n} from './conversation-view.js'\nimport type {\n ConversationEvent,\n ConversationManifest,\n ConversationMessagesPageInfo,\n ConversationMessagesPageOptions,\n ConversationProfileSummary,\n ConversationRuntimeMetadata,\n ConversationSnapshot,\n ConversationSummary,\n LinkMessage,\n LinkMessageAgentEvent,\n} from './types.js'\n\nexport interface ConversationQueryDeps {\n readonly paths: RuntimePaths\n readonly store: ConversationStore\n readonly metadata: ConversationMetadataCoordinator\n}\n\nexport class ConversationQueryCoordinator {\n constructor(private readonly deps: ConversationQueryDeps) {}\n\n async listConversations(): Promise<ConversationSummary[]> {\n const summaries: ConversationSummary[] = []\n for (const conversationId of await this.deps.store.listConversationIds()) {\n const manifest = await this.deps.store.readManifest(conversationId).catch(\n () => null,\n )\n if (!manifest || manifest.status !== 'active') {\n continue\n }\n const snapshot = await this.deps.store.readSnapshot(conversationId).catch(() =>\n emptySnapshot(),\n )\n const refreshed = await this.deps.metadata\n .refreshTitleFromHermes(manifest, { snapshot })\n .catch(() => manifest)\n summaries.push(await this.summarizeConversation(refreshed, snapshot))\n }\n return summaries.sort(\n (left, right) =>\n Date.parse(right.updated_at) - Date.parse(left.updated_at),\n )\n }\n\n async getMessages(\n conversationId: string,\n options: ConversationMessagesPageOptions = {},\n ): Promise<{\n messages: LinkMessage[]\n last_event_seq: number\n runtime: ConversationRuntimeMetadata\n page: ConversationMessagesPageInfo\n }> {\n const manifest = await this.deps.store.readActiveManifest(conversationId)\n const snapshot = await this.deps.store.readSnapshot(conversationId)\n const limit = normalizeMessagesPageLimit(options.limit)\n const total = snapshot.messages.length\n const endIndex = options.beforeMessageId\n ? snapshot.messages.findIndex(\n (message) => message.id === options.beforeMessageId,\n )\n : total\n if (endIndex < 0) {\n throw new LinkHttpError(\n 400,\n 'message_cursor_not_found',\n 'Message cursor was not found',\n )\n }\n const startIndex = Math.max(0, endIndex - limit)\n const messages = await this.hydrateAgentEventsForMessages(\n conversationId,\n snapshot.messages.slice(startIndex, endIndex),\n )\n return {\n messages,\n last_event_seq: manifest.last_event_seq,\n runtime: await buildConversationRuntimeMetadata(\n this.deps.paths,\n manifest,\n snapshot,\n ),\n page: {\n limit,\n has_more_before: startIndex > 0,\n has_more_after: endIndex < total,\n oldest_message_id: messages[0]?.id ?? null,\n newest_message_id: messages.at(-1)?.id ?? null,\n },\n }\n }\n\n async listEvents(\n conversationId: string,\n after = 0,\n ): Promise<ConversationEvent[]> {\n return this.deps.store.listEvents(conversationId, after)\n }\n\n async summarizeConversation(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot,\n profile?: ConversationProfileSummary,\n ): Promise<ConversationSummary> {\n return toSummary(\n manifest,\n snapshot,\n profile ??\n (await readConversationProfileSummary(this.deps.paths, manifest)),\n )\n }\n\n private async hydrateAgentEventsForMessages(\n conversationId: string,\n messages: LinkMessage[],\n ): Promise<LinkMessage[]> {\n if (!messages.some((message) => message.role === 'assistant')) {\n return messages\n }\n const eventsByMessageId = new Map<string, LinkMessageAgentEvent[]>()\n const events = await this.listEvents(conversationId, 0).catch(() => [])\n for (const event of events) {\n if (!event.message_id) {\n continue\n }\n const agentEvent = projectConversationAgentEvent(event)\n if (!agentEvent) {\n continue\n }\n eventsByMessageId.set(\n event.message_id,\n upsertAgentEventProjection(\n eventsByMessageId.get(event.message_id) ?? [],\n agentEvent,\n ),\n )\n }\n return messages.map((message) => {\n if (message.role !== 'assistant') {\n return message\n }\n const fromLog = eventsByMessageId.get(message.id) ?? []\n const persisted = (message.agent_events ?? []).filter(\n isMeaningfulAgentEventProjection,\n )\n const agentEvents = mergeAgentEventProjections(fromLog, persisted)\n return agentEvents.length > 0\n ? { ...message, agent_events: agentEvents }\n : message\n })\n }\n}\n","import {\n appendFile,\n mkdir,\n readdir,\n readFile,\n rm,\n writeFile,\n} from 'node:fs/promises'\nimport path from 'node:path'\nimport { LinkHttpError } from '../core/errors.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\nimport type {\n ConversationEvent,\n ConversationManifest,\n ConversationSnapshot,\n} from './types.js'\nimport { assertValidConversationId } from './blob-store.js'\n\nexport class ConversationStore {\n constructor(private readonly paths: RuntimePaths) {}\n\n async ensureConversationsDir(): Promise<void> {\n await mkdir(this.paths.conversationsDir, { recursive: true, mode: 0o700 })\n }\n\n async listConversationIds(): Promise<string[]> {\n await this.ensureConversationsDir()\n const entries = await readdir(this.paths.conversationsDir, {\n withFileTypes: true,\n }).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n })\n return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name)\n }\n\n async createConversation(\n manifest: ConversationManifest,\n snapshot: ConversationSnapshot = createEmptySnapshot(),\n ): Promise<void> {\n await mkdir(this.conversationDir(manifest.id), {\n recursive: true,\n mode: 0o700,\n })\n await this.writeManifest(manifest)\n await this.writeSnapshot(manifest.id, snapshot)\n }\n\n async readManifest(conversationId: string): Promise<ConversationManifest> {\n const manifest = await readJsonFile<ConversationManifest>(\n this.manifestPath(conversationId),\n )\n if (!manifest) {\n throw new LinkHttpError(\n 404,\n 'conversation_not_found',\n 'Conversation was not found',\n )\n }\n return manifest\n }\n\n writeManifest(manifest: ConversationManifest): Promise<void> {\n return writeJsonFile(this.manifestPath(manifest.id), manifest)\n }\n\n async readSnapshot(conversationId: string): Promise<ConversationSnapshot> {\n return (\n (await readJsonFile<ConversationSnapshot>(\n this.snapshotPath(conversationId),\n )) ?? createEmptySnapshot()\n )\n }\n\n writeSnapshot(\n conversationId: string,\n snapshot: ConversationSnapshot,\n ): Promise<void> {\n return writeJsonFile(this.snapshotPath(conversationId), snapshot)\n }\n\n async appendEvent(\n conversationId: string,\n input: Omit<ConversationEvent, 'seq' | 'conversation_id' | 'created_at'>,\n ): Promise<ConversationEvent> {\n const manifest = await this.readManifest(conversationId)\n const now = new Date().toISOString()\n const event: ConversationEvent = {\n ...input,\n seq: manifest.last_event_seq + 1,\n conversation_id: conversationId,\n created_at: now,\n }\n await mkdir(this.conversationDir(conversationId), {\n recursive: true,\n mode: 0o700,\n })\n await appendFile(\n this.eventsPath(conversationId),\n `${JSON.stringify(event)}\\n`,\n { mode: 0o600 },\n )\n await this.writeManifest({\n ...manifest,\n last_event_seq: event.seq,\n updated_at: now,\n })\n return event\n }\n\n async listEvents(\n conversationId: string,\n after = 0,\n ): Promise<ConversationEvent[]> {\n await this.readManifest(conversationId)\n const raw = await readFile(this.eventsPath(conversationId), 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n return raw\n .split('\\n')\n .filter(Boolean)\n .map((line) => JSON.parse(line) as ConversationEvent)\n .filter((event) => event.seq > after)\n }\n\n overwriteEvents(\n conversationId: string,\n events: ConversationEvent[],\n ): Promise<void> {\n const content = events.map((event) => JSON.stringify(event)).join('\\n')\n return writeFile(\n this.eventsPath(conversationId),\n content ? `${content}\\n` : '',\n { mode: 0o600 },\n )\n }\n\n async readActiveManifest(\n conversationId: string,\n ): Promise<ConversationManifest> {\n const manifest = await this.readManifest(conversationId)\n if (manifest.status !== 'active') {\n throw new LinkHttpError(\n 404,\n 'conversation_not_found',\n 'Conversation was not found',\n )\n }\n return manifest\n }\n\n async isConversationActive(conversationId: string): Promise<boolean> {\n const manifest = await this.readManifest(conversationId).catch(() => null)\n return manifest?.status === 'active'\n }\n\n removeConversationAttachments(conversationId: string): Promise<void> {\n return rm(path.join(this.conversationDir(conversationId), 'attachments'), {\n recursive: true,\n force: true,\n })\n }\n\n private conversationDir(conversationId: string): string {\n assertValidConversationId(conversationId)\n return path.join(this.paths.conversationsDir, conversationId)\n }\n\n private manifestPath(conversationId: string): string {\n return path.join(this.conversationDir(conversationId), 'manifest.json')\n }\n\n private snapshotPath(conversationId: string): string {\n return path.join(this.conversationDir(conversationId), 'snapshot.json')\n }\n\n private eventsPath(conversationId: string): string {\n return path.join(this.conversationDir(conversationId), 'events.ndjson')\n }\n}\n\nfunction createEmptySnapshot(): ConversationSnapshot {\n return { schema_version: 1, messages: [], runs: [] }\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n","import { readFile, readdir, stat } from 'node:fs/promises'\nimport path from 'node:path'\nimport {\n cancelHermesRun,\n createHermesRun,\n listHermesCronJobs,\n streamHermesRunEvents,\n} from '../hermes/api-server.js'\nimport { HERMES_LINK_DELIVERY_INSTRUCTIONS } from './delivery-contract.js'\nimport { buildConversationHistory } from './history-builder.js'\nimport { bindNewCronJobsToHermesLink } from '../hermes/cron-link-delivery.js'\nimport { readHermesApiServerHealth } from '../hermes/gateway.js'\nimport { readHermesCompressionTip } from '../hermes/session-title.js'\nimport { transcribeAudioWithHermesProfile } from '../hermes/stt.js'\nimport { LinkHttpError } from '../core/errors.js'\nimport type { FileLogger } from '../runtime/logger.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport {\n closeRunningAgentEvents,\n projectConversationAgentEvent,\n upsertAgentEventProjection,\n} from './agent-events.js'\nimport { messageText } from './conversation-view.js'\nimport { parseSseResponse, type ParsedSseEvent } from './hermes-sse.js'\nimport {\n cleanMessageTextParts,\n collectLooseMediaReferences,\n collectMediaReferences,\n collectMediaTags,\n extractStreamingMediaReferences,\n inferMimeType,\n mediaKindForMime,\n mediaSourceKey,\n readImportedMediaSourceKeys,\n resolveMediaSourcePath,\n type MediaReference,\n} from './media.js'\nimport {\n normalizeProfileName,\n readCurrentConversationRuntime,\n} from './profile-runtime.js'\nimport { readUsage } from './statistics.js'\nimport {\n emptyHermesResponseMessage as defaultEmptyHermesResponseMessage,\n buildHermesEmptyResponseDetail,\n normalizeHermesStreamEvent,\n normalizeStreamingTextDelta,\n readDelta,\n readErrorMessage,\n} from './stream-events.js'\nimport { blobPath } from './blob-store.js'\nimport type {\n CancelRunResult,\n ConversationEvent,\n ConversationManifest,\n ConversationSnapshot,\n ConversationUsageStats,\n LinkMessagePart,\n LinkRun,\n} from './types.js'\n\nconst MAX_IMPORTED_BLOB_BYTES = 100 * 1024 * 1024\n\ntype ActiveRunControllers = Map<\n string,\n { conversationId: string; controller: AbortController }\n>\n\ntype WriteBlobResult = {\n id: string\n size: number\n mime: string\n filename: string\n}\n\nexport interface ConversationRunLifecycleDeps {\n readonly paths: RuntimePaths\n readonly logger: FileLogger\n readonly activeRunControllers: ActiveRunControllers\n readonly withConversationLock: <T>(\n conversationId: string,\n task: () => Promise<T>,\n ) => Promise<T>\n readonly readSnapshot: (\n conversationId: string,\n ) => Promise<ConversationSnapshot>\n readonly writeSnapshot: (\n conversationId: string,\n snapshot: ConversationSnapshot,\n ) => Promise<void>\n readonly appendEvent: (\n conversationId: string,\n input: Omit<ConversationEvent, 'seq' | 'conversation_id' | 'created_at'>,\n ) => Promise<ConversationEvent>\n readonly persistConversationStats: (\n conversationId: string,\n snapshot: ConversationSnapshot,\n statsOverride?: ConversationUsageStats,\n ) => Promise<void>\n readonly readActiveManifest: (\n conversationId: string,\n ) => Promise<ConversationManifest>\n readonly isConversationActive: (conversationId: string) => Promise<boolean>\n readonly writeBlob: (\n conversationId: string,\n input: { bytes: Uint8Array; filename?: string; mime?: string },\n ) => Promise<WriteBlobResult>\n readonly syncCronDeliveries: () => Promise<void>\n readonly scheduleTitleRefresh: (conversationId: string) => void\n}\n\nexport class ConversationRunLifecycle {\n constructor(private readonly deps: ConversationRunLifecycleDeps) {}\n\n async startRunWorker(\n conversationId: string,\n runId: string,\n input: string,\n ): Promise<void> {\n const snapshot = await this.deps.readSnapshot(conversationId)\n const run = snapshot.runs.find((item) => item.id === runId)\n if (!run || run.status !== 'running') {\n return\n }\n const controller = new AbortController()\n this.deps.activeRunControllers.set(runId, { conversationId, controller })\n try {\n const hermesSessionId =\n (await readHermesCompressionTip(\n run.hermes_session_id,\n this.deps.paths,\n run.profile,\n ).catch(() => undefined)) ?? run.hermes_session_id\n await this.updateRun(conversationId, runId, {\n hermes_session_id: hermesSessionId,\n })\n const conversationHistory = await buildConversationHistory({\n paths: this.deps.paths,\n profileName: run.profile,\n hermesSessionId,\n snapshot,\n run,\n }).catch(async (error: unknown) => {\n await this.deps.logger.warn('conversation_history_build_failed', {\n conversation_id: conversationId,\n run_id: runId,\n error: error instanceof Error ? error.message : String(error),\n })\n return { messages: [], source: 'empty' as const }\n })\n await this.deps.logger.debug('conversation_history_built', {\n conversation_id: conversationId,\n run_id: runId,\n source: conversationHistory.source,\n message_count: conversationHistory.messages.length,\n })\n const cronJobIdsBeforeRun = await this.readHermesCronJobIds(\n run.profile,\n ).catch(() => null)\n const resolvedInput = await this.resolveRunInput({\n conversationId,\n run,\n fallbackInput: input,\n snapshot,\n })\n const hermesRun = await createHermesRun(\n {\n input: resolvedInput,\n instructions: buildRunInstructions(run),\n session_id: hermesSessionId,\n model: run.model,\n ...(conversationHistory.messages.length > 0\n ? { conversation_history: conversationHistory.messages }\n : {}),\n },\n { logger: this.deps.logger, profileName: run.profile },\n )\n await this.updateRun(conversationId, runId, {\n hermes_run_id: hermesRun.run_id,\n })\n const response = await streamHermesRunEvents(hermesRun.run_id, {\n logger: this.deps.logger,\n profileName: run.profile,\n signal: controller.signal,\n })\n for await (const rawEvent of parseSseResponse(response)) {\n if (controller.signal.aborted) {\n await this.deps.withConversationLock(conversationId, () =>\n this.cancelRunLocked(conversationId, runId, {\n abortUpstream: false,\n reason: 'cancelled by app',\n }),\n )\n return\n }\n if (!(await this.deps.isConversationActive(conversationId))) {\n return\n }\n const event = normalizeHermesStreamEvent(rawEvent)\n if (!event) {\n continue\n }\n if (event.payloadType === 'run.completed') {\n if (cronJobIdsBeforeRun) {\n await this.bindNewCronJobsCreatedByRun({\n profileName: run.profile,\n conversationId,\n beforeJobIds: cronJobIdsBeforeRun,\n })\n }\n await this.deps.syncCronDeliveries().catch((error: unknown) => {\n void this.deps.logger.warn('cron_link_delivery_sync_failed', {\n conversation_id: conversationId,\n run_id: runId,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n await this.importMediaReferencesForEvent(conversationId, runId, event)\n if (!(await this.runHasAssistantOutput(conversationId, runId))) {\n await this.failRun(\n conversationId,\n runId,\n await this.buildEmptyHermesResponseMessage({\n source: 'final-empty-response',\n }),\n event,\n )\n return\n }\n await this.completeRun(conversationId, runId, event)\n this.deps.scheduleTitleRefresh(conversationId)\n return\n }\n if (event.payloadType === 'run.failed') {\n await this.importMediaReferencesForEvent(conversationId, runId, event)\n await this.failRun(\n conversationId,\n runId,\n readErrorMessage(event.payload) ?? 'Hermes run failed',\n event,\n )\n return\n }\n await this.persistHermesEvent(conversationId, runId, event)\n }\n if (controller.signal.aborted) {\n await this.deps.withConversationLock(conversationId, () =>\n this.cancelRunLocked(conversationId, runId, {\n abortUpstream: false,\n reason: 'cancelled by app',\n }),\n )\n return\n }\n if (await this.runHasAssistantOutput(conversationId, runId)) {\n await this.completeRun(conversationId, runId)\n } else {\n await this.failRun(\n conversationId,\n runId,\n await this.buildEmptyHermesResponseMessage({\n source: 'final-empty-response',\n }),\n )\n }\n this.deps.scheduleTitleRefresh(conversationId)\n } catch (error) {\n if (controller.signal.aborted) {\n await this.deps.withConversationLock(conversationId, () =>\n this.cancelRunLocked(conversationId, runId, {\n abortUpstream: false,\n reason: 'cancelled by app',\n }),\n )\n return\n }\n throw error\n } finally {\n if (\n this.deps.activeRunControllers.get(runId)?.controller === controller\n ) {\n this.deps.activeRunControllers.delete(runId)\n }\n }\n }\n\n async cancelRun(\n conversationId: string,\n runId: string,\n options: { abortUpstream: boolean; reason: string },\n ): Promise<CancelRunResult> {\n return this.deps.withConversationLock(conversationId, () =>\n this.cancelRunLocked(conversationId, runId, options),\n )\n }\n\n async failRun(\n conversationId: string,\n runId: string,\n message: string,\n source?: ParsedSseEvent,\n ): Promise<void> {\n return this.deps.withConversationLock(conversationId, () =>\n this.failRunLocked(conversationId, runId, message, source),\n )\n }\n\n async findConversationIdForRun(runId: string): Promise<string | undefined> {\n const entries = await readdirWithDirs(this.deps.paths.conversationsDir)\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue\n }\n const snapshot = await this.deps\n .readSnapshot(entry.name)\n .catch(() => null)\n if (snapshot?.runs.some((run) => run.id === runId)) {\n return entry.name\n }\n }\n return undefined\n }\n\n private async resolveRunInput(input: {\n conversationId: string\n run: LinkRun\n fallbackInput: string\n snapshot: ConversationSnapshot\n }): Promise<string> {\n const userMessage = input.snapshot.messages.find(\n (message) => message.id === input.run.trigger_message_id,\n )\n if (!userMessage || !userMessage.parts.some(isVoicePart)) {\n return input.fallbackInput\n }\n\n const content = messageText(userMessage)\n const voiceLines: string[] = []\n for (const part of userMessage.parts.filter(isVoicePart)) {\n const audioPath =\n part.local_path ??\n (part.blob ? blobPath(this.deps.paths, part.blob) : '')\n const result = await transcribeAudioWithHermesProfile({\n audioPath,\n profileName: input.run.profile,\n logger: this.deps.logger,\n })\n const label = part.filename ?? part.blob ?? 'voice message'\n voiceLines.push(`- ${label}: ${result.transcript}`)\n }\n\n const attachmentLines = userMessage.parts\n .filter((part) => Boolean(part.blob))\n .filter((part) => !isVoicePart(part))\n .map((part) => {\n const label = part.filename ?? part.blob\n const mime = part.mime ? `, ${part.mime}` : ''\n const size = part.size ? `, ${part.size} bytes` : ''\n return `- ${label}${mime}${size}: ${\n part.local_path ?? blobPath(this.deps.paths, part.blob!)\n }`\n })\n\n const sections: string[] = []\n if (voiceLines.length > 0) {\n sections.push(`Voice message transcript:\\n${voiceLines.join('\\n')}`)\n }\n if (attachmentLines.length > 0) {\n sections.push(\n `Attachments available on this computer:\\n${attachmentLines.join('\\n')}`,\n )\n }\n if (sections.length === 0) {\n return content\n }\n return `${content ? `${content}\\n\\n` : ''}${sections.join('\\n\\n')}`\n }\n\n private async updateRun(\n conversationId: string,\n runId: string,\n patch: Partial<LinkRun>,\n ): Promise<void> {\n return this.deps.withConversationLock(conversationId, () =>\n this.updateRunLocked(conversationId, runId, patch),\n )\n }\n\n private async updateRunLocked(\n conversationId: string,\n runId: string,\n patch: Partial<LinkRun>,\n ): Promise<void> {\n const snapshot = await this.deps.readSnapshot(conversationId)\n const run = snapshot.runs.find((item) => item.id === runId)\n if (!run) {\n return\n }\n Object.assign(run, patch)\n await this.deps.writeSnapshot(conversationId, snapshot)\n }\n\n private async runHasAssistantOutput(\n conversationId: string,\n runId: string,\n ): Promise<boolean> {\n const snapshot = await this.deps\n .readSnapshot(conversationId)\n .catch(() => null)\n const run = snapshot?.runs.find((item) => item.id === runId)\n const assistant = snapshot?.messages.find(\n (item) => item.id === run?.assistant_message_id,\n )\n if (!assistant) {\n return false\n }\n return (\n messageText(assistant).length > 0 ||\n (assistant.agent_events?.length ?? 0) > 0 ||\n assistant.parts.some((part) => part.type !== 'text')\n )\n }\n\n private async buildEmptyHermesResponseMessage(input?: {\n source?: 'final-empty-response' | 'run-failed' | 'stream-error'\n upstreamError?: string | null\n eventError?: string | null\n }): Promise<string> {\n const runtime = await readCurrentConversationRuntime(this.deps.paths).catch(\n () => null,\n )\n const health = await readHermesApiServerHealth().catch(() => null)\n const details = buildHermesEmptyResponseDetail({\n model: runtime?.model,\n provider: runtime?.provider,\n healthIssue: health?.issue ?? null,\n upstreamError: input?.upstreamError ?? null,\n eventError: input?.eventError ?? null,\n })\n if (input?.source === 'final-empty-response') {\n details.unshift('Hermes 已完成运行,但没有产出可显示内容。')\n if (!health?.issue) {\n details.push(\n '如果这是刚新增或切换的模型,优先检查模型配置是否已被 Gateway 重载,以及 provider 是否真的返回了 assistant 正文。',\n )\n }\n }\n return details.length > 0\n ? `Hermes 没有返回有效内容。\\n${details.join('\\n')}`\n : defaultEmptyHermesResponseMessage()\n }\n\n private async persistHermesEvent(\n conversationId: string,\n runId: string,\n event: ParsedSseEvent,\n ): Promise<void> {\n return this.deps.withConversationLock(conversationId, () =>\n this.persistHermesEventLocked(conversationId, runId, event),\n )\n }\n\n private async persistHermesEventLocked(\n conversationId: string,\n runId: string,\n event: ParsedSseEvent,\n ): Promise<void> {\n if (!(await this.deps.isConversationActive(conversationId))) {\n return\n }\n if (event.payloadType === 'message.delta') {\n const delta = readDelta(event.payload)\n if (delta) {\n await this.appendAssistantDelta(\n conversationId,\n runId,\n delta,\n event.payload,\n )\n }\n return\n }\n const messageId = await this.assistantMessageIdForRun(conversationId, runId)\n const shouldImportLooseToolMedia =\n isFileSearchCompletion(event.payloadType, event.payload) &&\n (await this.runRequestsAppDelivery(conversationId, runId))\n const mediaReferences = [\n ...collectMediaReferences(event.payload),\n ...(shouldImportLooseToolMedia\n ? collectLooseMediaReferences(event.payload)\n : []),\n ]\n const conversationEvent = await this.deps.appendEvent(conversationId, {\n type: event.payloadType,\n message_id: messageId,\n run_id: runId,\n payload: event.payload,\n raw: { format: 'hermes-run-event', payload: event.rawPayload },\n })\n if (messageId) {\n await this.persistAgentEventProjection(\n conversationId,\n messageId,\n conversationEvent,\n )\n await this.importMediaReferences(\n conversationId,\n runId,\n messageId,\n mediaReferences,\n )\n }\n }\n\n private async persistAgentEventProjection(\n conversationId: string,\n messageId: string,\n event: ConversationEvent,\n ): Promise<void> {\n const agentEvent = projectConversationAgentEvent(event)\n if (!agentEvent) {\n return\n }\n const snapshot = await this.deps.readSnapshot(conversationId)\n const assistant = snapshot.messages.find(\n (message) => message.id === messageId,\n )\n if (!assistant) {\n return\n }\n assistant.agent_events = upsertAgentEventProjection(\n assistant.agent_events ?? [],\n agentEvent,\n )\n assistant.updated_at = event.created_at\n await this.deps.writeSnapshot(conversationId, snapshot)\n }\n\n private async importMediaReferencesForEvent(\n conversationId: string,\n runId: string,\n event: ParsedSseEvent,\n ): Promise<void> {\n return this.deps.withConversationLock(conversationId, () =>\n this.importMediaReferencesForEventLocked(conversationId, runId, event),\n )\n }\n\n private async importMediaReferencesForEventLocked(\n conversationId: string,\n runId: string,\n event: ParsedSseEvent,\n ): Promise<void> {\n const messageId = await this.assistantMessageIdForRun(conversationId, runId)\n if (!messageId) {\n return\n }\n await this.importMediaReferences(\n conversationId,\n runId,\n messageId,\n collectMediaReferences(event.payload),\n )\n }\n\n private async appendAssistantDelta(\n conversationId: string,\n runId: string,\n delta: string,\n rawPayload: unknown,\n ): Promise<void> {\n const snapshot = await this.deps.readSnapshot(conversationId)\n const run = snapshot.runs.find((item) => item.id === runId)\n if (!run) {\n return\n }\n const assistant = snapshot.messages.find(\n (message) => message.id === run.assistant_message_id,\n )\n if (!assistant) {\n return\n }\n const textPart = assistant.parts.find((part) => part.type === 'text')\n const currentText = textPart?.text ?? ''\n const pendingDeliveryText = readString(\n toRecord(assistant.hermes),\n 'pending_media_delivery_text',\n )\n const normalizedDelta = normalizeStreamingTextDelta(\n `${currentText}${pendingDeliveryText ?? ''}`,\n delta,\n )\n if (!normalizedDelta) {\n return\n }\n const extracted = extractStreamingMediaReferences(\n normalizedDelta,\n pendingDeliveryText ?? '',\n )\n const nextHermes = {\n ...toRecord(assistant.hermes),\n ...(extracted.pendingText\n ? { pending_media_delivery_text: extracted.pendingText }\n : {}),\n }\n if (!extracted.pendingText) {\n delete nextHermes.pending_media_delivery_text\n }\n assistant.hermes = nextHermes\n if (textPart) {\n const nextText = `${currentText}${extracted.visibleText}`\n textPart.text =\n extracted.references.length > 0 ? nextText.trimEnd() : nextText\n } else if (extracted.visibleText) {\n assistant.parts.push({ type: 'text', text: extracted.visibleText })\n }\n assistant.updated_at = new Date().toISOString()\n assistant.raw = { format: 'hermes-run-event', payload: rawPayload }\n await this.deps.writeSnapshot(conversationId, snapshot)\n if (extracted.visibleText) {\n await this.deps.appendEvent(conversationId, {\n type: 'message.delta',\n message_id: assistant.id,\n run_id: runId,\n payload: { delta: extracted.visibleText },\n raw: { format: 'hermes-run-event', payload: rawPayload },\n })\n }\n await this.importMediaReferences(\n conversationId,\n runId,\n assistant.id,\n extracted.references,\n )\n }\n\n private async runRequestsAppDelivery(\n conversationId: string,\n runId: string,\n ): Promise<boolean> {\n const snapshot = await this.deps\n .readSnapshot(conversationId)\n .catch(() => null)\n const run = snapshot?.runs.find((item) => item.id === runId)\n const user = snapshot?.messages.find(\n (message) => message.id === run?.trigger_message_id,\n )\n return user ? messageRequestsAppDelivery(messageText(user)) : false\n }\n\n private async completeRun(\n conversationId: string,\n runId: string,\n source?: ParsedSseEvent,\n ): Promise<void> {\n return this.deps.withConversationLock(conversationId, () =>\n this.completeRunLocked(conversationId, runId, source),\n )\n }\n\n private async completeRunLocked(\n conversationId: string,\n runId: string,\n source?: ParsedSseEvent,\n ): Promise<void> {\n let snapshot = await this.deps.readSnapshot(conversationId)\n let run = snapshot.runs.find((item) => item.id === runId)\n if (!run || run.status !== 'running') {\n return\n }\n const initialRun = run\n let assistant = snapshot.messages.find(\n (message) => message.id === initialRun.assistant_message_id,\n )\n if (assistant) {\n await this.importMediaReferences(\n conversationId,\n runId,\n assistant.id,\n collectMediaTags(messageText(assistant)),\n )\n snapshot = await this.deps.readSnapshot(conversationId)\n const refreshedRun = snapshot.runs.find((item) => item.id === runId)\n if (!refreshedRun) {\n return\n }\n run = refreshedRun\n assistant = snapshot.messages.find(\n (message) => message.id === refreshedRun.assistant_message_id,\n )\n }\n const completedAt = new Date().toISOString()\n const usage = readUsage(source?.payload)\n run.status = 'completed'\n run.completed_at = completedAt\n if (usage) {\n run.usage = usage\n }\n if (assistant) {\n assistant.status = 'completed'\n assistant.updated_at = completedAt\n assistant.agent_events = closeRunningAgentEvents(\n assistant.agent_events,\n 'completed',\n completedAt,\n )\n cleanMessageTextParts(assistant)\n }\n await this.deps.writeSnapshot(conversationId, snapshot)\n if (assistant) {\n await this.deps.appendEvent(conversationId, {\n type: 'message.completed',\n message_id: assistant.id,\n run_id: runId,\n payload: { message: assistant },\n })\n }\n const contextUsage = contextUsagePayload(run)\n await this.deps.appendEvent(conversationId, {\n type: 'run.completed',\n message_id: assistant?.id,\n run_id: runId,\n payload: {\n run,\n ...(contextUsage ? { context: contextUsage } : {}),\n ...(source ? { hermes: source.payload } : {}),\n },\n ...(source\n ? { raw: { format: 'hermes-run-event', payload: source.rawPayload } }\n : {}),\n })\n await this.deps.persistConversationStats(conversationId, snapshot)\n }\n\n private async failRunLocked(\n conversationId: string,\n runId: string,\n message: string,\n source?: ParsedSseEvent,\n ): Promise<void> {\n const snapshot = await this.deps\n .readSnapshot(conversationId)\n .catch(() => null)\n if (!snapshot) {\n return\n }\n const run = snapshot.runs.find((item) => item.id === runId)\n if (!run || run.status !== 'running') {\n return\n }\n run.status = 'failed'\n run.completed_at = new Date().toISOString()\n run.error_message = message\n run.error_detail = source\n ? (readErrorMessage(source.payload) ?? undefined)\n : undefined\n const visibleMessage = formatFailureMessage(message, run.error_detail)\n const usage = readUsage(source?.payload)\n if (usage) {\n run.usage = usage\n }\n const assistant = snapshot.messages.find(\n (item) => item.id === run.assistant_message_id,\n )\n if (assistant) {\n assistant.status = 'failed'\n assistant.updated_at = run.completed_at\n assistant.agent_events = closeRunningAgentEvents(\n assistant.agent_events,\n 'failed',\n run.completed_at,\n )\n const textPart = assistant.parts.find((part) => part.type === 'text')\n if (textPart && !textPart.text) {\n textPart.text = visibleMessage\n }\n }\n await this.deps.writeSnapshot(conversationId, snapshot)\n await this.deps.appendEvent(conversationId, {\n type: 'run.failed',\n message_id: assistant?.id,\n run_id: runId,\n payload: {\n error: { message },\n ...(run.error_detail ? { error_detail: run.error_detail } : {}),\n run,\n ...(source ? { hermes: source.payload } : {}),\n },\n ...(source\n ? { raw: { format: 'hermes-run-event', payload: source.rawPayload } }\n : {}),\n })\n await this.deps.persistConversationStats(conversationId, snapshot)\n void this.deps.logger.warn('conversation_run_failed', {\n conversation_id: conversationId,\n run_id: runId,\n error: message,\n })\n }\n\n private async cancelRunLocked(\n conversationId: string,\n runId: string,\n options: { abortUpstream: boolean; reason: string },\n ): Promise<CancelRunResult> {\n const manifest = await this.deps.readActiveManifest(conversationId)\n const snapshot = await this.deps.readSnapshot(conversationId)\n const run = snapshot.runs.find((item) => item.id === runId)\n if (!run) {\n throw new LinkHttpError(404, 'run_not_found', 'Run was not found')\n }\n if (run.status !== 'running') {\n return {\n conversation_id: conversationId,\n run: { id: run.id, status: run.status },\n last_event_seq: manifest.last_event_seq,\n }\n }\n if (options.abortUpstream) {\n this.deps.activeRunControllers.get(runId)?.controller.abort()\n if (run.hermes_run_id) {\n void cancelHermesRun(run.hermes_run_id, {\n logger: this.deps.logger,\n profileName: run.profile,\n }).catch((error: unknown) => {\n void this.deps.logger.debug('hermes_run_cancel_failed', {\n conversation_id: conversationId,\n run_id: runId,\n hermes_run_id: run.hermes_run_id,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n }\n }\n\n const cancelledAt = new Date().toISOString()\n run.status = 'cancelled'\n run.completed_at = cancelledAt\n run.error_message = options.reason\n const assistant = snapshot.messages.find(\n (item) => item.id === run.assistant_message_id,\n )\n if (assistant) {\n assistant.status = 'cancelled'\n assistant.updated_at = cancelledAt\n assistant.agent_events = closeRunningAgentEvents(\n assistant.agent_events,\n 'failed',\n cancelledAt,\n )\n cleanMessageTextParts(assistant)\n }\n await this.deps.writeSnapshot(conversationId, snapshot)\n if (assistant) {\n await this.deps.appendEvent(conversationId, {\n type: 'message.completed',\n message_id: assistant.id,\n run_id: runId,\n payload: { message: assistant, cancelled: true },\n })\n }\n const event = await this.deps.appendEvent(conversationId, {\n type: 'run.cancelled',\n message_id: assistant?.id,\n run_id: runId,\n payload: { run, reason: options.reason },\n })\n await this.deps.persistConversationStats(conversationId, snapshot)\n void this.deps.logger.info('conversation_run_cancelled', {\n conversation_id: conversationId,\n run_id: runId,\n })\n return {\n conversation_id: conversationId,\n run: { id: run.id, status: run.status },\n last_event_seq: event.seq,\n }\n }\n\n private async assistantMessageIdForRun(\n conversationId: string,\n runId: string,\n ): Promise<string | undefined> {\n const snapshot = await this.deps\n .readSnapshot(conversationId)\n .catch(() => null)\n return snapshot?.runs.find((item) => item.id === runId)\n ?.assistant_message_id\n }\n\n private async importMediaReferences(\n conversationId: string,\n runId: string,\n messageId: string,\n references: MediaReference[],\n ): Promise<void> {\n if (references.length === 0) {\n return\n }\n const snapshot = await this.deps.readSnapshot(conversationId)\n const assistant = snapshot.messages.find(\n (message) => message.id === messageId,\n )\n if (!assistant) {\n return\n }\n const importedSourceKeys = readImportedMediaSourceKeys(assistant)\n const importedParts: LinkMessagePart[] = []\n for (const reference of references.slice(0, 10)) {\n try {\n const sourceKey = mediaSourceKey(reference.path)\n if (importedSourceKeys.has(sourceKey)) {\n continue\n }\n const blob = await this.writeBlobFromFile(conversationId, reference)\n const part: LinkMessagePart = {\n type: reference.kind ?? mediaKindForMime(blob.mime),\n blob: blob.id,\n mime: blob.mime,\n size: blob.size,\n filename: blob.filename,\n url: `/api/v1/conversations/${encodeURIComponent(conversationId)}/blobs/${encodeURIComponent(blob.id)}`,\n }\n assistant.parts.push(part)\n assistant.attachments.push({\n blob_id: blob.id,\n mime: blob.mime,\n size: blob.size,\n filename: blob.filename,\n source: 'hermes_output',\n })\n importedSourceKeys.add(sourceKey)\n importedParts.push(part)\n } catch (error) {\n void this.deps.logger.warn('conversation_media_import_failed', {\n conversation_id: conversationId,\n run_id: runId,\n message_id: messageId,\n error: error instanceof Error ? error.message : String(error),\n })\n }\n }\n if (importedParts.length === 0) {\n return\n }\n assistant.hermes = {\n ...toRecord(assistant.hermes),\n imported_media_source_keys: [...importedSourceKeys],\n }\n assistant.updated_at = new Date().toISOString()\n await this.deps.writeSnapshot(conversationId, snapshot)\n await this.deps.appendEvent(conversationId, {\n type: 'message.parts.created',\n message_id: messageId,\n run_id: runId,\n payload: { parts: importedParts },\n })\n }\n\n private async writeBlobFromFile(\n conversationId: string,\n source: MediaReference,\n ): Promise<WriteBlobResult> {\n const sourcePath = resolveMediaSourcePath(source.path)\n const fileStat = await stat(sourcePath).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n throw new LinkHttpError(\n 404,\n 'media_source_not_found',\n 'Hermes output file was not found',\n )\n }\n throw error\n })\n if (!fileStat.isFile()) {\n throw new LinkHttpError(\n 400,\n 'media_source_not_file',\n 'Hermes output media source is not a file',\n )\n }\n if (fileStat.size > MAX_IMPORTED_BLOB_BYTES) {\n throw new LinkHttpError(\n 413,\n 'media_source_too_large',\n 'Hermes output media source is too large',\n )\n }\n return this.deps.writeBlob(conversationId, {\n bytes: await readFile(sourcePath),\n filename: path.basename(sourcePath),\n mime: source.mime ?? inferMimeType(sourcePath),\n })\n }\n\n private async readHermesCronJobIds(\n profileName?: string,\n ): Promise<Set<string>> {\n const jobs = await listHermesCronJobs({\n logger: this.deps.logger,\n profileName: normalizeProfileName(profileName),\n includeDisabled: true,\n })\n return new Set(\n jobs\n .map((job) => readString(job, 'id') ?? readString(job, 'job_id'))\n .filter((id): id is string => Boolean(id)),\n )\n }\n\n private async bindNewCronJobsCreatedByRun(input: {\n profileName?: string\n conversationId: string\n beforeJobIds: Set<string>\n }): Promise<void> {\n const profileName = normalizeProfileName(input.profileName)\n const jobs = await listHermesCronJobs({\n logger: this.deps.logger,\n profileName,\n includeDisabled: true,\n })\n await bindNewCronJobsToHermesLink(this.deps.paths, {\n profileName,\n conversationId: input.conversationId,\n beforeJobIds: input.beforeJobIds,\n jobs,\n })\n }\n}\n\nfunction buildRunInstructions(run: LinkRun): string {\n return [\n HERMES_LINK_DELIVERY_INSTRUCTIONS,\n '',\n 'Current runtime selected by Hermes Link:',\n `- Model: ${run.model ?? 'hermes-agent'}`,\n `- Provider: ${run.provider ?? 'unknown'}`,\n 'If the user asks what model or provider you are currently using, answer from this runtime selection instead of inferring from earlier conversation history.',\n ].join('\\n')\n}\n\nasync function readdirWithDirs(directory: string) {\n return readdir(directory, { withFileTypes: true }).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n })\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction formatFailureMessage(message: string, detail?: string): string {\n const normalizedMessage = message.trim()\n const normalizedDetail = detail?.trim()\n if (!normalizedDetail || normalizedDetail === normalizedMessage) {\n return normalizedMessage\n }\n return `${normalizedMessage}\\n${normalizedDetail}`\n}\n\nfunction isFileSearchCompletion(\n payloadType: string,\n payload: Record<string, unknown>,\n): boolean {\n if (payloadType !== 'tool.completed') {\n return false\n }\n const tool = toRecord(payload.tool)\n const toolCall = toRecord(payload.tool_call ?? payload.toolCall)\n const fn = toRecord(toolCall.function ?? payload.function)\n const candidates = [\n readString(payload, 'tool_name'),\n readString(payload, 'toolName'),\n readString(payload, 'name'),\n readString(payload, 'tool'),\n readString(tool, 'name'),\n readString(toolCall, 'name'),\n readString(fn, 'name'),\n ]\n .filter((value): value is string => Boolean(value))\n .map(normalizeToolName)\n return candidates.some((name) =>\n [\n 'search_files',\n 'search_file',\n 'file_search',\n 'find_files',\n 'find_file',\n 'locate_files',\n 'locate_file',\n 'list_files',\n 'glob',\n ].includes(name),\n )\n}\n\nfunction messageRequestsAppDelivery(text: string): boolean {\n const normalized = text.trim()\n if (!normalized) {\n return false\n }\n const hasChineseDeliverable =\n /(图片|照片|图像|截图|文件|附件|文档|表格|压缩包|音频|录音|视频|生成物|产物|pdf)/iu.test(\n normalized,\n )\n const hasChineseDeliveryAction =\n /(发给我|发送给我|传给我|分享给我|给我发|给我传|发一下|发下|发送一下|传一下|发过来|发我|发到(?:app|手机)|附上|作为附件|以附件|给我看|展示给我|显示给我)/iu.test(\n normalized,\n )\n if (hasChineseDeliverable && hasChineseDeliveryAction) {\n return true\n }\n const lower = normalized.toLowerCase()\n const hasEnglishDeliverable =\n /\\b(image|photo|picture|file|screenshot|attachment|audio|recording|video|pdf|document|spreadsheet|archive|zip|artifact)s?\\b/u.test(\n lower,\n )\n const hasEnglishDeliveryAction =\n /\\b(send|share|attach|deliver|display)\\b/u.test(lower) ||\n /\\bshow\\s+me\\b/u.test(lower)\n return hasEnglishDeliverable && hasEnglishDeliveryAction\n}\n\nfunction isVoicePart(part: LinkMessagePart): boolean {\n return part.kind === 'voice' || part.is_voice_note === true\n}\n\nfunction normalizeToolName(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[\\s-]+/gu, '_')\n}\n\nfunction contextUsagePayload(run: LinkRun) {\n const usage = run.usage\n const contextTokens = usage?.context_tokens\n if (contextTokens === undefined) {\n return null\n }\n const contextWindow = usage?.context_window ?? run.context_window\n return {\n input_tokens: contextTokens,\n output_tokens: usage?.output_tokens ?? 0,\n total_tokens: usage?.total_tokens ?? contextTokens,\n ...(contextWindow ? { context_window: contextWindow } : {}),\n ...(usage?.usage_percent !== undefined\n ? { usage_percent: usage.usage_percent }\n : contextWindow\n ? {\n usage_percent: Math.min(\n 100,\n Math.round((contextTokens / contextWindow) * 100),\n ),\n }\n : {}),\n }\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n","import { LinkHttpError } from '../core/errors.js'\nimport type { FileLogger } from '../runtime/logger.js'\nimport {\n assertHermesRunsApiSupported,\n ensureHermesApiServerAvailable,\n readHermesVersion,\n} from './gateway.js'\n\nexport interface HermesRunRequest {\n input: string\n instructions?: string\n conversation_history?: Array<{ role: string; content: string }>\n session_id?: string\n model?: string\n}\n\nexport interface HermesChatCompletionStreamRequest {\n input: string\n sessionId: string\n model?: string\n profileName?: string\n signal?: AbortSignal\n}\n\nexport interface HermesApiClientOptions {\n fetchImpl?: typeof fetch\n logger?: FileLogger\n profileName?: string\n signal?: AbortSignal\n}\n\nexport interface HermesCronJobInput {\n name?: string\n prompt?: string\n schedule?: string\n deliver?: string\n skills?: string[]\n repeat?: number\n enabled?: boolean\n}\n\nexport async function listHermesModels(\n options: HermesApiClientOptions = {},\n): Promise<unknown> {\n const response = await callHermesApi('/v1/models', { method: 'GET' }, options)\n if (response.status === 404) {\n return { models: [] }\n }\n return await readJsonResponse(response)\n}\n\nexport async function listHermesCronJobs(\n options: HermesApiClientOptions & { includeDisabled?: boolean } = {},\n): Promise<Record<string, unknown>[]> {\n const query = options.includeDisabled ? '?include_disabled=true' : ''\n const response = await callHermesApi(\n `/api/jobs${query}`,\n { method: 'GET' },\n options,\n )\n const payload = await readJsonResponse(response)\n const jobs = payload.jobs\n return Array.isArray(jobs)\n ? jobs.filter(isRecord).map((job) => ({ ...job }))\n : []\n}\n\nexport async function getHermesCronJob(\n jobId: string,\n options: HermesApiClientOptions = {},\n): Promise<Record<string, unknown>> {\n const response = await callHermesApi(\n `/api/jobs/${encodeURIComponent(jobId)}`,\n { method: 'GET' },\n options,\n )\n const payload = await readJsonResponse(response)\n if (!isRecord(payload.job)) {\n throw new LinkHttpError(\n 502,\n 'hermes_cron_job_invalid',\n 'Hermes API Server did not return a cron job',\n )\n }\n return { ...payload.job }\n}\n\nexport async function createHermesCronJob(\n input: HermesCronJobInput,\n options: HermesApiClientOptions = {},\n): Promise<Record<string, unknown>> {\n const response = await callHermesApi(\n '/api/jobs',\n {\n method: 'POST',\n body: JSON.stringify(input),\n headers: { 'content-type': 'application/json' },\n },\n options,\n )\n const payload = await readJsonResponse(response)\n if (!isRecord(payload.job)) {\n throw new LinkHttpError(\n 502,\n 'hermes_cron_job_invalid',\n 'Hermes API Server did not return a cron job',\n )\n }\n return { ...payload.job }\n}\n\nexport async function updateHermesCronJob(\n jobId: string,\n input: HermesCronJobInput,\n options: HermesApiClientOptions = {},\n): Promise<Record<string, unknown>> {\n const response = await callHermesApi(\n `/api/jobs/${encodeURIComponent(jobId)}`,\n {\n method: 'PATCH',\n body: JSON.stringify(input),\n headers: { 'content-type': 'application/json' },\n },\n options,\n )\n const payload = await readJsonResponse(response)\n if (!isRecord(payload.job)) {\n throw new LinkHttpError(\n 502,\n 'hermes_cron_job_invalid',\n 'Hermes API Server did not return a cron job',\n )\n }\n return { ...payload.job }\n}\n\nexport async function deleteHermesCronJob(\n jobId: string,\n options: HermesApiClientOptions = {},\n): Promise<void> {\n const response = await callHermesApi(\n `/api/jobs/${encodeURIComponent(jobId)}`,\n { method: 'DELETE' },\n options,\n )\n await readJsonResponse(response)\n}\n\nexport async function runHermesCronJobAction(\n jobId: string,\n action: 'pause' | 'resume' | 'run',\n options: HermesApiClientOptions = {},\n): Promise<Record<string, unknown>> {\n const response = await callHermesApi(\n `/api/jobs/${encodeURIComponent(jobId)}/${action}`,\n { method: 'POST' },\n options,\n )\n const payload = await readJsonResponse(response)\n if (!isRecord(payload.job)) {\n throw new LinkHttpError(\n 502,\n 'hermes_cron_job_invalid',\n 'Hermes API Server did not return a cron job',\n )\n }\n return { ...payload.job }\n}\n\nexport async function createHermesRun(\n input: HermesRunRequest,\n options: HermesApiClientOptions = {},\n): Promise<{ run_id: string; fallback: boolean }> {\n const response = await callHermesApi(\n '/v1/runs',\n {\n method: 'POST',\n body: JSON.stringify(input),\n headers: { 'content-type': 'application/json' },\n },\n options,\n )\n if (response.status === 404 || response.status === 503) {\n assertHermesRunsApiSupported(\n await readHermesVersion().catch(() => null),\n response.status,\n )\n throw new LinkHttpError(\n 503,\n 'hermes_api_server_unavailable',\n 'Hermes API Server is unavailable',\n )\n }\n const payload = await readJsonResponse(response)\n const runId =\n readString(payload, 'run_id') ??\n readString(payload, 'runId') ??\n readString(payload, 'id')\n if (!runId) {\n throw new LinkHttpError(\n 502,\n 'hermes_run_invalid',\n 'Hermes API Server did not return a run id',\n )\n }\n return { run_id: runId, fallback: false }\n}\n\nexport async function streamHermesRunEvents(\n runId: string,\n options: HermesApiClientOptions = {},\n): Promise<Response> {\n const response = await callHermesApi(\n `/v1/runs/${encodeURIComponent(runId)}/events`,\n { method: 'GET', signal: options.signal },\n options,\n )\n assertHermesRunsApiSupported(\n await readHermesVersion().catch(() => null),\n response.status,\n )\n if (!response.ok || !response.body) {\n throw new LinkHttpError(\n 502,\n 'hermes_events_unavailable',\n 'Hermes run event stream is unavailable',\n )\n }\n return new Response(response.body, {\n status: response.status,\n headers: {\n 'content-type':\n response.headers.get('content-type') ??\n 'text/event-stream; charset=utf-8',\n 'cache-control': 'no-store',\n },\n })\n}\n\nexport async function streamHermesChatCompletion(\n input: HermesChatCompletionStreamRequest,\n options: HermesApiClientOptions = {},\n): Promise<Response> {\n const response = await callHermesApi(\n '/v1/chat/completions',\n {\n method: 'POST',\n body: JSON.stringify({\n model: input.model ?? 'hermes-agent',\n stream: true,\n messages: [{ role: 'user', content: input.input }],\n }),\n headers: {\n accept: 'text/event-stream',\n 'content-type': 'application/json',\n 'x-hermes-session-id': input.sessionId,\n },\n signal: input.signal,\n },\n { ...options, profileName: input.profileName ?? options.profileName },\n )\n if (response.status === 404 || response.status === 503) {\n assertHermesRunsApiSupported(\n await readHermesVersion().catch(() => null),\n response.status,\n )\n throw new LinkHttpError(\n 503,\n 'hermes_api_server_unavailable',\n 'Hermes API Server is unavailable',\n )\n }\n if (response.status === 403) {\n throw new LinkHttpError(\n 502,\n 'hermes_session_continuity_unavailable',\n await readUpstreamErrorMessage(\n response,\n 'Hermes API Server rejected session continuity. Configure API_SERVER_KEY so Link can use X-Hermes-Session-Id.',\n ),\n )\n }\n if (!response.ok || !response.body) {\n throw new LinkHttpError(\n 502,\n 'hermes_chat_stream_unavailable',\n await readUpstreamErrorMessage(\n response,\n 'Hermes chat completion stream is unavailable',\n ),\n )\n }\n return new Response(response.body, {\n status: response.status,\n headers: {\n 'content-type':\n response.headers.get('content-type') ??\n 'text/event-stream; charset=utf-8',\n 'cache-control': 'no-store',\n ...(response.headers.get('x-hermes-session-id')\n ? {\n 'x-hermes-session-id': response.headers.get('x-hermes-session-id')!,\n }\n : {}),\n },\n })\n}\n\nexport async function cancelHermesRun(\n runId: string,\n options: HermesApiClientOptions = {},\n): Promise<void> {\n const response = await callHermesApi(\n `/v1/runs/${encodeURIComponent(runId)}/cancel`,\n { method: 'POST' },\n options,\n )\n if (\n response.status === 404 ||\n response.status === 405 ||\n response.status === 501\n ) {\n throw new LinkHttpError(\n 501,\n 'hermes_cancel_unsupported',\n 'Hermes Agent does not expose a run cancel endpoint; only Link-managed conversation runs can be cancelled.',\n )\n }\n if (!response.ok) {\n throw new LinkHttpError(\n 502,\n 'hermes_cancel_failed',\n 'Hermes run cancel failed',\n )\n }\n}\n\nasync function callHermesApi(\n path: string,\n init: RequestInit,\n options: HermesApiClientOptions,\n): Promise<Response> {\n const method = init.method ?? 'GET'\n const startedAt = Date.now()\n void options.logger?.debug('hermes_api_request_started', { method, path })\n const availability = await ensureHermesApiServerAvailable({\n fetchImpl: options.fetchImpl,\n logger: options.logger,\n profileName: options.profileName,\n })\n let config = availability.configResult.apiServer\n const fetcher = options.fetchImpl ?? fetch\n const request = () => fetchHermesApi(fetcher, config, path, init, options)\n let response: Response\n try {\n response = await request()\n } catch (error) {\n logHermesApiError(options.logger, method, path, startedAt, error)\n throw error\n }\n if (response.status !== 401) {\n logHermesApiResponse(options.logger, method, path, startedAt, response)\n return response\n }\n void options.logger?.warn('hermes_api_request_retrying_after_401', {\n method,\n path,\n duration_ms: Date.now() - startedAt,\n })\n const refreshedAvailability = await ensureHermesApiServerAvailable({\n fetchImpl: options.fetchImpl,\n forceRestart: true,\n logger: options.logger,\n profileName: options.profileName,\n })\n config = refreshedAvailability.configResult.apiServer\n try {\n response = await request()\n } catch (error) {\n logHermesApiError(options.logger, method, path, startedAt, error)\n throw error\n }\n logHermesApiResponse(options.logger, method, path, startedAt, response)\n return response\n}\n\nasync function fetchHermesApi(\n fetcher: typeof fetch,\n config: { port?: number; key?: string },\n path: string,\n init: RequestInit,\n options: HermesApiClientOptions,\n): Promise<Response> {\n const headers = new Headers(init.headers)\n headers.set('accept', headers.get('accept') ?? 'application/json')\n if (config.key) {\n headers.set('x-api-key', config.key)\n headers.set('authorization', `Bearer ${config.key}`)\n }\n return await fetcher(`http://127.0.0.1:${config.port}${path}`, {\n ...init,\n headers,\n }).catch((error: unknown) => {\n if (isAbortError(error)) {\n throw error\n }\n void options.logger?.warn('hermes_api_server_connect_failed', {\n path,\n port: config.port ?? null,\n error: error instanceof Error ? error.message : String(error),\n })\n throw new LinkHttpError(\n 503,\n 'hermes_api_server_unavailable',\n 'Hermes API Server is unavailable',\n )\n })\n}\n\nfunction logHermesApiResponse(\n logger: FileLogger | undefined,\n method: string,\n path: string,\n startedAt: number,\n response: Response,\n): void {\n const fields = {\n method,\n path,\n status: response.status,\n duration_ms: Date.now() - startedAt,\n }\n if (response.ok) {\n void logger?.debug('hermes_api_request_succeeded', fields)\n return\n }\n void logHermesApiFailureResponse(logger, fields, response)\n}\n\nasync function logHermesApiFailureResponse(\n logger: FileLogger | undefined,\n fields: {\n method: string\n path: string\n status: number\n duration_ms: number\n },\n response: Response,\n): Promise<void> {\n if (!logger) {\n return\n }\n const upstreamError = await readUpstreamErrorForLog(response)\n await logger.warn('hermes_api_request_failed', {\n ...fields,\n ...(upstreamError ? { upstream_error: upstreamError } : {}),\n })\n}\n\nfunction logHermesApiError(\n logger: FileLogger | undefined,\n method: string,\n path: string,\n startedAt: number,\n error: unknown,\n): void {\n void logger?.warn('hermes_api_request_failed', {\n method,\n path,\n duration_ms: Date.now() - startedAt,\n ...(error instanceof LinkHttpError\n ? { status: error.status, code: error.code }\n : {}),\n error: error instanceof Error ? error.message : String(error),\n })\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === 'AbortError'\n}\n\nasync function readJsonResponse(\n response: Response,\n): Promise<Record<string, unknown>> {\n const raw = await response.text().catch(() => '')\n const payload = parseJsonObject(raw)\n if (!response.ok || typeof payload !== 'object' || payload === null) {\n throw new LinkHttpError(\n 502,\n 'hermes_response_invalid',\n `Hermes API Server returned HTTP ${response.status}: ${readUpstreamMessage(payload, raw)}`,\n )\n }\n return payload as Record<string, unknown>\n}\n\nasync function readUpstreamErrorMessage(\n response: Response,\n fallback: string,\n): Promise<string> {\n const raw = await response.text().catch(() => '')\n const payload = parseJsonObject(raw)\n const upstream = readUpstreamMessage(payload, raw)\n return upstream === 'empty response body'\n ? fallback\n : `Hermes API Server returned HTTP ${response.status}: ${upstream}`\n}\n\nasync function readUpstreamErrorForLog(\n response: Response,\n): Promise<string | null> {\n const raw = await response\n .clone()\n .text()\n .catch(() => '')\n const payload = parseJsonObject(raw)\n const message = readUpstreamMessage(payload, raw)\n return message === 'empty response body' ? null : message\n}\n\nfunction parseJsonObject(raw: string): Record<string, unknown> | null {\n if (!raw.trim()) {\n return null\n }\n try {\n const parsed = JSON.parse(raw) as unknown\n return typeof parsed === 'object' && parsed !== null\n ? (parsed as Record<string, unknown>)\n : null\n } catch {\n return null\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction readUpstreamMessage(\n payload: Record<string, unknown> | null,\n raw: string,\n): string {\n const error =\n typeof payload?.error === 'object' && payload.error !== null\n ? (payload.error as Record<string, unknown>)\n : null\n const message =\n readString(error ?? {}, 'message') ?? readString(payload ?? {}, 'message')\n if (message) {\n return message\n }\n const body = raw.trim().replace(/\\s+/gu, ' ').slice(0, 500)\n return body || 'empty response body'\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n","import { stat } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport path from 'node:path'\nimport type { DatabaseSync } from 'node:sqlite'\nimport { resolveHermesProfileDir } from '../hermes/config.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { messageText } from './conversation-view.js'\nimport type { ConversationSnapshot, LinkRun } from './types.js'\n\nconst nodeRequire = createRequire(import.meta.url)\nconst HISTORY_ROLES = new Set(['user', 'assistant'])\n\nexport interface ConversationHistoryMessage {\n role: 'user' | 'assistant'\n content: string\n}\n\nexport type ConversationHistorySource =\n | 'hermes_state_db'\n | 'link_snapshot'\n | 'empty'\n\nexport interface BuiltConversationHistory {\n messages: ConversationHistoryMessage[]\n source: ConversationHistorySource\n}\n\nexport interface BuildConversationHistoryInput {\n paths: RuntimePaths\n profileName?: string\n hermesSessionId: string\n snapshot: ConversationSnapshot\n run: LinkRun\n}\n\nexport async function buildConversationHistory(\n input: BuildConversationHistoryInput,\n): Promise<BuiltConversationHistory> {\n const snapshotHistory = buildLinkSnapshotHistory(input.snapshot, input.run)\n if (hasCrossProfileHistory(input.snapshot, input.run)) {\n return {\n messages: snapshotHistory,\n source: snapshotHistory.length > 0 ? 'link_snapshot' : 'empty',\n }\n }\n\n const hermesHistory = await readHermesStateDbHistory(\n input.hermesSessionId,\n input.paths,\n input.profileName,\n )\n if (hermesHistory.length > 0) {\n return { messages: hermesHistory, source: 'hermes_state_db' }\n }\n\n return {\n messages: snapshotHistory,\n source: snapshotHistory.length > 0 ? 'link_snapshot' : 'empty',\n }\n}\n\nasync function readHermesStateDbHistory(\n sessionId: string,\n _paths: RuntimePaths,\n profileName?: string,\n): Promise<ConversationHistoryMessage[]> {\n const normalizedSessionId = sessionId.trim()\n if (!normalizedSessionId) {\n return []\n }\n const normalizedProfileName = isValidProfileName(profileName)\n ? profileName\n : 'default'\n const dbPath = path.join(\n resolveHermesProfileDir(normalizedProfileName),\n 'state.db',\n )\n const exists = await stat(dbPath)\n .then((value) => value.isFile())\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n if (!exists) {\n return []\n }\n return readHistoryRows(dbPath, normalizedSessionId)\n}\n\nfunction readHistoryRows(\n dbPath: string,\n sessionId: string,\n): ConversationHistoryMessage[] {\n let db: DatabaseSync | null = null\n try {\n const { DatabaseSync } = nodeRequire(\n 'node:sqlite',\n ) as typeof import('node:sqlite')\n db = new DatabaseSync(dbPath, {\n readOnly: true,\n timeout: 1_000,\n })\n const rows = db\n .prepare(\n `\n SELECT role, content\n FROM messages\n WHERE session_id = ?\n AND role IN ('user', 'assistant')\n AND content IS NOT NULL\n ORDER BY timestamp, id\n `,\n )\n .all(sessionId) as Array<Record<string, unknown>>\n return rows\n .map((row) => normalizeHistoryMessage(row.role, row.content))\n .filter((message): message is ConversationHistoryMessage =>\n Boolean(message),\n )\n } catch {\n return []\n } finally {\n db?.close()\n }\n}\n\nfunction buildLinkSnapshotHistory(\n snapshot: ConversationSnapshot,\n run: LinkRun,\n): ConversationHistoryMessage[] {\n return snapshot.messages\n .filter((message) => {\n if (!HISTORY_ROLES.has(message.role)) {\n return false\n }\n if (message.status !== 'completed') {\n return false\n }\n if (\n message.id === run.trigger_message_id ||\n message.id === run.assistant_message_id\n ) {\n return false\n }\n return message.run_id !== run.id\n })\n .map((message) => normalizeHistoryMessage(message.role, messageText(message)))\n .filter((message): message is ConversationHistoryMessage =>\n Boolean(message),\n )\n}\n\nfunction hasCrossProfileHistory(\n snapshot: ConversationSnapshot,\n run: LinkRun,\n): boolean {\n const currentProfile = normalizeProfileForCompare(run.profile)\n if (!currentProfile) {\n return false\n }\n return snapshot.runs.some((item) => {\n if (item.id === run.id || item.kind !== 'agent') {\n return false\n }\n const profile = normalizeProfileForCompare(\n item.profile_name_snapshot ?? item.profile,\n )\n return profile !== null && profile !== currentProfile\n })\n}\n\nfunction normalizeHistoryMessage(\n role: unknown,\n content: unknown,\n): ConversationHistoryMessage | null {\n if (role !== 'user' && role !== 'assistant') {\n return null\n }\n const text = typeof content === 'string' ? content.trim() : ''\n if (!text) {\n return null\n }\n return { role, content: text }\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n\nfunction isValidProfileName(value: string | undefined): value is string {\n return typeof value === 'string' && /^[a-zA-Z0-9._-]{1,64}$/u.test(value)\n}\n\nfunction normalizeProfileForCompare(value: string | undefined): string | null {\n if (!isValidProfileName(value)) {\n return null\n }\n return value.trim()\n}\n","import { execFile } from \"node:child_process\";\nimport { access, readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { LinkHttpError } from \"../core/errors.js\";\nimport {\n readHermesEnvFile,\n readHermesProfileToolConfig,\n resolveHermesProfileDir,\n} from \"./config.js\";\nimport { resolveHermesBin } from \"./cli.js\";\nimport type { FileLogger } from \"../runtime/logger.js\";\n\nconst execFileAsync = promisify(execFile);\nconst STT_RESULT_PREFIX = \"__HERMES_LINK_STT__\";\nconst STT_TIMEOUT_MS = 180_000;\nconst STT_MAX_BUFFER_BYTES = 2 * 1024 * 1024;\n\nexport interface HermesTranscriptionResult {\n transcript: string;\n provider?: string;\n}\n\nexport async function transcribeAudioWithHermesProfile(input: {\n audioPath: string;\n profileName?: string;\n logger?: FileLogger;\n}): Promise<HermesTranscriptionResult> {\n const profileName = input.profileName?.trim() || \"default\";\n const toolConfig = await readHermesProfileToolConfig(profileName, \"stt\");\n if (toolConfig.values.enabled === false) {\n throw new LinkHttpError(\n 422,\n \"voice_stt_disabled\",\n \"语音转写未启用。请在 App 的 Profile 工具管理中启用语音转写 (STT)。\",\n );\n }\n\n const python = await resolveHermesPythonCommand();\n const env = await buildHermesSttEnv(profileName);\n const script = [\n \"import json, sys\",\n \"try:\",\n \" from tools.transcription_tools import transcribe_audio\",\n \" result = transcribe_audio(sys.argv[1])\",\n \"except Exception as exc:\",\n ' result = {\"success\": False, \"transcript\": \"\", \"error\": str(exc)}',\n `print(${JSON.stringify(STT_RESULT_PREFIX)} + json.dumps(result, ensure_ascii=False))`,\n ].join(\"\\n\");\n\n await input.logger?.debug(\"voice_stt_started\", {\n profile: profileName,\n provider: toolConfig.values.provider ?? null,\n audio_path: input.audioPath,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n try {\n const output = await execFileAsync(\n python.command,\n [...python.args, \"-c\", script, input.audioPath],\n {\n env,\n timeout: STT_TIMEOUT_MS,\n maxBuffer: STT_MAX_BUFFER_BYTES,\n windowsHide: true,\n },\n );\n stdout = output.stdout;\n stderr = output.stderr;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n await input.logger?.warn(\"voice_stt_process_failed\", {\n profile: profileName,\n error: message,\n });\n throw new LinkHttpError(\n 502,\n \"voice_stt_failed\",\n `语音转写失败:${message}`,\n );\n }\n\n const result = parseSttResult(stdout);\n if (!result.success) {\n const error =\n result.error || compactProcessOutput(stderr) || \"unknown error\";\n await input.logger?.warn(\"voice_stt_failed\", {\n profile: profileName,\n provider: result.provider ?? toolConfig.values.provider ?? null,\n error,\n });\n throw new LinkHttpError(502, \"voice_stt_failed\", `语音转写失败:${error}`);\n }\n\n const transcript = result.transcript?.trim() ?? \"\";\n if (!transcript) {\n throw new LinkHttpError(\n 422,\n \"voice_stt_empty_transcript\",\n \"语音转写没有识别到有效文本,请重新录制后再试。\",\n );\n }\n\n await input.logger?.debug(\"voice_stt_succeeded\", {\n profile: profileName,\n provider: result.provider ?? toolConfig.values.provider ?? null,\n transcript_length: transcript.length,\n });\n return { transcript, provider: result.provider };\n}\n\nasync function buildHermesSttEnv(\n profileName: string,\n): Promise<NodeJS.ProcessEnv> {\n const hermesEnv = await readHermesEnvFile(profileName);\n const hermesHome = resolveHermesProfileDir(profileName);\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...hermesEnv,\n HERMES_HOME: hermesHome,\n PYTHONIOENCODING: \"utf-8\",\n };\n const devSource = await findDevHermesAgentSource();\n if (devSource) {\n env.PYTHONPATH = [devSource, env.PYTHONPATH]\n .filter(Boolean)\n .join(path.delimiter);\n }\n return env;\n}\n\nfunction parseSttResult(stdout: string): {\n success: boolean;\n transcript?: string;\n provider?: string;\n error?: string;\n} {\n const line = stdout\n .split(/\\r?\\n/u)\n .reverse()\n .find((item) => item.startsWith(STT_RESULT_PREFIX));\n if (!line) {\n return {\n success: false,\n error: \"Hermes STT did not return a transcription result\",\n };\n }\n try {\n const parsed = JSON.parse(line.slice(STT_RESULT_PREFIX.length)) as unknown;\n if (typeof parsed !== \"object\" || parsed === null) {\n return { success: false, error: \"Invalid STT result\" };\n }\n const record = parsed as Record<string, unknown>;\n return {\n success: record.success === true,\n transcript:\n typeof record.transcript === \"string\" ? record.transcript : undefined,\n provider:\n typeof record.provider === \"string\" ? record.provider : undefined,\n error: typeof record.error === \"string\" ? record.error : undefined,\n };\n } catch {\n return { success: false, error: \"Invalid STT JSON result\" };\n }\n}\n\nasync function resolveHermesPythonCommand(): Promise<{\n command: string;\n args: string[];\n}> {\n const explicit = process.env.HERMES_PYTHON?.trim();\n if (explicit) {\n return { command: explicit, args: [] };\n }\n\n const hermesBin = await resolveExecutablePath(resolveHermesBin());\n if (hermesBin) {\n const shebang = await readShebang(hermesBin);\n const command = shebangToPythonCommand(shebang);\n if (command) {\n return command;\n }\n }\n\n return {\n command: process.platform === \"win32\" ? \"python\" : \"python3\",\n args: [],\n };\n}\n\nasync function resolveExecutablePath(command: string): Promise<string | null> {\n if (path.isAbsolute(command)) {\n return (await isExecutableFile(command)) ? command : null;\n }\n const pathEnv = process.env.PATH ?? \"\";\n const extensions =\n process.platform === \"win32\"\n ? (process.env.PATHEXT ?? \".EXE;.CMD;.BAT\").split(\";\")\n : [\"\"];\n for (const dir of pathEnv.split(path.delimiter)) {\n for (const extension of extensions) {\n const candidate = path.join(dir, `${command}${extension}`);\n if (await isExecutableFile(candidate)) {\n return candidate;\n }\n }\n }\n return null;\n}\n\nasync function isExecutableFile(filePath: string): Promise<boolean> {\n try {\n const info = await stat(filePath);\n if (!info.isFile()) {\n return false;\n }\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readShebang(filePath: string): Promise<string | null> {\n const raw = await readFile(filePath, \"utf8\").catch(() => \"\");\n const firstLine = raw.split(/\\r?\\n/u)[0]?.trim() ?? \"\";\n return firstLine.startsWith(\"#!\") ? firstLine.slice(2).trim() : null;\n}\n\nfunction shebangToPythonCommand(\n shebang: string | null,\n): { command: string; args: string[] } | null {\n if (!shebang || !shebang.toLowerCase().includes(\"python\")) {\n return null;\n }\n const parts = shebang.split(/\\s+/u).filter(Boolean);\n if (parts.length === 0) {\n return null;\n }\n if (parts[0]?.endsWith(\"/env\") && parts.length >= 2) {\n return { command: parts[1]!, args: parts.slice(2) };\n }\n return { command: parts[0]!, args: parts.slice(1) };\n}\n\nasync function findDevHermesAgentSource(): Promise<string | null> {\n const candidates = [\n path.resolve(process.cwd(), \"reference/hermes-agent\"),\n path.resolve(process.cwd(), \"../../reference/hermes-agent\"),\n ];\n for (const candidate of candidates) {\n if (await isDirectory(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n\nasync function isDirectory(candidate: string): Promise<boolean> {\n return stat(candidate)\n .then((info) => info.isDirectory())\n .catch(() => false);\n}\n\nfunction compactProcessOutput(value: string): string | null {\n const compact = value.trim().replace(/\\s+/gu, \" \").slice(0, 500);\n return compact || null;\n}\n","export interface ParsedSseEvent {\n eventName: string\n payloadType: string\n payload: Record<string, unknown>\n rawPayload: unknown\n}\n\nexport async function* parseSseResponse(\n response: Response,\n): AsyncGenerator<ParsedSseEvent> {\n if (!response.body) {\n return\n }\n const decoder = new TextDecoder()\n let buffer = ''\n for await (const chunk of response.body as unknown as AsyncIterable<Uint8Array>) {\n buffer += decoder.decode(chunk, { stream: true })\n let separatorIndex = buffer.indexOf('\\n\\n')\n while (separatorIndex >= 0) {\n const block = buffer.slice(0, separatorIndex)\n buffer = buffer.slice(separatorIndex + 2)\n const parsed = parseSseBlock(block)\n if (parsed) {\n yield parsed\n }\n separatorIndex = buffer.indexOf('\\n\\n')\n }\n }\n const trailing = parseSseBlock(buffer)\n if (trailing) {\n yield trailing\n }\n}\n\nfunction parseSseBlock(block: string): ParsedSseEvent | null {\n const lines = block.split('\\n')\n let eventName = ''\n const data: string[] = []\n for (const rawLine of lines) {\n const line = rawLine.trimEnd()\n if (line.startsWith('event:')) {\n eventName = line.slice(6).trim()\n } else if (line.startsWith('data:')) {\n data.push(line.slice(5).trimStart())\n }\n }\n if (!eventName && data.length === 0) {\n return null\n }\n const raw = data.join('\\n')\n const decoded = decodeJson(raw)\n if (decoded === null) {\n return null\n }\n const payload = toRecord(decoded)\n const payloadType =\n (readString(payload, 'type') ??\n readString(payload, 'event') ??\n readString(payload, 'object') ??\n eventName) ||\n 'message'\n return { eventName, payloadType, payload, rawPayload: decoded ?? raw }\n}\n\nfunction decodeJson(value: string): unknown {\n if (!value.trim()) {\n return {}\n }\n if (value.trim() === '[DONE]') {\n return null\n }\n try {\n return JSON.parse(value) as unknown\n } catch {\n return { type: 'message.delta', delta: value }\n }\n}\n\nfunction readString(\n body: Record<string, unknown>,\n key: string,\n): string | null {\n const value = body[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n","import type { ParsedSseEvent } from './hermes-sse.js'\nimport type { LinkRun } from './types.js'\n\nexport function normalizeHermesStreamEvent(\n event: ParsedSseEvent,\n): ParsedSseEvent | null {\n if (isTopLevelErrorEvent(event)) {\n return {\n ...event,\n payloadType: 'run.failed',\n payload: {\n ...event.payload,\n type: 'run.failed',\n error: {\n message:\n readErrorMessage(event.payload) ??\n readDelta(event.payload) ??\n 'Hermes run failed',\n },\n },\n }\n }\n\n if (event.eventName === 'hermes.tool.progress') {\n const toolName =\n readString(event.payload, 'tool') ??\n readString(event.payload, 'name') ??\n 'tool'\n const preview =\n readString(event.payload, 'label') ??\n readString(event.payload, 'preview') ??\n toolName\n return {\n ...event,\n payloadType: 'tool.started',\n payload: {\n ...event.payload,\n type: 'tool.started',\n tool: toolName,\n tool_name: toolName,\n preview,\n },\n }\n }\n\n if (event.payloadType !== 'chat.completion.chunk') {\n return event\n }\n\n const delta = readChatCompletionDelta(event.payload)\n if (delta) {\n return {\n ...event,\n payloadType: 'message.delta',\n payload: { type: 'message.delta', delta },\n }\n }\n\n const finishReason = readChatCompletionFinishReason(event.payload)\n const usage = readChatCompletionUsage(event.payload)\n if (finishReason || usage) {\n return {\n ...event,\n payloadType: 'run.completed',\n payload: {\n type: 'run.completed',\n ...(finishReason ? { finish_reason: finishReason } : {}),\n ...(usage ? { usage } : {}),\n },\n }\n }\n\n return null\n}\n\nexport function normalizeStreamingTextDelta(\n currentText: string,\n nextChunk: string,\n): string {\n if (!nextChunk) {\n return ''\n }\n if (!currentText) {\n return nextChunk\n }\n if (nextChunk === currentText) {\n return ''\n }\n if (nextChunk.startsWith(currentText)) {\n return nextChunk.slice(currentText.length)\n }\n return nextChunk\n}\n\nexport function readErrorMessage(\n payload: Record<string, unknown>,\n): string | null {\n if (typeof payload.error === 'string' && payload.error.trim()) {\n return payload.error.trim()\n }\n const error = toRecord(payload.error)\n return readString(error, 'message') ?? readString(payload, 'message')\n}\n\nexport function readDelta(payload: Record<string, unknown>): string | null {\n return (\n readText(payload, 'delta') ??\n readText(payload, 'text') ??\n readText(payload, 'content')\n )\n}\n\nexport function emptyHermesResponseMessage(): string {\n return 'Hermes 没有返回有效内容。请先看 Gateway / 模型配置是否正常,或查看下方失败详情。'\n}\n\nexport function buildHermesEmptyResponseDetail(input: {\n model?: string\n provider?: string\n healthIssue?: string | null\n upstreamError?: string | null\n eventError?: string | null\n}): string[] {\n const details: string[] = []\n if (input.model) {\n details.push(\n `当前模型:${input.model}${input.provider ? `(${input.provider})` : ''}`,\n )\n }\n if (input.healthIssue) {\n details.push(input.healthIssue)\n }\n if (input.upstreamError) {\n details.push(`上游返回:${input.upstreamError}`)\n }\n if (input.eventError) {\n details.push(`运行事件:${input.eventError}`)\n }\n return details\n}\n\nfunction isTopLevelErrorEvent(event: ParsedSseEvent): boolean {\n const type = event.payloadType\n if (type.startsWith('tool.')) {\n return false\n }\n return (\n type === 'error' ||\n type === 'run.error' ||\n event.eventName === 'error' ||\n Boolean(readErrorMessage(event.payload))\n )\n}\n\nfunction readChatCompletionDelta(\n payload: Record<string, unknown>,\n): string | null {\n const choice = readFirstChoice(payload)\n const delta = toRecord(choice.delta)\n return readText(delta, 'content')\n}\n\nfunction readChatCompletionFinishReason(\n payload: Record<string, unknown>,\n): string | null {\n const choice = readFirstChoice(payload)\n return (\n readString(choice, 'finish_reason') ?? readString(choice, 'finishReason')\n )\n}\n\nfunction readChatCompletionUsage(\n payload: Record<string, unknown>,\n): LinkRun['usage'] | undefined {\n const usage = toRecord(payload.usage)\n const input =\n readInteger(usage, 'prompt_tokens') ?? readInteger(usage, 'input_tokens')\n const output =\n readInteger(usage, 'completion_tokens') ??\n readInteger(usage, 'output_tokens')\n const total = readInteger(usage, 'total_tokens')\n const contextWindow =\n readInteger(usage, 'context_window') ?? readInteger(usage, 'context_max')\n const explicitContextTokens =\n readInteger(usage, 'context_tokens') ??\n readInteger(usage, 'context_used') ??\n readInteger(usage, 'current_context_tokens') ??\n readInteger(usage, 'last_prompt_tokens')\n if (input === undefined && output === undefined && total === undefined) {\n return undefined\n }\n const contextTokens =\n explicitContextTokens ??\n (contextWindow !== undefined &&\n input !== undefined &&\n input <= contextWindow\n ? input\n : undefined)\n return {\n input_tokens: input ?? 0,\n output_tokens: output ?? 0,\n total_tokens: total ?? (input ?? 0) + (output ?? 0),\n ...(contextTokens !== undefined ? { context_tokens: contextTokens } : {}),\n ...(contextWindow !== undefined ? { context_window: contextWindow } : {}),\n ...(contextTokens !== undefined && contextWindow\n ? {\n usage_percent: Math.min(\n 100,\n Math.round((contextTokens / contextWindow) * 100),\n ),\n }\n : {}),\n }\n}\n\nfunction readFirstChoice(\n payload: Record<string, unknown>,\n): Record<string, unknown> {\n const choices = payload.choices\n if (!Array.isArray(choices)) {\n return {}\n }\n return toRecord(choices[0])\n}\n\nfunction readInteger(\n payload: Record<string, unknown>,\n key: string,\n): number | undefined {\n const value = payload[key]\n if (typeof value === 'number' && Number.isFinite(value)) {\n return Math.max(0, Math.floor(value))\n }\n if (typeof value === 'string' && value.trim()) {\n const parsed = Number.parseInt(value.replaceAll(',', ''), 10)\n return Number.isFinite(parsed) ? Math.max(0, parsed) : undefined\n }\n return undefined\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction readText(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n","import { generateKeyPairSync, randomUUID, sign } from 'node:crypto'\nimport { mkdir, chmod } from 'node:fs/promises'\nimport { z } from 'zod'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\n\nconst linkIdentitySchema = z.object({\n install_id: z.string().min(1),\n link_id: z.string().min(1).nullable().optional(),\n public_key_pem: z.string().min(1),\n private_key_pem: z.string().min(1),\n created_at: z.string().min(1),\n updated_at: z.string().min(1),\n})\n\nexport type LinkIdentity = z.infer<typeof linkIdentitySchema>\n\nexport interface IdentityStatus {\n installId: string\n linkId: string | null\n hasPrivateKey: boolean\n publicKeyPem: string\n}\n\nexport async function loadIdentity(paths: RuntimePaths = resolveRuntimePaths()): Promise<LinkIdentity | null> {\n const value = await readJsonFile<unknown>(paths.identityFile)\n if (value === null) {\n return null\n }\n return linkIdentitySchema.parse(value)\n}\n\nexport async function ensureIdentity(paths: RuntimePaths = resolveRuntimePaths()): Promise<LinkIdentity> {\n const existing = await loadIdentity(paths)\n if (existing) {\n return existing\n }\n\n await mkdir(paths.homeDir, { recursive: true, mode: 0o700 })\n await chmod(paths.homeDir, 0o700).catch(() => undefined)\n\n const { publicKey, privateKey } = generateKeyPairSync('ed25519')\n const now = new Date().toISOString()\n const identity: LinkIdentity = {\n install_id: `install_${randomUUID().replaceAll('-', '')}`,\n link_id: null,\n public_key_pem: publicKey.export({ type: 'spki', format: 'pem' }).toString(),\n private_key_pem: privateKey.export({ type: 'pkcs8', format: 'pem' }).toString(),\n created_at: now,\n updated_at: now,\n }\n await writeJsonFile(paths.identityFile, identity)\n return identity\n}\n\nexport async function saveAssignedLinkId(\n linkId: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<LinkIdentity> {\n const identity = await ensureIdentity(paths)\n const next: LinkIdentity = {\n ...identity,\n link_id: linkId,\n updated_at: new Date().toISOString(),\n }\n await writeJsonFile(paths.identityFile, next)\n return next\n}\n\nexport function signRelayNonce(identity: LinkIdentity, nonce: string): string {\n const signature = sign(null, Buffer.from(nonce, 'utf8'), identity.private_key_pem)\n return signature.toString('base64url')\n}\n\nexport function getIdentityStatus(identity: LinkIdentity): IdentityStatus {\n return {\n installId: identity.install_id,\n linkId: identity.link_id ?? null,\n hasPrivateKey: identity.private_key_pem.trim().length > 0,\n publicKeyPem: identity.public_key_pem,\n }\n}\n\n","import { randomBytes, randomUUID, timingSafeEqual, createHash } from 'node:crypto'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\nimport { LinkHttpError } from '../core/errors.js'\n\nexport interface DeviceRecord {\n id: string\n label: string\n platform: string\n model?: string | null\n scope: 'admin'\n access_token_hash: string\n access_expires_at: string\n refresh_token_hash: string\n refresh_expires_at: string\n created_at: string\n updated_at: string\n last_seen_at?: string | null\n revoked_at: string | null\n app_hidden_at?: string | null\n app_instance_hash?: string | null\n}\n\ninterface CredentialStore {\n devices: DeviceRecord[]\n}\n\nexport interface CreatedDeviceSession {\n device: {\n id: string\n device_id: string\n label: string\n platform: string\n model: string | null\n scope: 'admin'\n }\n accessToken: {\n token: string\n expiresAt: string\n }\n refreshToken: {\n token: string\n expiresAt: string\n }\n}\n\nexport interface DeviceListItem {\n id: string\n device_id: string\n label: string\n platform: string\n model: string | null\n scope: 'admin'\n status: 'active' | 'revoked'\n paired_at: string\n created_at: string\n updated_at: string\n last_seen_at: string | null\n access_expires_at: string\n refresh_expires_at: string\n revoked_at: string | null\n app_hidden_at: string | null\n app_instance_bound: boolean\n}\n\nconst ACCESS_TOKEN_TTL_MS = 15 * 60 * 1000\nconst REFRESH_TOKEN_TTL_MS = 90 * 24 * 60 * 60 * 1000\nconst DEVICE_SEEN_WRITE_INTERVAL_MS = 60 * 60 * 1000\n\nexport async function createDeviceSession(\n input: { label: string; platform: string; model?: string | null; appInstanceId?: string | null },\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<CreatedDeviceSession> {\n const store = await readCredentialStore(paths)\n const now = new Date()\n const appInstanceHash = hashAppInstanceId(input.appInstanceId)\n if (appInstanceHash) {\n const existing = store.devices.find((item) => item.app_instance_hash === appInstanceHash)\n if (existing) {\n updateDeviceDescriptor(existing, input)\n existing.revoked_at = null\n existing.app_hidden_at = null\n return await rotateDeviceSession(store, existing, now, paths)\n }\n }\n\n const device: DeviceRecord = {\n id: `dev_${randomUUID().replaceAll('-', '')}`,\n label: normalizeDeviceLabel(input.label),\n platform: normalizeDevicePlatform(input.platform),\n model: normalizeDeviceModel(input.model),\n scope: 'admin',\n access_token_hash: '',\n access_expires_at: '',\n refresh_token_hash: '',\n refresh_expires_at: '',\n created_at: now.toISOString(),\n updated_at: now.toISOString(),\n last_seen_at: now.toISOString(),\n revoked_at: null,\n app_hidden_at: null,\n app_instance_hash: appInstanceHash,\n }\n store.devices.push(device)\n return await rotateDeviceSession(store, device, now, paths)\n}\n\nexport async function hasActiveDevices(paths: RuntimePaths = resolveRuntimePaths()): Promise<boolean> {\n const store = await readCredentialStore(paths)\n return store.devices.some((device) => !device.revoked_at)\n}\n\nexport async function readDeviceSummary(\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<{ total: number; active: number; revoked: number }> {\n const store = await readCredentialStore(paths)\n const visibleDevices = store.devices.filter(isDeviceVisibleInApp)\n const revoked = visibleDevices.filter((device) => device.revoked_at).length\n return {\n total: visibleDevices.length,\n active: visibleDevices.length - revoked,\n revoked,\n }\n}\n\nexport async function listDevices(\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<DeviceListItem[]> {\n const store = await readCredentialStore(paths)\n return store.devices\n .filter(isDeviceVisibleInApp)\n .map(formatDeviceListItem)\n .sort((left, right) => {\n if (left.status !== right.status) {\n return left.status === 'active' ? -1 : 1\n }\n return Date.parse(right.created_at) - Date.parse(left.created_at)\n })\n}\n\nexport async function hideRevokedDeviceFromAppList(\n deviceId: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<DeviceListItem> {\n const store = await readCredentialStore(paths)\n const device = store.devices.find((item) => item.id === deviceId)\n if (!device) {\n throw new LinkHttpError(404, 'device_not_found', 'Device was not found')\n }\n if (!device.revoked_at) {\n throw new LinkHttpError(\n 409,\n 'device_still_active',\n 'Device must be revoked before it can be deleted from the app list',\n )\n }\n if (!device.app_hidden_at) {\n device.app_hidden_at = new Date().toISOString()\n device.updated_at = device.app_hidden_at\n await writeCredentialStore(paths, store)\n }\n return formatDeviceListItem(device)\n}\n\nexport async function authenticateDeviceAccessToken(\n token: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<DeviceRecord | null> {\n const tokenHash = sha256(token)\n const store = await readCredentialStore(paths)\n const device = store.devices.find((item) => safeEqual(item.access_token_hash, tokenHash))\n if (!device || device.revoked_at || Date.parse(device.access_expires_at) <= Date.now()) {\n return null\n }\n return device\n}\n\nexport async function refreshDeviceSession(\n refreshToken: string,\n options: {\n appInstanceId?: string | null\n label?: string | null\n platform?: string | null\n model?: string | null\n } = {},\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<CreatedDeviceSession> {\n const tokenHash = sha256(refreshToken)\n const store = await readCredentialStore(paths)\n const device = store.devices.find((item) => safeEqual(item.refresh_token_hash, tokenHash))\n if (!device || device.revoked_at || Date.parse(device.refresh_expires_at) <= Date.now()) {\n throw new LinkHttpError(401, 'refresh_token_invalid', 'Refresh token is invalid or expired')\n }\n\n const now = new Date()\n maybeBindAppInstance(store, device, options.appInstanceId)\n updateDeviceDescriptor(device, options)\n return await rotateDeviceSession(store, device, now, paths)\n}\n\nexport async function recordDeviceSeen(\n deviceId: string,\n options: { appInstanceId?: string | null; model?: string | null } = {},\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<DeviceRecord | null> {\n const store = await readCredentialStore(paths)\n const device = store.devices.find((item) => item.id === deviceId)\n if (!device || device.revoked_at) {\n return device ?? null\n }\n const now = new Date()\n const bound = maybeBindAppInstance(store, device, options.appInstanceId)\n const descriptorUpdated = updateDeviceDescriptor(device, { model: options.model })\n const shouldTouch =\n !device.last_seen_at ||\n Number.isNaN(Date.parse(device.last_seen_at)) ||\n now.getTime() - Date.parse(device.last_seen_at) >= DEVICE_SEEN_WRITE_INTERVAL_MS\n if (bound || descriptorUpdated || shouldTouch) {\n device.last_seen_at = now.toISOString()\n device.updated_at = now.toISOString()\n await writeCredentialStore(paths, store)\n }\n return device\n}\n\nexport async function revokeDeviceRefreshToken(\n refreshToken: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<void> {\n const tokenHash = sha256(refreshToken)\n const store = await readCredentialStore(paths)\n const device = store.devices.find((item) => safeEqual(item.refresh_token_hash, tokenHash))\n if (!device || device.revoked_at) {\n return\n }\n device.revoked_at = new Date().toISOString()\n device.updated_at = device.revoked_at\n await writeCredentialStore(paths, store)\n}\n\nexport async function revokeDeviceById(\n deviceId: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<DeviceListItem> {\n const store = await readCredentialStore(paths)\n const device = store.devices.find((item) => item.id === deviceId)\n if (!device) {\n throw new LinkHttpError(404, 'device_not_found', 'Device was not found')\n }\n if (!device.revoked_at) {\n device.revoked_at = new Date().toISOString()\n device.updated_at = device.revoked_at\n await writeCredentialStore(paths, store)\n }\n return formatDeviceListItem(device)\n}\n\nexport async function renameDeviceById(\n deviceId: string,\n label: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<DeviceListItem> {\n const normalizedLabel = label.trim()\n if (!normalizedLabel || normalizedLabel.length > 128) {\n throw new LinkHttpError(400, 'device_label_invalid', 'Device label is invalid')\n }\n const store = await readCredentialStore(paths)\n const device = store.devices.find((item) => item.id === deviceId)\n if (!device) {\n throw new LinkHttpError(404, 'device_not_found', 'Device was not found')\n }\n if (device.revoked_at) {\n throw new LinkHttpError(409, 'device_revoked', 'Device has already been revoked')\n }\n device.label = normalizedLabel\n device.updated_at = new Date().toISOString()\n await writeCredentialStore(paths, store)\n return formatDeviceListItem(device)\n}\n\nasync function readCredentialStore(paths: RuntimePaths): Promise<CredentialStore> {\n const existing = await readJsonFile<Partial<CredentialStore>>(paths.credentialsFile)\n return {\n devices: Array.isArray(existing?.devices) ? existing.devices.filter(isDeviceRecord) : [],\n }\n}\n\nasync function writeCredentialStore(paths: RuntimePaths, store: CredentialStore): Promise<void> {\n await writeJsonFile(paths.credentialsFile, store)\n}\n\nfunction formatDeviceSession(device: DeviceRecord, accessToken: string, refreshToken: string): CreatedDeviceSession {\n return {\n device: {\n id: device.id,\n device_id: device.id,\n label: device.label,\n platform: device.platform,\n model: device.model ?? null,\n scope: device.scope,\n },\n accessToken: {\n token: accessToken,\n expiresAt: device.access_expires_at,\n },\n refreshToken: {\n token: refreshToken,\n expiresAt: device.refresh_expires_at,\n },\n }\n}\n\nfunction formatDeviceListItem(device: DeviceRecord): DeviceListItem {\n return {\n id: device.id,\n device_id: device.id,\n label: device.label,\n platform: device.platform,\n model: device.model ?? null,\n scope: device.scope,\n status: device.revoked_at ? 'revoked' : 'active',\n paired_at: device.created_at,\n created_at: device.created_at,\n updated_at: device.updated_at,\n access_expires_at: device.access_expires_at,\n refresh_expires_at: device.refresh_expires_at,\n last_seen_at: device.last_seen_at ?? null,\n revoked_at: device.revoked_at,\n app_hidden_at: device.app_hidden_at ?? null,\n app_instance_bound: Boolean(device.app_instance_hash),\n }\n}\n\nasync function rotateDeviceSession(\n store: CredentialStore,\n device: DeviceRecord,\n now: Date,\n paths: RuntimePaths,\n): Promise<CreatedDeviceSession> {\n const accessToken = randomToken('hpat_')\n const refreshToken = randomToken('hprt_')\n device.access_token_hash = sha256(accessToken)\n device.access_expires_at = new Date(now.getTime() + ACCESS_TOKEN_TTL_MS).toISOString()\n device.refresh_token_hash = sha256(refreshToken)\n device.refresh_expires_at = new Date(now.getTime() + REFRESH_TOKEN_TTL_MS).toISOString()\n device.last_seen_at = now.toISOString()\n device.updated_at = now.toISOString()\n await writeCredentialStore(paths, store)\n return formatDeviceSession(device, accessToken, refreshToken)\n}\n\nfunction maybeBindAppInstance(\n store: CredentialStore,\n device: DeviceRecord,\n appInstanceId: string | null | undefined,\n): boolean {\n const appInstanceHash = hashAppInstanceId(appInstanceId)\n if (!appInstanceHash || device.app_instance_hash === appInstanceHash) {\n return false\n }\n if (device.app_instance_hash) {\n return false\n }\n const existing = store.devices.find(\n (item) => item.id !== device.id && item.app_instance_hash === appInstanceHash,\n )\n if (existing) {\n return false\n }\n device.app_instance_hash = appInstanceHash\n return true\n}\n\nfunction updateDeviceDescriptor(\n device: DeviceRecord,\n input: { label?: string | null; platform?: string | null; model?: string | null },\n): boolean {\n let changed = false\n if (input.label !== undefined && input.label !== null) {\n const label = normalizeDeviceLabel(input.label)\n if (device.label !== label) {\n device.label = label\n changed = true\n }\n }\n if (input.platform !== undefined && input.platform !== null) {\n const platform = normalizeDevicePlatform(input.platform)\n if (device.platform !== platform) {\n device.platform = platform\n changed = true\n }\n }\n if (input.model !== undefined && input.model !== null) {\n const model = normalizeDeviceModel(input.model)\n if ((device.model ?? null) !== model) {\n device.model = model\n changed = true\n }\n }\n return changed\n}\n\nfunction hashAppInstanceId(value: string | null | undefined): string | null {\n const normalized = normalizeAppInstanceId(value)\n return normalized ? sha256(`hermespilot-app-instance:${normalized}`) : null\n}\n\nfunction normalizeAppInstanceId(value: string | null | undefined): string | null {\n if (typeof value !== 'string') {\n return null\n }\n const trimmed = value.trim()\n return /^appi_[A-Za-z0-9_-]{16,96}$/u.test(trimmed) ? trimmed : null\n}\n\nfunction normalizeDeviceLabel(value: string): string {\n const trimmed = value.trim()\n return trimmed ? trimmed.slice(0, 128) : 'HermesPilot App'\n}\n\nfunction normalizeDevicePlatform(value: string): string {\n const trimmed = value.trim().toLowerCase()\n return trimmed ? trimmed.slice(0, 48) : 'unknown'\n}\n\nfunction normalizeDeviceModel(value: string | null | undefined): string | null {\n const trimmed = value?.trim()\n return trimmed ? trimmed.slice(0, 128) : null\n}\n\nfunction isDeviceVisibleInApp(device: DeviceRecord): boolean {\n return !device.app_hidden_at\n}\n\nfunction isDeviceRecord(value: unknown): value is DeviceRecord {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as DeviceRecord).id === 'string' &&\n typeof (value as DeviceRecord).access_token_hash === 'string' &&\n typeof (value as DeviceRecord).refresh_token_hash === 'string'\n )\n}\n\nfunction randomToken(prefix: string): string {\n return `${prefix}${randomBytes(24).toString('base64url')}`\n}\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex')\n}\n\nfunction safeEqual(left: string, right: string): boolean {\n const leftBytes = Buffer.from(left)\n const rightBytes = Buffer.from(right)\n return leftBytes.length === rightBytes.length && timingSafeEqual(leftBytes, rightBytes)\n}\n","import { createPublicKey, verify, type JsonWebKey as NodeJsonWebKey } from 'node:crypto'\nimport { LinkConfig } from '../config/config.js'\nimport { LinkHttpError } from '../core/errors.js'\n\ninterface JwksResponse {\n keys?: ServerJwk[]\n}\n\ninterface JwtHeader {\n alg?: string\n kid?: string\n typ?: string\n}\n\nexport interface AppConnectClaims {\n token_type: 'hermes_app_connect'\n iss: string\n aud: string\n sub: string\n link_id: string\n scope?: string[] | string\n app_instance_id?: string\n exp: number\n iat?: number\n jti?: string\n}\n\ntype ServerJwk = NodeJsonWebKey & { kid?: string }\n\nlet cachedJwks: { expiresAt: number; keys: ServerJwk[] } | null = null\n\nexport async function verifyAppConnectToken(\n token: string,\n options: {\n config: LinkConfig\n linkId: string\n fetchImpl?: typeof fetch\n },\n): Promise<AppConnectClaims> {\n const segments = token.split('.')\n if (segments.length !== 3) {\n throw new LinkHttpError(401, 'app_connect_token_invalid', 'App connect token is malformed')\n }\n const [encodedHeader, encodedPayload, encodedSignature] = segments\n const header = decodeJson<JwtHeader>(encodedHeader)\n const payload = decodeJson<AppConnectClaims>(encodedPayload)\n if (header.alg !== 'ES256' || header.typ !== 'JWT') {\n throw new LinkHttpError(401, 'app_connect_token_invalid', 'App connect token algorithm is unsupported')\n }\n if (\n payload.token_type !== 'hermes_app_connect' ||\n payload.iss !== options.config.appConnectTokenIssuer ||\n payload.aud !== options.config.appConnectTokenAudience ||\n payload.link_id !== options.linkId ||\n !Number.isFinite(payload.exp) ||\n payload.exp <= Math.floor(Date.now() / 1000)\n ) {\n throw new LinkHttpError(401, 'app_connect_token_invalid', 'App connect token claims are invalid')\n }\n\n const jwks = await getJwks(options.config, options.fetchImpl ?? fetch)\n const key = jwks.find((item) => item.kid === header.kid) ?? jwks[0]\n if (!key) {\n throw new LinkHttpError(503, 'app_connect_jwks_unavailable', 'App connect token key is unavailable')\n }\n const publicKey = createPublicKey({ key, format: 'jwk' })\n const ok = verify(\n 'sha256',\n Buffer.from(`${encodedHeader}.${encodedPayload}`),\n { key: publicKey, dsaEncoding: 'ieee-p1363' },\n Buffer.from(base64UrlToBase64(encodedSignature), 'base64'),\n )\n if (!ok) {\n throw new LinkHttpError(401, 'app_connect_token_invalid', 'App connect token signature is invalid')\n }\n return payload\n}\n\nasync function getJwks(config: LinkConfig, fetcher: typeof fetch): Promise<ServerJwk[]> {\n if (cachedJwks && cachedJwks.expiresAt > Date.now()) {\n return cachedJwks.keys\n }\n const response = await fetcher(`${config.serverBaseUrl.replace(/\\/+$/u, '')}/api/v1/app-connect/jwks.json`, {\n headers: { accept: 'application/json' },\n })\n if (!response.ok) {\n throw new LinkHttpError(503, 'app_connect_jwks_unavailable', 'Unable to load app connect JWKS')\n }\n const payload = (await response.json()) as JwksResponse\n const keys = Array.isArray(payload.keys) ? payload.keys : []\n cachedJwks = {\n keys,\n expiresAt: Date.now() + 5 * 60 * 1000,\n }\n return keys\n}\n\nfunction decodeJson<T>(value: string): T {\n return JSON.parse(Buffer.from(base64UrlToBase64(value), 'base64').toString('utf8')) as T\n}\n\nfunction base64UrlToBase64(value: string): string {\n const normalized = value.replace(/-/g, '+').replace(/_/g, '/')\n return normalized + '='.repeat((4 - (normalized.length % 4)) % 4)\n}\n","import type Koa from 'koa'\nimport { loadConfig } from '../config/config.js'\nimport { loadIdentity } from '../identity/identity.js'\nimport {\n authenticateDeviceAccessToken,\n type DeviceRecord,\n} from '../security/devices.js'\nimport { verifyAppConnectToken } from '../security/app-connect-token.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { LinkHttpError } from './errors.js'\n\nexport interface AuthContext {\n kind: 'device' | 'app-connect'\n device?: DeviceRecord\n accountId?: string\n scopes?: string[]\n appInstanceId?: string\n}\n\nexport async function authenticateRequest(\n ctx: Koa.ParameterizedContext,\n paths: RuntimePaths,\n): Promise<AuthContext> {\n const token = readBearerToken(ctx.get('authorization'))\n if (!token) {\n throw new LinkHttpError(\n 401,\n 'auth_required',\n 'Authorization bearer token is required',\n )\n }\n const device = await authenticateDeviceAccessToken(token, paths)\n if (device) {\n return { kind: 'device', device }\n }\n if (token.startsWith('hpat_')) {\n throw new LinkHttpError(\n 401,\n 'device_access_token_invalid',\n 'Device access token is invalid or expired',\n )\n }\n const [identity, config] = await Promise.all([\n loadRequiredIdentity(paths),\n loadConfig(paths),\n ])\n const claims = await verifyAppConnectToken(token, {\n config,\n linkId: identity.link_id,\n })\n return {\n kind: 'app-connect',\n accountId: claims.sub,\n scopes: normalizeScopes(claims.scope),\n appInstanceId: normalizeAppInstanceId(claims.app_instance_id),\n }\n}\n\nexport async function loadRequiredIdentity(paths: RuntimePaths) {\n const identity = await loadIdentity(paths)\n if (!identity?.link_id) {\n throw new LinkHttpError(409, 'link_not_paired', 'Hermes Link is not paired')\n }\n return identity as NonNullable<typeof identity> & { link_id: string }\n}\n\nfunction readBearerToken(value: string): string | null {\n const trimmed = value.trim()\n if (!trimmed.toLowerCase().startsWith('bearer ')) {\n return null\n }\n const token = trimmed.slice(7).trim()\n return token || null\n}\n\nfunction normalizeScopes(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value\n .filter((item): item is string => typeof item === 'string')\n .map((item) => item.trim())\n .filter(Boolean)\n }\n if (typeof value === 'string') {\n return value\n .split(/\\s+/u)\n .map((item) => item.trim())\n .filter(Boolean)\n }\n return []\n}\n\nfunction normalizeAppInstanceId(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined\n }\n const trimmed = value.trim()\n return /^appi_[A-Za-z0-9_-]{16,96}$/u.test(trimmed) ? trimmed : undefined\n}\n","import type Koa from \"koa\";\nimport { LinkHttpError } from \"./errors.js\";\n\nexport const MAX_JSON_BODY_BYTES = 1024 * 1024;\nexport const MAX_BLOB_UPLOAD_BYTES = 50 * 1024 * 1024;\n\nexport async function readJsonBody(\n request: NodeJS.ReadableStream,\n): Promise<Record<string, unknown>> {\n const raw = await readRawBody(request, MAX_JSON_BODY_BYTES);\n if (raw.byteLength === 0) {\n return {};\n }\n try {\n return JSON.parse(Buffer.from(raw).toString(\"utf8\")) as Record<\n string,\n unknown\n >;\n } catch {\n throw new LinkHttpError(\n 400,\n \"invalid_json\",\n \"Request body must be valid JSON\",\n );\n }\n}\n\nexport async function readRawBody(\n request: NodeJS.ReadableStream,\n maxBytes: number,\n): Promise<Buffer> {\n const chunks: Buffer[] = [];\n let totalBytes = 0;\n for await (const chunk of request) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n totalBytes += buffer.byteLength;\n if (totalBytes > maxBytes) {\n throw new LinkHttpError(\n 413,\n \"request_body_too_large\",\n \"Request body is too large\",\n );\n }\n chunks.push(buffer);\n }\n return Buffer.concat(chunks);\n}\n\nexport function readString(\n body: Record<string, unknown>,\n key: string,\n): string | null {\n const value = body[key];\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nexport function readOptionalProfileName(\n body: Record<string, unknown>,\n): string | undefined {\n return (\n readString(body, \"profile\") ??\n readString(body, \"profile_name\") ??\n readString(body, \"profileName\") ??\n undefined\n );\n}\n\nexport function readStringArray(\n body: Record<string, unknown>,\n ...keys: string[]\n): string[] | null {\n for (const key of keys) {\n if (!Object.prototype.hasOwnProperty.call(body, key)) {\n continue;\n }\n const value = body[key];\n if (!Array.isArray(value)) {\n throw new LinkHttpError(\n 400,\n \"conversation_ids_invalid\",\n `${key} must be an array of conversation ids`,\n );\n }\n return value.map((item) => {\n if (typeof item !== \"string\" || !item.trim()) {\n throw new LinkHttpError(\n 400,\n \"conversation_ids_invalid\",\n `${key} must contain non-empty strings`,\n );\n }\n return item.trim();\n });\n }\n return null;\n}\n\nexport function readPositiveInteger(value: unknown): number | undefined {\n if (typeof value === \"number\" && Number.isFinite(value) && value > 0) {\n return Math.floor(value);\n }\n if (typeof value === \"string\" && value.trim()) {\n const parsed = Number.parseInt(value.replaceAll(\",\", \"\"), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n }\n return undefined;\n}\n\nexport function readBoolean(value: unknown): boolean | undefined {\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"string\") {\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) {\n return true;\n }\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) {\n return false;\n }\n }\n return undefined;\n}\n\nexport function readLimit(value: unknown): number | undefined {\n const raw = Array.isArray(value) ? value[0] : value;\n if (typeof raw !== \"string\") {\n return undefined;\n }\n const parsed = Number.parseInt(raw, 10);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nexport function readLogSource(value: unknown): \"link\" | \"gateway\" {\n const raw = Array.isArray(value) ? value[0] : value;\n if (typeof raw !== \"string\") {\n return \"link\";\n }\n return raw.trim().toLowerCase() === \"gateway\" ? \"gateway\" : \"link\";\n}\n\nexport function readQueryString(value: unknown): string | undefined {\n const raw = Array.isArray(value) ? value[0] : value;\n if (typeof raw !== \"string\") {\n return undefined;\n }\n const trimmed = raw.trim();\n return trimmed ? trimmed : undefined;\n}\n\nexport function readInteger(value: unknown): number | undefined {\n const raw = Array.isArray(value) ? value[0] : value;\n if (typeof raw !== \"string\") {\n return undefined;\n }\n const parsed = Number.parseInt(raw, 10);\n return Number.isFinite(parsed) ? Math.max(0, parsed) : undefined;\n}\n\nexport function readHeader(\n ctx: Koa.ParameterizedContext,\n name: string,\n): string | null {\n const value = ctx.get(name).trim();\n return value ? value : null;\n}\n\nexport function readConversationHistory(\n value: unknown,\n): Array<{ role: string; content: string }> {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((item) => {\n if (typeof item !== \"object\" || item === null) {\n return null;\n }\n const role = (item as { role?: unknown }).role;\n const content = (item as { content?: unknown }).content;\n if (typeof role !== \"string\" || typeof content !== \"string\") {\n return null;\n }\n return { role, content };\n })\n .filter((item): item is { role: string; content: string } => Boolean(item));\n}\n\nexport function readMessageAttachments(value: unknown): Array<{\n blob_id: string;\n kind?: string;\n type?: string;\n is_voice_note?: boolean;\n duration_ms?: number;\n waveform?: number[];\n}> {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((item) => {\n if (typeof item === \"string\" && item.trim()) {\n return { blob_id: item.trim() };\n }\n if (typeof item !== \"object\" || item === null) {\n return null;\n }\n const record = item as Record<string, unknown>;\n const blobId =\n typeof record.blob_id === \"string\"\n ? record.blob_id.trim()\n : typeof record.blobId === \"string\"\n ? record.blobId.trim()\n : \"\";\n if (!blobId) {\n return null;\n }\n const kind = readAttachmentString(record.kind);\n const type = readAttachmentString(record.type);\n const isVoiceNote =\n readBoolean(record.is_voice_note) ?? readBoolean(record.isVoiceNote);\n const durationMs =\n readPositiveInteger(record.duration_ms) ??\n readPositiveInteger(record.durationMs);\n const waveform = readAttachmentWaveform(\n record.waveform ?? record.waveform_samples ?? record.waveformSamples,\n );\n return {\n blob_id: blobId,\n ...(kind ? { kind } : {}),\n ...(type ? { type } : {}),\n ...(isVoiceNote !== undefined ? { is_voice_note: isVoiceNote } : {}),\n ...(durationMs !== undefined ? { duration_ms: durationMs } : {}),\n ...(waveform.length > 0 ? { waveform } : {}),\n };\n })\n .filter(\n (\n item,\n ): item is {\n blob_id: string;\n kind?: string;\n type?: string;\n is_voice_note?: boolean;\n duration_ms?: number;\n waveform?: number[];\n } => Boolean(item),\n );\n}\n\nfunction readAttachmentString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim()\n ? value.trim().toLowerCase()\n : undefined;\n}\n\nfunction readAttachmentWaveform(value: unknown): number[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value\n .map((item) => {\n const parsed =\n typeof item === \"number\"\n ? item\n : typeof item === \"string\"\n ? Number.parseFloat(item)\n : Number.NaN;\n return Number.isFinite(parsed)\n ? Math.max(0, Math.min(1, parsed))\n : undefined;\n })\n .filter((item): item is number => item !== undefined)\n .slice(0, 96);\n}\n\nexport function routeObjects(urls: string[]) {\n return urls.map((url) => ({\n kind: routeKindForUrl(url),\n url,\n observed_at: new Date().toISOString(),\n }));\n}\n\nfunction routeKindForUrl(url: string): \"lan\" | \"public\" | \"relay\" {\n if (url.includes(\"/api/v1/relay/links/\")) {\n return \"relay\";\n }\n try {\n const parsed = new URL(url);\n return isLanHost(parsed.hostname) ? \"lan\" : \"public\";\n } catch {\n return \"public\";\n }\n}\n\nfunction isLanHost(hostname: string): boolean {\n const host = hostname.toLowerCase().replace(/^\\[/u, \"\").replace(/\\]$/u, \"\");\n if (host === \"localhost\" || host.endsWith(\".local\")) {\n return true;\n }\n const ipv4 = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/u.exec(host);\n if (ipv4) {\n const parts = ipv4.slice(1).map((part) => Number.parseInt(part, 10));\n if (parts.length !== 4 || parts.some((part) => part < 0 || part > 255)) {\n return false;\n }\n const first = parts[0] ?? -1;\n const second = parts[1] ?? -1;\n return (\n first === 10 ||\n (first === 172 && second >= 16 && second <= 31) ||\n (first === 192 && second === 168) ||\n (first === 169 && second === 254) ||\n first === 127\n );\n }\n return (\n host.startsWith(\"fe80:\") ||\n host.startsWith(\"fc\") ||\n host.startsWith(\"fd\") ||\n host === \"::1\"\n );\n}\n","import type { ServerResponse } from 'node:http'\nimport type { ConversationEvent } from '../conversations/types.js'\n\nexport function writeSseEvent(\n response: ServerResponse,\n event: ConversationEvent,\n): void {\n response.write(`event: ${event.type}\\n`)\n response.write(`data: ${JSON.stringify(event)}\\n\\n`)\n}\n","import type Router from '@koa/router'\nimport { LinkHttpError } from '../errors.js'\nimport { authenticateRequest } from '../auth.js'\nimport {\n MAX_BLOB_UPLOAD_BYTES,\n readHeader,\n readInteger,\n readJsonBody,\n readLimit,\n readMessageAttachments,\n readOptionalProfileName,\n readQueryString,\n readRawBody,\n readString,\n readStringArray,\n} from '../request.js'\nimport { writeSseEvent } from '../sse.js'\nimport type { ConversationService } from '../../conversations/conversation-service.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\n\nexport function registerConversationRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n conversations: ConversationService\n },\n): void {\n const { paths, conversations } = options\n\n router.get('/api/v1/conversations', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = {\n ok: true,\n conversations: await conversations.listConversations(),\n }\n })\n\n router.post('/api/v1/conversations', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n ctx.status = 201\n ctx.body = {\n ok: true,\n conversation: await conversations.createConversation({\n title: readString(body, 'title') ?? undefined,\n profileName: readOptionalProfileName(body),\n }),\n }\n })\n\n router.get('/api/v1/conversations/:conversationId/messages', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n const result = await conversations.getMessages(ctx.params.conversationId, {\n limit: readLimit(ctx.query.limit),\n beforeMessageId:\n readQueryString(ctx.query.before_message_id) ??\n readQueryString(ctx.query.before),\n })\n ctx.body = {\n ok: true,\n conversation_id: ctx.params.conversationId,\n ...result,\n }\n })\n\n router.get('/api/v1/conversations/events', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.respond = false\n const response = ctx.res\n response.statusCode = 200\n response.setHeader('content-type', 'text/event-stream; charset=utf-8')\n response.setHeader('cache-control', 'no-store')\n response.setHeader('connection', 'keep-alive')\n const unsubscribe = conversations.subscribeAll((event) => {\n writeSseEvent(response, event)\n })\n const cleanup = () => {\n unsubscribe()\n response.end()\n }\n ctx.req.on('close', cleanup)\n })\n\n router.get('/api/v1/conversations/:conversationId/events', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const after = readInteger(ctx.query.after) ?? 0\n const history = await conversations.listEvents(\n ctx.params.conversationId,\n after,\n )\n ctx.respond = false\n const response = ctx.res\n response.statusCode = 200\n response.setHeader('content-type', 'text/event-stream; charset=utf-8')\n response.setHeader('cache-control', 'no-store')\n response.setHeader('connection', 'keep-alive')\n for (const event of history) {\n writeSseEvent(response, event)\n }\n const unsubscribe = conversations.subscribe(\n ctx.params.conversationId,\n (event) => {\n writeSseEvent(response, event)\n },\n )\n const cleanup = () => {\n unsubscribe()\n response.end()\n }\n ctx.req.on('close', cleanup)\n })\n\n router.post('/api/v1/conversations/:conversationId/messages', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const content =\n readString(body, 'content') ??\n readString(body, 'text') ??\n readString(body, 'input') ??\n ''\n const attachments = readMessageAttachments(body.attachments ?? body.blobs)\n if (!content && attachments.length === 0) {\n throw new LinkHttpError(\n 400,\n 'message_content_required',\n 'message content is required',\n )\n }\n ctx.status = 202\n ctx.body = {\n ok: true,\n ...(await conversations.sendMessage({\n conversationId: ctx.params.conversationId,\n content,\n attachments,\n clientMessageId:\n readString(body, 'client_message_id') ??\n readString(body, 'clientMessageId') ??\n undefined,\n idempotencyKey: readHeader(ctx, 'idempotency-key') ?? undefined,\n profileName: readOptionalProfileName(body),\n })),\n }\n })\n\n router.patch('/api/v1/conversations/:conversationId/model', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const modelId =\n readString(body, 'model_id') ??\n readString(body, 'modelId') ??\n readString(body, 'model')\n if (!modelId) {\n throw new LinkHttpError(400, 'model_id_required', 'model_id is required')\n }\n ctx.body = {\n ok: true,\n ...(await conversations.setConversationModel(\n ctx.params.conversationId,\n modelId,\n )),\n }\n })\n\n router.patch('/api/v1/conversations/:conversationId/profile', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const profileName = readOptionalProfileName(body)\n if (!profileName) {\n throw new LinkHttpError(400, 'profile_required', 'profile is required')\n }\n ctx.body = {\n ok: true,\n ...(await conversations.setConversationProfile(\n ctx.params.conversationId,\n profileName,\n )),\n }\n })\n\n router.patch('/api/v1/conversations/:conversationId/title', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const title =\n readString(body, 'title') ??\n readString(body, 'name') ??\n readString(body, 'display_name')\n if (!title) {\n throw new LinkHttpError(400, 'title_required', 'title is required')\n }\n ctx.body = {\n ok: true,\n ...(await conversations.renameConversation(\n ctx.params.conversationId,\n title,\n )),\n }\n })\n\n router.post('/api/v1/conversations/:conversationId/ack', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.body = { ok: true }\n })\n\n router.delete('/api/v1/conversations', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const conversationIds = readStringArray(\n body,\n 'conversation_ids',\n 'conversationIds',\n )\n if (conversationIds == null || conversationIds.length === 0) {\n throw new LinkHttpError(\n 400,\n 'conversation_ids_required',\n 'conversation_ids must be a non-empty array',\n )\n }\n const deleted = await conversations.deleteConversations(conversationIds)\n const ok = deleted.failed_count === 0\n ctx.status = ok ? 200 : 409\n ctx.body = {\n ok,\n ...(ok\n ? {}\n : {\n error: {\n code: 'conversation_bulk_delete_partial_failure',\n message: 'Some conversations could not be deleted',\n },\n }),\n ...deleted,\n blob_gc_completed: true,\n }\n })\n\n router.post(\n '/api/v1/conversations/:conversationId/runs/:runId/cancel',\n async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.body = {\n ok: true,\n ...(await conversations.cancelRun(\n ctx.params.conversationId,\n ctx.params.runId,\n )),\n }\n },\n )\n\n router.delete('/api/v1/conversations/:conversationId', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.body = {\n ok: true,\n ...(await conversations.deleteConversation(ctx.params.conversationId)),\n blob_gc_completed: true,\n }\n })\n\n router.post('/api/v1/conversations/:conversationId/blobs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const bytes = await readRawBody(ctx.req, MAX_BLOB_UPLOAD_BYTES)\n if (bytes.byteLength === 0) {\n throw new LinkHttpError(400, 'blob_empty', 'Blob body is empty')\n }\n const blob = await conversations.writeBlob(ctx.params.conversationId, {\n bytes,\n filename: readHeader(ctx, 'x-filename') ?? undefined,\n mime: ctx.get('content-type') || undefined,\n })\n ctx.status = 201\n ctx.body = { ok: true, blob }\n })\n\n router.get(\n '/api/v1/conversations/:conversationId/blobs/:blobId',\n async (ctx) => {\n await authenticateRequest(ctx, paths)\n const blob = await conversations.readBlob(\n ctx.params.conversationId,\n ctx.params.blobId,\n )\n ctx.set('content-type', blob.mime)\n ctx.set('content-length', String(blob.size))\n ctx.set('cache-control', 'private, max-age=86400')\n ctx.set(\n 'content-disposition',\n `inline; filename=\"${blob.filename.replaceAll('\"', '')}\"`,\n )\n ctx.body = blob.bytes\n },\n )\n\n router.delete(\n '/api/v1/conversations/:conversationId/blobs/:blobId',\n async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.body = {\n ok: true,\n ...(await conversations.deleteUnreferencedBlob(\n ctx.params.conversationId,\n ctx.params.blobId,\n )),\n }\n },\n )\n}\n","import type Koa from 'koa'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport { isLinkHttpError } from '../errors.js'\n\nexport function createHttpErrorMiddleware(\n logger: FileLogger,\n): Koa.Middleware {\n return async (ctx, next) => {\n const startedAt = Date.now()\n try {\n await next()\n } catch (error) {\n const profileError =\n error instanceof Error && error.message === 'invalid profile name'\n const profileNotFound =\n error instanceof Error && error.message === 'profile does not exist'\n const status = isLinkHttpError(error)\n ? error.status\n : profileError\n ? 400\n : profileNotFound\n ? 404\n : 500\n const code = isLinkHttpError(error)\n ? error.code\n : profileNotFound\n ? 'profile_not_found'\n : status === 400\n ? 'invalid_profile_name'\n : 'internal_error'\n ctx.status = status\n ctx.body = {\n ok: false,\n error: {\n code,\n message: error instanceof Error ? error.message : 'Internal error',\n },\n }\n void logger.write(\n status >= 500 ? 'error' : 'warn',\n 'http_request_failed',\n {\n method: ctx.method,\n path: ctx.path,\n status,\n code,\n error: error instanceof Error ? error.message : String(error),\n },\n )\n } finally {\n void logger.info('http_request', {\n method: ctx.method,\n path: ctx.path,\n status: ctx.status,\n duration_ms: Date.now() - startedAt,\n })\n }\n }\n}\n","import { mkdir, readdir, readFile, rename, rm, stat } from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport YAML from 'yaml'\nimport { LinkHttpError } from '../core/errors.js'\nimport {\n deleteProfileIdentity,\n ensureProfileIdentity,\n renameProfileIdentity,\n updateProfileMetadata,\n type LinkStatistics,\n type ProfileAvatarType,\n type ProfileIdentityRecord,\n} from '../database/link-database.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport {\n ensureHermesApiServerKey,\n listHermesModelConfigs,\n readHermesApiServerConfig,\n resolveHermesConfigPath,\n resolveHermesProfileDir,\n} from './config.js'\n\nexport interface HermesProfile {\n uid: string\n name: string\n active: boolean\n path: string\n configPath: string\n displayName: string | null\n description: string | null\n avatarType: ProfileAvatarType\n avatarUrl: string | null\n}\n\nexport interface HermesProfileMetadataInput {\n displayName?: string | null\n description?: string | null\n avatarType?: ProfileAvatarType\n avatarUrl?: string | null\n}\n\nexport interface HermesProfileCapabilitySummary {\n defaultModel: string | null\n modelCount: number\n skillCount: number\n toolCount: number\n}\n\nexport interface HermesProfileStatistics extends LinkStatistics {\n profile: HermesProfile\n}\n\nconst DEFAULT_PROFILE = 'default'\nconst PROFILE_NAME_PATTERN = /^[a-zA-Z0-9._-]{1,64}$/\n\nexport async function listHermesProfiles(\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfile[]> {\n const profiles = new Map<string, HermesProfile>()\n profiles.set(DEFAULT_PROFILE, await profileInfo(DEFAULT_PROFILE, paths))\n\n const profilesDir = path.join(os.homedir(), '.hermes', 'profiles')\n const entries = await readdir(profilesDir, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n },\n )\n for (const entry of entries) {\n if (entry.isDirectory() && PROFILE_NAME_PATTERN.test(entry.name)) {\n profiles.set(entry.name, await profileInfo(entry.name, paths))\n }\n }\n\n return [...profiles.values()].sort((left, right) => {\n if (left.name === DEFAULT_PROFILE) {\n return -1\n }\n if (right.name === DEFAULT_PROFILE) {\n return 1\n }\n return left.name.localeCompare(right.name)\n })\n}\n\nexport async function getHermesProfileStatus(\n name: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfile & { exists: boolean; apiKeyConfigured: boolean }> {\n assertProfileName(name)\n const profile = await profileInfo(name, paths)\n const exists = await stat(profile.path)\n .then((value) => value.isDirectory())\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n const config = await readHermesApiServerConfig(name, profile.configPath)\n return {\n ...profile,\n exists,\n apiKeyConfigured: Boolean(config.key),\n }\n}\n\nexport async function createHermesProfile(\n name: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfile> {\n assertProfileName(name)\n if (name === DEFAULT_PROFILE) {\n throw new Error('default profile already exists')\n }\n const profile = await profileInfo(name, paths)\n if (await pathExists(profile.path)) {\n throw new Error('profile already exists')\n }\n await mkdir(profile.path, { recursive: true, mode: 0o700 })\n await ensureHermesApiServerKey(name, profile.configPath)\n return profile\n}\n\nexport async function renameHermesProfile(\n oldName: string,\n newName: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfile> {\n assertMutableProfile(oldName)\n assertMutableProfile(newName)\n const oldProfile = await profileInfo(oldName, paths)\n const newProfilePath = resolveHermesProfileDir(newName)\n await rename(oldProfile.path, newProfilePath)\n const identity = await renameProfileIdentity(paths, {\n oldProfileName: oldName,\n newProfileName: newName,\n newProfilePath,\n })\n return profileFromIdentity(identity)\n}\n\nexport async function updateHermesProfileMetadata(\n name: string,\n metadata: HermesProfileMetadataInput,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfile> {\n assertProfileName(name)\n const profile = await getHermesProfileStatus(name, paths)\n if (!profile.exists && name !== DEFAULT_PROFILE) {\n throw new Error('profile does not exist')\n }\n const identity = await updateProfileMetadata(paths, {\n profileName: name,\n metadata,\n })\n return profileFromIdentity(identity)\n}\n\nexport async function deleteHermesProfile(\n name: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfile> {\n assertMutableProfile(name)\n const profile = await profileInfo(name, paths)\n const exists = await stat(profile.path)\n .then((value) => value.isDirectory())\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n if (!exists) {\n throw new LinkHttpError(\n 404,\n 'profile_not_found',\n `Profile \"${name}\" does not exist`,\n )\n }\n await rm(resolveHermesProfileDir(name), { recursive: true, force: true })\n await deleteProfileIdentity(paths, {\n profileName: profile.name,\n profileUid: profile.uid,\n })\n return profile\n}\n\nexport async function readHermesProfileCapabilities(\n name: string,\n): Promise<HermesProfileCapabilitySummary> {\n assertProfileName(name)\n const listedModels = await listHermesModelConfigs(name).catch(() => null)\n const profileDir = resolveHermesProfileDir(name)\n return {\n defaultModel: listedModels?.defaultModel ?? null,\n modelCount: listedModels?.models.length ?? 0,\n skillCount: await countSkills(path.join(profileDir, 'skills')).catch(\n () => 0,\n ),\n toolCount: await countConfiguredTools(name).catch(() => 0),\n }\n}\n\nasync function profileInfo(\n name: string,\n paths: RuntimePaths,\n): Promise<HermesProfile> {\n const profilePath = resolveHermesProfileDir(name)\n const identity = await ensureProfileIdentity(paths, {\n profileName: name,\n profilePath,\n })\n return profileFromIdentity(identity)\n}\n\nfunction profileFromIdentity(identity: ProfileIdentityRecord): HermesProfile {\n return {\n uid: identity.profileUid,\n name: identity.profileName,\n active: false,\n path: identity.profilePath,\n configPath: resolveHermesConfigPath(identity.profileName),\n displayName: identity.displayName ?? null,\n description: identity.description ?? null,\n avatarType: identity.avatarType,\n avatarUrl: identity.avatarUrl ?? null,\n }\n}\n\nfunction assertMutableProfile(name: string): void {\n assertProfileName(name)\n if (name === DEFAULT_PROFILE) {\n throw new LinkHttpError(\n 400,\n 'default_profile_not_mutable',\n 'default profile cannot be renamed or deleted',\n )\n }\n}\n\nfunction assertProfileName(name: string): void {\n if (!PROFILE_NAME_PATTERN.test(name)) {\n throw new LinkHttpError(400, 'invalid_profile_name', 'invalid profile name')\n }\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n return await stat(targetPath)\n .then(() => true)\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n\nasync function countSkills(root: string): Promise<number> {\n const entries = await readdir(root, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n },\n )\n let count = 0\n for (const entry of entries) {\n const entryPath = path.join(root, entry.name)\n if (entry.name === '.git' || entry.name === '.hub') {\n continue\n }\n if (entry.isDirectory()) {\n count += await countSkills(entryPath)\n continue\n }\n if (entry.isFile() && entry.name === 'SKILL.md') {\n count += 1\n }\n }\n return count\n}\n\nasync function countConfiguredTools(profileName: string): Promise<number> {\n const raw = await readFile(\n resolveHermesConfigPath(profileName),\n 'utf8',\n ).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n if (!raw.trim()) {\n return 0\n }\n const config = toRecord(YAML.parse(raw))\n const toolsets = new Set<string>()\n collectToolsetValues(config.toolsets, toolsets)\n const platformToolsets = toRecord(config.platform_toolsets)\n for (const value of Object.values(platformToolsets)) {\n collectToolsetValues(value, toolsets)\n }\n const mcpServers = Object.keys(toRecord(config.mcp_servers)).length\n return toolsets.size + mcpServers\n}\n\nfunction collectToolsetValues(value: unknown, target: Set<string>): void {\n if (Array.isArray(value)) {\n for (const item of value) {\n collectToolsetValues(item, target)\n }\n return\n }\n if (typeof value === 'string' && value.trim()) {\n target.add(value.trim())\n }\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n","import type Router from '@koa/router'\nimport type { ConversationService } from '../../conversations/conversation-service.js'\nimport {\n createHermesCronJob,\n deleteHermesCronJob,\n getHermesCronJob,\n listHermesCronJobs,\n runHermesCronJobAction,\n updateHermesCronJob,\n type HermesCronJobInput,\n} from '../../hermes/api-server.js'\nimport {\n bindCronJobToHermesLink,\n decorateHermesLinkCronJob,\n HERMES_LINK_CRON_DELIVER,\n isHermesLinkCronDeliver,\n normalizeCronDeliverForHermes,\n unbindCronJobFromHermesLink,\n} from '../../hermes/cron-link-delivery.js'\nimport {\n getHermesProfileStatus,\n listHermesProfiles,\n type HermesProfile,\n} from '../../hermes/profiles.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { LinkHttpError } from '../errors.js'\nimport {\n readBoolean,\n readJsonBody,\n readPositiveInteger,\n readQueryString,\n readString,\n} from '../request.js'\n\nexport function registerCronJobRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n conversations: ConversationService\n syncCronDeliveries: () => Promise<void>\n },\n): void {\n const { paths, logger, conversations, syncCronDeliveries } = options\n\n router.get('/api/v1/cron-jobs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n await syncCronDeliveries()\n ctx.set('cache-control', 'no-store')\n const includeDisabled =\n readQueryString(ctx.query.include_disabled)?.toLowerCase() === 'true' ||\n readQueryString(ctx.query.includeDisabled)?.toLowerCase() === 'true'\n const profiles = await listHermesProfiles(paths)\n const results = await Promise.allSettled(\n profiles.map(async (profile) => ({\n profile,\n jobs: await listHermesCronJobs({\n logger,\n profileName: profile.name,\n includeDisabled,\n }),\n })),\n )\n const jobs: Record<string, unknown>[] = []\n const failures: Array<{ profile: string; message: string }> = []\n for (const result of results) {\n if (result.status === 'fulfilled') {\n const decoratedJobs = await Promise.all(\n result.value.jobs.map((job) =>\n decorateHermesLinkCronJob(paths, result.value.profile.name, job),\n ),\n )\n jobs.push(\n ...decoratedJobs.map((job) =>\n attachCronJobProfile(job, result.value.profile),\n ),\n )\n continue\n }\n const profileIndex = results.indexOf(result)\n failures.push({\n profile: profiles[profileIndex]?.name ?? 'unknown',\n message:\n result.reason instanceof Error\n ? result.reason.message\n : String(result.reason),\n })\n }\n ctx.body = { ok: failures.length === 0, jobs, failures }\n })\n\n router.get('/api/v1/profiles/:name/cron-jobs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n await syncCronDeliveries()\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n ctx.set('cache-control', 'no-store')\n const includeDisabled =\n readQueryString(ctx.query.include_disabled)?.toLowerCase() === 'true' ||\n readQueryString(ctx.query.includeDisabled)?.toLowerCase() === 'true'\n const jobs = await listHermesCronJobs({\n logger,\n profileName: profile.name,\n includeDisabled,\n })\n const decoratedJobs = await Promise.all(\n jobs.map((job) => decorateHermesLinkCronJob(paths, profile.name, job)),\n )\n ctx.body = {\n ok: true,\n profile,\n jobs: decoratedJobs.map((job) => attachCronJobProfile(job, profile)),\n }\n })\n\n router.post('/api/v1/profiles/:name/cron-jobs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n const body = await readJsonBody(ctx.req)\n const input = readCronJobCreateInput(body)\n const shouldDeliverToLink = isHermesLinkCronDeliver(input.deliver)\n const job = await createHermesCronJob(toHermesCronJobInput(input), {\n logger,\n profileName: profile.name,\n })\n const decoratedJob = shouldDeliverToLink\n ? await bindAndDecorateCronJobForHermesLink({\n paths,\n conversations,\n profileName: profile.name,\n job,\n source: 'app',\n })\n : job\n ctx.status = 201\n ctx.body = { ok: true, job: attachCronJobProfile(decoratedJob, profile) }\n })\n\n router.get('/api/v1/profiles/:name/cron-jobs/:jobId', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n ctx.set('cache-control', 'no-store')\n const job = await getHermesCronJob(ctx.params.jobId, {\n logger,\n profileName: profile.name,\n })\n ctx.body = {\n ok: true,\n job: attachCronJobProfile(\n await decorateHermesLinkCronJob(paths, profile.name, job),\n profile,\n ),\n }\n })\n\n router.patch('/api/v1/profiles/:name/cron-jobs/:jobId', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n const body = await readJsonBody(ctx.req)\n const input = readCronJobUpdateInput(body)\n const deliverTouched = readOptionalCronText(body, 'deliver').present\n const shouldDeliverToLink = isHermesLinkCronDeliver(input.deliver)\n const job = await updateHermesCronJob(\n ctx.params.jobId,\n toHermesCronJobInput(input),\n {\n logger,\n profileName: profile.name,\n },\n )\n let decoratedJob = await decorateHermesLinkCronJob(paths, profile.name, job)\n if (shouldDeliverToLink) {\n decoratedJob = await bindAndDecorateCronJobForHermesLink({\n paths,\n conversations,\n profileName: profile.name,\n job,\n source: 'app',\n })\n } else if (deliverTouched) {\n await unbindCronJobFromHermesLink(paths, profile.name, ctx.params.jobId)\n decoratedJob = job\n }\n ctx.body = { ok: true, job: attachCronJobProfile(decoratedJob, profile) }\n })\n\n router.delete('/api/v1/profiles/:name/cron-jobs/:jobId', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n await deleteHermesCronJob(ctx.params.jobId, {\n logger,\n profileName: profile.name,\n })\n await unbindCronJobFromHermesLink(paths, profile.name, ctx.params.jobId)\n ctx.body = { ok: true }\n })\n\n router.post('/api/v1/profiles/:name/cron-jobs/:jobId/pause', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n const job = await runHermesCronJobAction(ctx.params.jobId, 'pause', {\n logger,\n profileName: profile.name,\n })\n ctx.body = {\n ok: true,\n job: attachCronJobProfile(\n await decorateHermesLinkCronJob(paths, profile.name, job),\n profile,\n ),\n }\n })\n\n router.post('/api/v1/profiles/:name/cron-jobs/:jobId/resume', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n const job = await runHermesCronJobAction(ctx.params.jobId, 'resume', {\n logger,\n profileName: profile.name,\n })\n ctx.body = {\n ok: true,\n job: attachCronJobProfile(\n await decorateHermesLinkCronJob(paths, profile.name, job),\n profile,\n ),\n }\n })\n\n router.post('/api/v1/profiles/:name/cron-jobs/:jobId/run', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await getHermesProfileStatus(ctx.params.name, paths)\n const job = await runHermesCronJobAction(ctx.params.jobId, 'run', {\n logger,\n profileName: profile.name,\n })\n await syncCronDeliveries()\n ctx.body = {\n ok: true,\n job: attachCronJobProfile(\n await decorateHermesLinkCronJob(paths, profile.name, job),\n profile,\n ),\n }\n })\n}\n\nfunction toHermesCronJobInput(input: HermesCronJobInput): HermesCronJobInput {\n return {\n ...input,\n deliver: normalizeCronDeliverForHermes(input.deliver),\n }\n}\n\nasync function bindAndDecorateCronJobForHermesLink(input: {\n paths: RuntimePaths\n conversations: ConversationService\n profileName: string\n job: Record<string, unknown>\n source: 'app' | 'natural_language'\n}): Promise<Record<string, unknown>> {\n const jobId = readString(input.job, 'id') ?? readString(input.job, 'job_id')\n if (!jobId) {\n return input.job\n }\n const conversationId = await input.conversations.ensureCronInboxConversation({\n profileName: input.profileName,\n })\n await bindCronJobToHermesLink(input.paths, {\n profileName: input.profileName,\n jobId,\n conversationId,\n source: input.source,\n })\n return { ...input.job, deliver: HERMES_LINK_CRON_DELIVER }\n}\n\nfunction readCronJobCreateInput(\n body: Record<string, unknown>,\n): HermesCronJobInput {\n const input: HermesCronJobInput = {}\n const name = readString(body, 'name') ?? readString(body, 'title')\n const prompt =\n readString(body, 'prompt') ??\n readString(body, 'description') ??\n readString(body, 'task')\n const schedule = readString(body, 'schedule')\n if (!name) {\n throw new LinkHttpError(400, 'cron_job_name_required', 'name is required')\n }\n if (!prompt) {\n throw new LinkHttpError(\n 400,\n 'cron_job_prompt_required',\n 'prompt is required',\n )\n }\n if (!schedule) {\n throw new LinkHttpError(\n 400,\n 'cron_job_schedule_required',\n 'schedule is required',\n )\n }\n input.name = name\n input.prompt = prompt\n input.schedule = schedule\n input.deliver = readString(body, 'deliver') ?? HERMES_LINK_CRON_DELIVER\n const skills = readOptionalCronSkills(body)\n if (skills) {\n input.skills = skills\n }\n const repeat = readPositiveInteger(body.repeat)\n if (repeat !== undefined) {\n input.repeat = repeat\n }\n return input\n}\n\nfunction readCronJobUpdateInput(\n body: Record<string, unknown>,\n): HermesCronJobInput {\n const input: HermesCronJobInput = {}\n const name = readOptionalCronText(body, 'name', 'title')\n if (name.present) {\n if (!name.value) {\n throw new LinkHttpError(\n 400,\n 'cron_job_name_required',\n 'name cannot be empty',\n )\n }\n input.name = name.value\n }\n const prompt = readOptionalCronText(body, 'prompt', 'description', 'task')\n if (prompt.present) {\n if (!prompt.value) {\n throw new LinkHttpError(\n 400,\n 'cron_job_prompt_required',\n 'prompt cannot be empty',\n )\n }\n input.prompt = prompt.value\n }\n const schedule = readOptionalCronText(body, 'schedule')\n if (schedule.present) {\n if (!schedule.value) {\n throw new LinkHttpError(\n 400,\n 'cron_job_schedule_required',\n 'schedule cannot be empty',\n )\n }\n input.schedule = schedule.value\n }\n const deliver = readOptionalCronText(body, 'deliver')\n if (deliver.present) {\n input.deliver = deliver.value ?? 'local'\n }\n const skills = readOptionalCronSkills(body)\n if (skills) {\n input.skills = skills\n }\n const repeat = readPositiveInteger(body.repeat)\n if (repeat !== undefined) {\n input.repeat = repeat\n }\n const enabled = readBoolean(body.enabled)\n if (enabled !== undefined) {\n input.enabled = enabled\n }\n if (Object.keys(input).length === 0) {\n throw new LinkHttpError(\n 400,\n 'cron_job_update_empty',\n 'No cron job fields were provided',\n )\n }\n return input\n}\n\nfunction readOptionalCronText(\n body: Record<string, unknown>,\n ...keys: string[]\n): { present: boolean; value: string | null } {\n for (const key of keys) {\n if (!Object.prototype.hasOwnProperty.call(body, key)) {\n continue\n }\n const value = body[key]\n if (value === null || value === undefined) {\n return { present: true, value: null }\n }\n if (typeof value !== 'string') {\n throw new LinkHttpError(\n 400,\n 'cron_job_field_invalid',\n `${key} must be a string`,\n )\n }\n const trimmed = value.trim()\n return { present: true, value: trimmed || null }\n }\n return { present: false, value: null }\n}\n\nfunction readOptionalCronSkills(\n body: Record<string, unknown>,\n): string[] | undefined {\n if (!Object.prototype.hasOwnProperty.call(body, 'skills')) {\n return undefined\n }\n const value = body.skills\n if (!Array.isArray(value)) {\n throw new LinkHttpError(\n 400,\n 'cron_job_skills_invalid',\n 'skills must be an array of strings',\n )\n }\n const skills = value\n .map((item) => (typeof item === 'string' ? item.trim() : ''))\n .filter((item) => item.length > 0)\n return [...new Set(skills)]\n}\n\nfunction attachCronJobProfile(\n job: Record<string, unknown>,\n profile: HermesProfile,\n): Record<string, unknown> {\n return {\n ...job,\n profile: {\n uid: profile.uid,\n name: profile.name,\n display_name: profile.displayName,\n description: profile.description ?? null,\n avatar_type: profile.avatarType,\n avatar_url: profile.avatarUrl ?? null,\n },\n }\n}\n","import { reloadHermesGateway } from '../../hermes/gateway.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\n\nexport async function reloadGatewayAfterModelConfigChange<\n T extends { requiresGatewayReload: boolean; restartHint: string },\n>(\n result: T,\n options: { paths: RuntimePaths; logger: FileLogger },\n): Promise<T & { gatewayReloaded: boolean; reloadError?: string }> {\n try {\n await reloadHermesGateway({ paths: options.paths, logger: options.logger })\n return {\n ...result,\n gatewayReloaded: true,\n requiresGatewayReload: false,\n restartHint:\n '模型配置已保存,Hermes Gateway 已自动重载。新的 Run 会读取最新配置。',\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n await options.logger.warn(\n 'hermes_gateway_reload_after_model_config_failed',\n {\n error: message,\n },\n )\n return {\n ...result,\n gatewayReloaded: false,\n reloadError: message,\n requiresGatewayReload: true,\n restartHint: `模型配置已保存,但 Hermes Gateway 自动重载失败:${message}`,\n }\n }\n}\n\nexport async function reloadGatewayAfterProfileModelConfigChange<\n T extends { requiresGatewayReload: boolean; restartHint: string },\n>(\n result: T,\n options: { paths: RuntimePaths; logger: FileLogger; profileName: string },\n): Promise<T & { gatewayReloaded: boolean; reloadError?: string }> {\n return reloadGatewayAfterProfileConfigChange(result, {\n ...options,\n configKind: 'profile_model_config',\n label: '模型配置',\n })\n}\n\nexport async function reloadGatewayAfterProfileConfigChange<\n T extends { requiresGatewayReload: boolean; restartHint: string },\n>(\n result: T,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n profileName: string\n configKind: string\n label: string\n },\n): Promise<T & { gatewayReloaded: boolean; reloadError?: string }> {\n try {\n await reloadHermesGateway({\n paths: options.paths,\n logger: options.logger,\n profileName: options.profileName,\n })\n return {\n ...result,\n gatewayReloaded: true,\n requiresGatewayReload: false,\n restartHint: `${options.label}已保存,${options.profileName} Profile 的 Hermes Gateway 已自动重载。新的 Run 会读取最新配置。`,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n await options.logger.warn(\n 'hermes_gateway_reload_after_profile_config_failed',\n {\n config_kind: options.configKind,\n profile: options.profileName,\n error: message,\n },\n )\n return {\n ...result,\n gatewayReloaded: false,\n reloadError: message,\n requiresGatewayReload: true,\n restartHint: `${options.label}已保存,但 ${options.profileName} Profile 的 Hermes Gateway 自动重载失败:${message}`,\n }\n }\n}\n","import type Router from '@koa/router'\nimport { listHermesModels } from '../../hermes/api-server.js'\nimport {\n deleteHermesModelConfig,\n listHermesModelConfigs,\n saveHermesModelDefaults,\n saveHermesModelConfig,\n type SaveHermesModelDefaultsInput,\n type SaveHermesModelConfigInput,\n} from '../../hermes/config.js'\nimport { getHermesProfileStatus } from '../../hermes/profiles.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { isLinkHttpError, LinkHttpError } from '../errors.js'\nimport {\n readBoolean,\n readJsonBody,\n readOptionalProfileName,\n readPositiveInteger,\n readQueryString,\n readString,\n} from '../request.js'\nimport {\n reloadGatewayAfterModelConfigChange,\n reloadGatewayAfterProfileModelConfigChange,\n} from './gateway-reload.js'\n\nexport function registerModelConfigRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n },\n): void {\n const { paths, logger } = options\n\n router.get('/api/v1/models', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.body = await listHermesModels({\n logger,\n profileName: readQueryString(ctx.query.profile),\n })\n })\n\n router.get('/api/v1/model-configs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await listHermesModelConfigs()\n })\n\n router.post('/api/v1/model-configs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n try {\n const result = await saveHermesModelConfig(readModelConfigInput(body))\n ctx.body = shouldReloadGatewayAfterModelConfigChange(body)\n ? await reloadGatewayAfterModelConfigChange(result, {\n paths,\n logger,\n })\n : markModelConfigAppliedWithoutGatewayReload(result)\n } catch (error) {\n throw toModelConfigHttpError(error)\n }\n })\n\n router.patch('/api/v1/model-configs/defaults', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n try {\n ctx.body = await saveHermesModelDefaults(readModelDefaultsInput(body))\n } catch (error) {\n throw toModelConfigHttpError(error)\n }\n })\n\n router.delete('/api/v1/model-configs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const modelId = readString(body, 'model_id') ?? readString(body, 'modelId')\n if (!modelId) {\n throw new LinkHttpError(400, 'model_id_required', 'model_id is required')\n }\n try {\n const result = await deleteHermesModelConfig(modelId)\n ctx.body = await reloadGatewayAfterModelConfigChange(result, {\n paths,\n logger,\n })\n } catch (error) {\n throw toModelConfigHttpError(error)\n }\n })\n\n router.get('/api/v1/profiles/:name/model-configs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n await getHermesProfileStatus(ctx.params.name, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await listHermesModelConfigs(ctx.params.name)\n })\n\n router.post('/api/v1/profiles/:name/model-configs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n await getHermesProfileStatus(ctx.params.name, paths)\n const body = await readJsonBody(ctx.req)\n try {\n const result = await saveHermesModelConfig(\n readModelConfigInput(body),\n ctx.params.name,\n )\n ctx.body = shouldReloadGatewayAfterModelConfigChange(body)\n ? await reloadGatewayAfterProfileModelConfigChange(result, {\n paths,\n logger,\n profileName: ctx.params.name,\n })\n : markModelConfigAppliedWithoutGatewayReload(result)\n } catch (error) {\n throw toModelConfigHttpError(error)\n }\n })\n\n router.patch('/api/v1/profiles/:name/model-configs/defaults', async (ctx) => {\n await authenticateRequest(ctx, paths)\n await getHermesProfileStatus(ctx.params.name, paths)\n const body = await readJsonBody(ctx.req)\n try {\n ctx.body = await saveHermesModelDefaults(\n readModelDefaultsInput(body),\n ctx.params.name,\n )\n } catch (error) {\n throw toModelConfigHttpError(error)\n }\n })\n\n router.delete('/api/v1/profiles/:name/model-configs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n await getHermesProfileStatus(ctx.params.name, paths)\n const body = await readJsonBody(ctx.req)\n const modelId = readString(body, 'model_id') ?? readString(body, 'modelId')\n if (!modelId) {\n throw new LinkHttpError(400, 'model_id_required', 'model_id is required')\n }\n try {\n const result = await deleteHermesModelConfig(modelId, ctx.params.name)\n ctx.body = await reloadGatewayAfterProfileModelConfigChange(result, {\n paths,\n logger,\n profileName: ctx.params.name,\n })\n } catch (error) {\n throw toModelConfigHttpError(error)\n }\n })\n}\n\nfunction readModelConfigInput(\n body: Record<string, unknown>,\n): SaveHermesModelConfigInput {\n const id =\n readString(body, 'id') ??\n readString(body, 'model_id') ??\n readString(body, 'modelId')\n const provider =\n readString(body, 'provider') ??\n readString(body, 'provider_key') ??\n readString(body, 'providerKey')\n const baseUrl = readString(body, 'base_url') ?? readString(body, 'baseUrl')\n if (!id || !provider || !baseUrl) {\n throw new LinkHttpError(\n 400,\n 'model_config_invalid',\n 'id, provider and base_url are required',\n )\n }\n return {\n id,\n originalModelId:\n readString(body, 'original_model_id') ??\n readString(body, 'originalModelId') ??\n readString(body, 'original_id') ??\n undefined,\n provider,\n providerName:\n readString(body, 'provider_name') ??\n readString(body, 'providerName') ??\n undefined,\n baseUrl,\n apiKey:\n readString(body, 'api_key') ?? readString(body, 'apiKey') ?? undefined,\n apiMode:\n readString(body, 'api_mode') ?? readString(body, 'apiMode') ?? undefined,\n contextLength: readPositiveInteger(\n body.context_length ?? body.contextLength,\n ),\n keyEnv:\n readString(body, 'key_env') ?? readString(body, 'keyEnv') ?? undefined,\n setDefault: readBoolean(body.set_default ?? body.setDefault),\n reasoningEffort: (readString(body, 'reasoning_effort') ??\n readString(body, 'reasoningEffort') ??\n undefined) as SaveHermesModelConfigInput['reasoningEffort'],\n }\n}\n\nfunction readModelDefaultsInput(\n body: Record<string, unknown>,\n): SaveHermesModelDefaultsInput {\n return {\n taskModelId:\n readString(body, 'task_model_id') ??\n readString(body, 'taskModelId') ??\n readString(body, 'default_model_id') ??\n readString(body, 'defaultModelId') ??\n undefined,\n compressionModelId:\n readString(body, 'compression_model_id') ??\n readString(body, 'compressionModelId') ??\n undefined,\n }\n}\n\nfunction shouldReloadGatewayAfterModelConfigChange(\n body: Record<string, unknown>,\n): boolean {\n const explicit =\n readBoolean(body.reload_gateway ?? body.reloadGateway) ??\n (readBoolean(body.skip_gateway_reload ?? body.skipGatewayReload) === true\n ? false\n : undefined)\n return explicit ?? true\n}\n\nfunction markModelConfigAppliedWithoutGatewayReload<\n T extends { requiresGatewayReload: boolean; restartHint: string },\n>(result: T): T {\n return {\n ...result,\n requiresGatewayReload: false,\n restartHint:\n '模型配置已保存。新的 Run 会直接读取最新配置,无需重载 Hermes Gateway。',\n }\n}\n\nfunction toModelConfigHttpError(error: unknown): LinkHttpError {\n if (isLinkHttpError(error)) {\n return error\n }\n if (error instanceof Error) {\n return new LinkHttpError(400, 'model_config_invalid', error.message)\n }\n return new LinkHttpError(400, 'model_config_invalid', 'Invalid model config')\n}\n","import type Router from '@koa/router'\nimport {\n listHermesModelConfigs,\n readHermesProfilePermissions,\n type HermesProfilePermissions,\n type ListHermesModelConfigsResult,\n} from '../../hermes/config.js'\nimport {\n listHermesProfiles,\n readHermesProfileCapabilities,\n type HermesProfile,\n type HermesProfileCapabilitySummary,\n} from '../../hermes/profiles.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\n\ninterface ProfileCatalogItem {\n profile: HermesProfile\n capabilities: HermesProfileCapabilitySummary | null\n permissions: HermesProfilePermissions | null\n modelConfigs: ListHermesModelConfigsResult | null\n errors: Array<{ field: string; message: string }>\n}\n\nexport function registerProfileCatalogRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n },\n): void {\n const { paths } = options\n\n router.get('/api/v1/profiles/catalog', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n const profiles = await listHermesProfiles(paths)\n ctx.body = {\n ok: true,\n generatedAt: new Date().toISOString(),\n profiles: await Promise.all(\n profiles.map((profile) => readProfileCatalogItem(profile)),\n ),\n }\n })\n}\n\nasync function readProfileCatalogItem(\n profile: HermesProfile,\n): Promise<ProfileCatalogItem> {\n const [capabilities, permissions, modelConfigs] = await Promise.all([\n readCatalogField('capabilities', () =>\n readHermesProfileCapabilities(profile.name),\n ),\n readCatalogField('permissions', () =>\n readHermesProfilePermissions(profile.name),\n ),\n readCatalogField('modelConfigs', () => listHermesModelConfigs(profile.name)),\n ])\n return {\n profile,\n capabilities: capabilities.value,\n permissions: permissions.value,\n modelConfigs: modelConfigs.value,\n errors: [\n ...capabilities.errors,\n ...permissions.errors,\n ...modelConfigs.errors,\n ],\n }\n}\n\nasync function readCatalogField<T>(\n field: string,\n load: () => Promise<T>,\n): Promise<{ value: T | null; errors: Array<{ field: string; message: string }> }> {\n try {\n return { value: await load(), errors: [] }\n } catch (error) {\n return {\n value: null,\n errors: [{ field, message: errorMessage(error) }],\n }\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n","import { spawn } from 'node:child_process'\nimport { EventEmitter } from 'node:events'\nimport {\n copyFile,\n cp,\n mkdir,\n readFile,\n rm,\n stat,\n writeFile,\n rename,\n} from 'node:fs/promises'\nimport path from 'node:path'\nimport YAML from 'yaml'\nimport { updateProfileMetadata } from '../database/link-database.js'\nimport { LinkHttpError } from '../core/errors.js'\nimport { createRotatingTextLogWriter, type FileLogger } from '../runtime/logger.js'\nimport { type RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\nimport { resolveHermesBin } from './cli.js'\nimport {\n ensureHermesApiServerKey,\n resolveHermesConfigPath,\n resolveHermesProfileDir,\n readHermesEnvFile,\n} from './config.js'\nimport { getHermesProfileStatus, listHermesProfiles, type HermesProfile } from './profiles.js'\n\nexport type HermesProfileCreationScope =\n | 'models'\n | 'skills'\n | 'tool_permissions'\n | 'approval_policy'\n\nexport type HermesProfileCreationJobState =\n | 'idle'\n | 'running'\n | 'succeeded'\n | 'failed'\n\nexport interface StartHermesProfileCreationInput {\n name?: string | null\n displayName?: string | null\n description?: string | null\n avatarType?: 'default' | 'url' | null\n avatarUrl?: string | null\n copyFrom?: string | null\n copyScopes?: HermesProfileCreationScope[]\n}\n\nexport interface HermesProfileCreationJobStatus {\n ok: true\n state: HermesProfileCreationJobState\n job_id: string | null\n profile_name: string | null\n source_profile: string | null\n copied_scopes: HermesProfileCreationScope[]\n profile: HermesProfile | null\n pid: number | null\n started_at: string | null\n finished_at: string | null\n exit_code: number | null\n signal: string | null\n log_path: string\n lines: string[]\n error: string | null\n}\n\ninterface ProfileCreationStateFile {\n state: HermesProfileCreationJobState\n job_id: string | null\n profile_name: string | null\n source_profile: string | null\n copied_scopes: HermesProfileCreationScope[]\n profile: HermesProfile | null\n pid: number | null\n started_at: string | null\n finished_at: string | null\n exit_code: number | null\n signal: string | null\n error: string | null\n}\n\ninterface StartHermesProfileCreationOptions {\n paths: RuntimePaths\n logger?: FileLogger\n now?: () => Date\n}\n\nconst PROFILE_CREATE_LOG_FILE = 'profile-create.log'\nconst PROFILE_CREATE_LOG_MAX_FILES = 3\nconst MAX_PROFILE_CREATE_LOG_LINES = 260\nconst MAX_OUTPUT_LINE_LENGTH = 1_200\nconst PROFILE_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/u\nconst ALL_COPY_SCOPES: HermesProfileCreationScope[] = [\n 'models',\n 'skills',\n 'tool_permissions',\n 'approval_policy',\n]\nconst PROFILE_CREATION_EVENTS = new EventEmitter()\nlet runningProfileCreation: Promise<HermesProfileCreationJobStatus> | null = null\n\nexport async function startHermesProfileCreation(\n input: StartHermesProfileCreationInput,\n options: StartHermesProfileCreationOptions,\n): Promise<HermesProfileCreationJobStatus> {\n const current = await readHermesProfileCreationStatus(options.paths)\n if (runningProfileCreation || current.state === 'running') {\n return current\n }\n\n const now = options.now ?? (() => new Date())\n const normalized = await normalizeProfileCreationInput(input, options.paths)\n const profileName =\n normalized.name ??\n (await generateProfileName(normalized.displayName, options.paths))\n const sourceProfile = normalized.copyFrom\n const copyScopes = normalized.copyScopes\n const jobId = `profile_create_${now().getTime().toString(36)}`\n\n await clearProfileCreationLogFiles(options.paths)\n const writer = createRotatingTextLogWriter({\n paths: options.paths,\n fileName: PROFILE_CREATE_LOG_FILE,\n maxFileBytes: 512 * 1024,\n maxFiles: PROFILE_CREATE_LOG_MAX_FILES,\n })\n const startedAt = now().toISOString()\n const started: ProfileCreationStateFile = {\n state: 'running',\n job_id: jobId,\n profile_name: profileName,\n source_profile: sourceProfile,\n copied_scopes: [],\n profile: null,\n pid: null,\n started_at: startedAt,\n finished_at: null,\n exit_code: null,\n signal: null,\n error: null,\n }\n await mkdir(options.paths.runDir, { recursive: true, mode: 0o700 })\n await writeProfileCreationState(options.paths, started)\n await writer.write(`\\n=== profile creation started ${startedAt} ===\\n`)\n await writer.write(`Profile ID: ${profileName}\\n`)\n if (sourceProfile && copyScopes.length > 0) {\n await writer.write(\n `Copy from: ${sourceProfile} (${copyScopes.join(', ')})\\n`,\n )\n } else {\n await writer.write('Copy from: none\\n')\n }\n\n const commandArgs = ['profile', 'create', profileName, '--no-alias']\n await writer.write(`$ ${resolveHermesBin()} ${commandArgs.join(' ')}\\n`)\n await emitProfileCreationStatus(options.paths)\n const child = spawn(resolveHermesBin(), commandArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, HERMES_NONINTERACTIVE: '1' },\n windowsHide: true,\n detached: false,\n })\n started.pid = child.pid ?? null\n await writeProfileCreationState(options.paths, started)\n await emitProfileCreationStatus(options.paths)\n\n const appendChunk = async (chunk: Buffer | string) => {\n await writer.write(chunk)\n await emitProfileCreationStatus(options.paths)\n }\n child.stdout?.on('data', (chunk: Buffer) => {\n void appendChunk(chunk)\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n void appendChunk(chunk)\n })\n\n runningProfileCreation = new Promise<HermesProfileCreationJobStatus>(\n (resolve) => {\n child.on('error', (error) => {\n void (async () => {\n const failed = await failProfileCreation({\n paths: options.paths,\n writer,\n state: started,\n error: `hermes profile create failed to start: ${error.message}`,\n now,\n logger: options.logger,\n })\n resolve(failed)\n })()\n })\n child.on('close', (code, signal) => {\n void (async () => {\n if (code !== 0) {\n const failed = await failProfileCreation({\n paths: options.paths,\n writer,\n state: {\n ...started,\n exit_code: code,\n signal,\n },\n error: `hermes profile create exited with code ${code ?? 'unknown'}`,\n now,\n logger: options.logger,\n })\n resolve(failed)\n return\n }\n\n try {\n await writer.write('\\nApplying HermesPilot profile settings...\\n')\n await applyProfileCreationPostSteps({\n paths: options.paths,\n writer,\n profileName,\n displayName: normalized.displayName,\n description: normalized.description,\n avatarType: normalized.avatarType,\n avatarUrl: normalized.avatarUrl,\n sourceProfile,\n copyScopes,\n })\n const profile = await getHermesProfileStatus(profileName, options.paths)\n const finishedAt = now().toISOString()\n const succeeded: ProfileCreationStateFile = {\n ...started,\n state: 'succeeded',\n profile,\n copied_scopes: sourceProfile ? copyScopes : [],\n finished_at: finishedAt,\n exit_code: code,\n signal,\n error: null,\n }\n await writer.write(\n `\\n=== profile creation finished ${finishedAt} exit=${code ?? 'null'} signal=${signal ?? 'null'} ===\\n`,\n )\n await writeProfileCreationState(options.paths, succeeded)\n await emitProfileCreationStatus(options.paths)\n void options.logger?.info('profile_creation_succeeded', {\n job_id: jobId,\n profile: profileName,\n source_profile: sourceProfile,\n copied_scopes: sourceProfile ? copyScopes : [],\n })\n resolve(await readHermesProfileCreationStatus(options.paths))\n } catch (error) {\n const failed = await failProfileCreation({\n paths: options.paths,\n writer,\n state: {\n ...started,\n exit_code: code,\n signal,\n },\n error: error instanceof Error ? error.message : String(error),\n rollbackProfileName: profileName,\n now,\n logger: options.logger,\n })\n resolve(failed)\n }\n })()\n })\n },\n ).finally(() => {\n runningProfileCreation = null\n })\n\n void options.logger?.info('profile_creation_started', {\n job_id: jobId,\n profile: profileName,\n source_profile: sourceProfile,\n copied_scopes: sourceProfile ? copyScopes : [],\n pid: child.pid ?? null,\n })\n\n return readHermesProfileCreationStatus(options.paths)\n}\n\nexport async function readHermesProfileCreationStatus(\n paths: RuntimePaths,\n): Promise<HermesProfileCreationJobStatus> {\n let state = await readJsonFile<ProfileCreationStateFile>(\n profileCreationStatePath(paths),\n )\n if (\n state?.state === 'running' &&\n !runningProfileCreation &&\n !isRecentRunningState(state) &&\n !isProcessAlive(state.pid)\n ) {\n state = {\n ...state,\n state: 'failed',\n finished_at: new Date().toISOString(),\n error:\n state.error ??\n 'Profile creation was interrupted before Link could observe completion.',\n }\n await writeProfileCreationState(paths, state)\n }\n const lines = await readProfileCreationLogLines(paths)\n return {\n ok: true,\n state: state?.state ?? 'idle',\n job_id: state?.job_id ?? null,\n profile_name: state?.profile_name ?? null,\n source_profile: state?.source_profile ?? null,\n copied_scopes: state?.copied_scopes ?? [],\n profile: state?.profile ?? null,\n pid: state?.pid ?? null,\n started_at: state?.started_at ?? null,\n finished_at: state?.finished_at ?? null,\n exit_code: state?.exit_code ?? null,\n signal: state?.signal ?? null,\n log_path: profileCreationLogPath(paths),\n lines,\n error: state?.error ?? null,\n }\n}\n\nexport function subscribeHermesProfileCreationStatus(\n listener: (status: HermesProfileCreationJobStatus) => void,\n): () => void {\n PROFILE_CREATION_EVENTS.on('status', listener)\n return () => PROFILE_CREATION_EVENTS.off('status', listener)\n}\n\nasync function normalizeProfileCreationInput(\n input: StartHermesProfileCreationInput,\n paths: RuntimePaths,\n): Promise<{\n name: string | null\n displayName: string | null\n description: string | null\n avatarType: 'default' | 'url'\n avatarUrl: string | null\n copyFrom: string | null\n copyScopes: HermesProfileCreationScope[]\n}> {\n const name = normalizeOptionalProfileName(input.name)\n const displayName = normalizeOptionalText(input.displayName)\n const description = normalizeOptionalText(input.description)\n const avatarType = input.avatarType === 'url' ? 'url' : 'default'\n const avatarUrl = normalizeOptionalText(input.avatarUrl)\n const copyFrom = normalizeOptionalProfileName(input.copyFrom)\n const copyScopes = normalizeCopyScopes(input.copyScopes, copyFrom)\n if (copyFrom && copyFrom !== 'default') {\n const source = await getHermesProfileStatus(copyFrom, paths)\n if (!source.exists) {\n throw new LinkHttpError(\n 404,\n 'source_profile_not_found',\n `Source profile \"${copyFrom}\" does not exist`,\n )\n }\n }\n return {\n name,\n displayName,\n description,\n avatarType,\n avatarUrl: avatarType === 'url' ? avatarUrl : null,\n copyFrom,\n copyScopes,\n }\n}\n\nfunction normalizeOptionalProfileName(value: string | null | undefined): string | null {\n const trimmed = value?.trim()\n if (!trimmed) {\n return null\n }\n if (!PROFILE_NAME_PATTERN.test(trimmed)) {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_name',\n 'Profile ID must match [a-z0-9][a-z0-9_-]{0,63}',\n )\n }\n return trimmed\n}\n\nfunction normalizeOptionalText(value: string | null | undefined): string | null {\n const trimmed = value?.trim()\n return trimmed ? trimmed : null\n}\n\nfunction normalizeCopyScopes(\n scopes: HermesProfileCreationScope[] | undefined,\n copyFrom: string | null,\n): HermesProfileCreationScope[] {\n if (!copyFrom) {\n return []\n }\n const values = scopes === undefined ? ALL_COPY_SCOPES : scopes\n const allowed = new Set<HermesProfileCreationScope>(ALL_COPY_SCOPES)\n return [\n ...new Set(\n values.map((scope) => {\n if (!allowed.has(scope)) {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_copy_scope',\n `Unsupported profile copy scope: ${scope}`,\n )\n }\n return scope\n }),\n ),\n ]\n}\n\nasync function generateProfileName(\n displayName: string | null,\n paths: RuntimePaths,\n): Promise<string> {\n const base = slugifyProfileName(displayName ?? 'profile')\n const existing = new Set((await listHermesProfiles(paths)).map((profile) => profile.name))\n for (let attempt = 0; attempt < 100; attempt += 1) {\n const suffix = randomSuffix(attempt)\n const candidate = `${base}-${suffix}`.slice(0, 64).replace(/[-_]+$/u, '')\n if (!existing.has(candidate) && !(await pathExists(resolveHermesProfileDir(candidate)))) {\n return candidate\n }\n }\n throw new LinkHttpError(\n 409,\n 'profile_name_generation_failed',\n 'Could not generate a unique Profile ID',\n )\n}\n\nfunction slugifyProfileName(value: string): string {\n const slug = value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9_-]+/gu, '-')\n .replace(/^-+/u, '')\n .replace(/-+$/u, '')\n .slice(0, 44)\n if (!slug || !/^[a-z0-9]/u.test(slug)) {\n return 'profile'\n }\n if (slug === 'default') {\n return 'profile'\n }\n return slug\n}\n\nfunction randomSuffix(attempt: number): string {\n const seed = `${Date.now().toString(36)}${Math.floor(Math.random() * 1_000_000)\n .toString(36)\n .padStart(4, '0')}`\n return attempt === 0 ? seed.slice(-6) : `${seed.slice(-5)}${attempt}`\n}\n\nasync function applyProfileCreationPostSteps(input: {\n paths: RuntimePaths\n writer: ReturnType<typeof createRotatingTextLogWriter>\n profileName: string\n displayName: string | null\n description: string | null\n avatarType: 'default' | 'url'\n avatarUrl: string | null\n sourceProfile: string | null\n copyScopes: HermesProfileCreationScope[]\n}): Promise<void> {\n const profilePath = resolveHermesProfileDir(input.profileName)\n if (!(await pathExists(profilePath))) {\n await mkdir(profilePath, { recursive: true, mode: 0o700 })\n }\n\n if (input.sourceProfile && input.copyScopes.length > 0) {\n await copyProfileScopes({\n targetProfile: input.profileName,\n sourceProfile: input.sourceProfile,\n scopes: input.copyScopes,\n writer: input.writer,\n })\n }\n\n await input.writer.write('Ensuring Hermes API Server config...\\n')\n await ensureHermesApiServerKey(input.profileName)\n await getHermesProfileStatus(input.profileName, input.paths)\n\n if (\n input.displayName ||\n input.description ||\n input.avatarType === 'url' ||\n input.avatarUrl\n ) {\n await input.writer.write('Saving Profile display metadata...\\n')\n await updateProfileMetadata(input.paths, {\n profileName: input.profileName,\n metadata: {\n ...(input.displayName ? { displayName: input.displayName } : {}),\n ...(input.description ? { description: input.description } : {}),\n avatarType: input.avatarType,\n avatarUrl: input.avatarUrl,\n },\n })\n }\n}\n\nasync function copyProfileScopes(input: {\n targetProfile: string\n sourceProfile: string\n scopes: HermesProfileCreationScope[]\n writer: ReturnType<typeof createRotatingTextLogWriter>\n}): Promise<void> {\n const sourceConfigPath = resolveHermesConfigPath(input.sourceProfile)\n const targetConfigPath = resolveHermesConfigPath(input.targetProfile)\n const sourceConfig = await readYamlConfig(sourceConfigPath)\n const targetConfig = await readYamlConfig(targetConfigPath)\n\n if (input.scopes.includes('models')) {\n await input.writer.write('Copying model configuration...\\n')\n const copiedModelConfig = copyModelConfig(sourceConfig.config, targetConfig.config)\n await copyReferencedEnvValues(copiedModelConfig, input.sourceProfile, input.targetProfile)\n }\n\n if (input.scopes.includes('tool_permissions')) {\n await input.writer.write('Copying tool permissions...\\n')\n copyToolPermissionsConfig(sourceConfig.config, targetConfig.config)\n }\n\n if (input.scopes.includes('approval_policy')) {\n await input.writer.write('Copying approval policy...\\n')\n copyProperty(sourceConfig.config, targetConfig.config, 'approvals')\n }\n\n if (input.scopes.includes('skills')) {\n await input.writer.write('Copying skills...\\n')\n await copySkills(input.sourceProfile, input.targetProfile)\n copyProperty(sourceConfig.config, targetConfig.config, 'skills')\n }\n\n await writeYamlConfig(targetConfigPath, targetConfig)\n}\n\nfunction copyModelConfig(\n source: Record<string, unknown>,\n target: Record<string, unknown>,\n): Record<string, unknown> {\n const copied: Record<string, unknown> = {}\n for (const key of [\n 'model',\n 'custom_providers',\n 'providers',\n 'fallback_model',\n 'credential_pool_strategies',\n ]) {\n copyProperty(source, target, key)\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n copied[key] = cloneJson(source[key])\n }\n }\n const sourceAuxiliary = toRecord(source.auxiliary)\n if (Object.prototype.hasOwnProperty.call(sourceAuxiliary, 'compression')) {\n const targetAuxiliary = ensureRecord(target, 'auxiliary')\n targetAuxiliary.compression = cloneJson(sourceAuxiliary.compression)\n copied.auxiliary = { compression: cloneJson(sourceAuxiliary.compression) }\n }\n return copied\n}\n\nfunction copyToolPermissionsConfig(\n source: Record<string, unknown>,\n target: Record<string, unknown>,\n): void {\n const sourcePlatformToolsets = toRecord(source.platform_toolsets)\n if (Object.prototype.hasOwnProperty.call(sourcePlatformToolsets, 'api_server')) {\n const targetPlatformToolsets = ensureRecord(target, 'platform_toolsets')\n targetPlatformToolsets.api_server = cloneJson(sourcePlatformToolsets.api_server)\n }\n\n const sourceStt = toRecord(source.stt)\n if (Object.prototype.hasOwnProperty.call(sourceStt, 'enabled')) {\n const targetStt = ensureRecord(target, 'stt')\n targetStt.enabled = cloneJson(sourceStt.enabled)\n }\n\n copyProperty(source, target, 'command_allowlist')\n}\n\nasync function copyReferencedEnvValues(\n sourceConfig: Record<string, unknown>,\n sourceProfile: string,\n targetProfile: string,\n): Promise<void> {\n const keys = collectEnvKeys(sourceConfig)\n if (keys.size === 0) {\n return\n }\n const sourceEnv = await readHermesEnvFile(sourceProfile)\n const values = [...keys]\n .map((key) => [key, sourceEnv[key]] as const)\n .filter((entry): entry is readonly [string, string] => Boolean(entry[1]))\n if (values.length === 0) {\n return\n }\n await writeEnvValues(targetProfile, values)\n}\n\nfunction collectEnvKeys(value: unknown, keys = new Set<string>()): Set<string> {\n if (Array.isArray(value)) {\n for (const item of value) {\n collectEnvKeys(item, keys)\n }\n return keys\n }\n if (typeof value === 'object' && value !== null) {\n for (const [key, item] of Object.entries(value)) {\n if (\n key === 'key_env' ||\n key.endsWith('_key_env') ||\n key.endsWith('_env_var') ||\n key === 'api_key_env'\n ) {\n const envKey = typeof item === 'string' ? item.trim() : ''\n if (/^[A-Za-z_][A-Za-z0-9_]*$/u.test(envKey)) {\n keys.add(envKey)\n }\n }\n collectEnvKeys(item, keys)\n }\n return keys\n }\n if (typeof value === 'string') {\n const match = /^\\$\\{(?<key>[A-Za-z_][A-Za-z0-9_]*)\\}$/u.exec(value.trim())\n if (match?.groups?.key) {\n keys.add(match.groups.key)\n }\n }\n return keys\n}\n\nasync function writeEnvValues(\n profileName: string,\n values: readonly (readonly [string, string])[],\n): Promise<void> {\n const envPath = path.join(resolveHermesProfileDir(profileName), '.env')\n const existingRaw = await readFile(envPath, 'utf8').catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n const lines = existingRaw ? existingRaw.split(/\\r?\\n/u) : []\n const remaining = new Map(values)\n const nextLines = lines.map((line) => {\n const trimmed = line.trim()\n for (const [key, value] of remaining) {\n const keyPattern = new RegExp(`^(?:export\\\\s+)?${escapeRegExp(key)}=`, 'u')\n if (keyPattern.test(trimmed)) {\n remaining.delete(key)\n return `${key}=${formatEnvValue(value)}`\n }\n }\n return line\n })\n if (remaining.size > 0 && nextLines.length > 0 && nextLines.at(-1) !== '') {\n nextLines.push('')\n }\n for (const [key, value] of remaining) {\n nextLines.push(`${key}=${formatEnvValue(value)}`)\n }\n const nextRaw = nextLines.join('\\n').replace(/\\n*$/u, '\\n')\n await mkdir(path.dirname(envPath), { recursive: true, mode: 0o700 })\n if (existingRaw) {\n await copyFile(envPath, `${envPath}.bak.${Date.now()}`)\n }\n const tempPath = `${envPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, nextRaw, { mode: 0o600 })\n await rename(tempPath, envPath)\n}\n\nasync function copySkills(sourceProfile: string, targetProfile: string): Promise<void> {\n const sourceSkills = path.join(resolveHermesProfileDir(sourceProfile), 'skills')\n const targetSkills = path.join(resolveHermesProfileDir(targetProfile), 'skills')\n if (!(await pathExists(sourceSkills))) {\n return\n }\n await rm(targetSkills, { recursive: true, force: true })\n await cp(sourceSkills, targetSkills, {\n recursive: true,\n force: true,\n errorOnExist: false,\n })\n}\n\nfunction copyProperty(\n source: Record<string, unknown>,\n target: Record<string, unknown>,\n key: string,\n): void {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = cloneJson(source[key])\n } else {\n delete target[key]\n }\n}\n\nasync function readYamlConfig(configPath: string): Promise<{\n config: Record<string, unknown>\n existingRaw: string | null\n}> {\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n return {\n config: toRecord(existingRaw ? YAML.parse(existingRaw) : {}),\n existingRaw,\n }\n}\n\nasync function writeYamlConfig(\n configPath: string,\n input: { config: Record<string, unknown>; existingRaw: string | null },\n): Promise<void> {\n await mkdir(path.dirname(configPath), { recursive: true, mode: 0o700 })\n if (input.existingRaw) {\n await copyFile(configPath, `${configPath}.bak.${Date.now()}`)\n }\n const document = new YAML.Document(input.config)\n const tempPath = `${configPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, document.toString(), { mode: 0o600 })\n await rename(tempPath, configPath)\n}\n\nasync function failProfileCreation(input: {\n paths: RuntimePaths\n writer: ReturnType<typeof createRotatingTextLogWriter>\n state: ProfileCreationStateFile\n error: string\n rollbackProfileName?: string\n now: () => Date\n logger?: FileLogger\n}): Promise<HermesProfileCreationJobStatus> {\n if (input.rollbackProfileName) {\n await input.writer.write(`\\nRolling back ${input.rollbackProfileName}...\\n`)\n await rm(resolveHermesProfileDir(input.rollbackProfileName), {\n recursive: true,\n force: true,\n }).catch(() => undefined)\n }\n const finishedAt = input.now().toISOString()\n const failed: ProfileCreationStateFile = {\n ...input.state,\n state: 'failed',\n finished_at: finishedAt,\n error: input.error,\n }\n await input.writer.write(`\\n[failed] ${input.error}\\n`)\n await writeProfileCreationState(input.paths, failed)\n await emitProfileCreationStatus(input.paths)\n void input.logger?.error('profile_creation_failed', {\n job_id: input.state.job_id,\n profile: input.state.profile_name,\n error: input.error,\n })\n return readHermesProfileCreationStatus(input.paths)\n}\n\nasync function emitProfileCreationStatus(paths: RuntimePaths): Promise<void> {\n PROFILE_CREATION_EVENTS.emit(\n 'status',\n await readHermesProfileCreationStatus(paths),\n )\n}\n\nasync function writeProfileCreationState(\n paths: RuntimePaths,\n state: ProfileCreationStateFile,\n): Promise<void> {\n await writeJsonFile(profileCreationStatePath(paths), state)\n}\n\nasync function readProfileCreationLogLines(paths: RuntimePaths): Promise<string[]> {\n const raw = await readFile(profileCreationLogPath(paths), 'utf8').catch(() => '')\n if (!raw.trim()) {\n return []\n }\n return raw\n .split(/\\r?\\n/u)\n .map((line) => line.trimEnd())\n .filter(Boolean)\n .slice(-MAX_PROFILE_CREATE_LOG_LINES)\n .map((line) =>\n line.length > MAX_OUTPUT_LINE_LENGTH\n ? `${line.slice(0, MAX_OUTPUT_LINE_LENGTH)}...`\n : line,\n )\n}\n\nfunction profileCreationStatePath(paths: RuntimePaths): string {\n return path.join(paths.runDir, 'profile-create-state.json')\n}\n\nfunction profileCreationLogPath(paths: RuntimePaths): string {\n return path.join(paths.logsDir, PROFILE_CREATE_LOG_FILE)\n}\n\nasync function clearProfileCreationLogFiles(paths: RuntimePaths): Promise<void> {\n const primary = profileCreationLogPath(paths)\n await Promise.all([\n rm(primary, { force: true }).catch(() => undefined),\n ...Array.from({ length: PROFILE_CREATE_LOG_MAX_FILES }, (_, index) =>\n rm(`${primary}.${index + 1}`, { force: true }).catch(() => undefined),\n ),\n ])\n}\n\nasync function pathExists(targetPath: string): Promise<boolean> {\n return await stat(targetPath)\n .then(() => true)\n .catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return false\n }\n throw error\n })\n}\n\nfunction isRecentRunningState(state: ProfileCreationStateFile): boolean {\n if (!state.started_at) {\n return false\n }\n return Date.now() - Date.parse(state.started_at) < 10_000\n}\n\nfunction isProcessAlive(pid: number | null): boolean {\n if (!pid || pid <= 0) {\n return false\n }\n try {\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\nfunction ensureRecord(\n target: Record<string, unknown>,\n key: string,\n): Record<string, unknown> {\n const value = target[key]\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n return value as Record<string, unknown>\n }\n const next: Record<string, unknown> = {}\n target[key] = next\n return next\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction cloneJson<T>(value: T): T {\n return value === undefined\n ? value\n : (JSON.parse(JSON.stringify(value)) as T)\n}\n\nfunction formatEnvValue(value: string): string {\n if (/^[A-Za-z0-9_./:@+-]*$/u.test(value)) {\n return value\n }\n return JSON.stringify(value)\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&')\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n","import type Router from '@koa/router'\nimport {\n readHermesProfilePermissions,\n readHermesProfileToolConfig,\n saveHermesProfilePermissions,\n saveHermesProfileToolConfig,\n type SaveHermesProfilePermissionsInput,\n type SaveHermesProfileToolConfigInput,\n} from '../../hermes/config.js'\nimport { getHermesProfileStatus } from '../../hermes/profiles.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { isLinkHttpError, LinkHttpError } from '../errors.js'\nimport {\n readBoolean,\n readJsonBody,\n readPositiveInteger,\n readString,\n} from '../request.js'\nimport { reloadGatewayAfterProfileConfigChange } from './gateway-reload.js'\n\nexport function registerProfileConfigRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n },\n): void {\n const { paths, logger } = options\n\n router.get('/api/v1/profiles/:name/permissions', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n await getHermesProfileStatus(ctx.params.name, paths)\n ctx.body = {\n ok: true,\n permissions: await readHermesProfilePermissions(ctx.params.name),\n }\n })\n\n router.patch('/api/v1/profiles/:name/permissions', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n const result = await saveHermesProfilePermissions(\n ctx.params.name,\n readProfilePermissionsInput(body),\n )\n ctx.body = {\n ok: true,\n permissions: await reloadGatewayAfterProfileConfigChange(result, {\n paths,\n logger,\n profileName: ctx.params.name,\n configKind: 'profile_permissions',\n label: '权限配置',\n }),\n }\n } catch (error) {\n throw toProfilePermissionsHttpError(error)\n }\n })\n\n router.get('/api/v1/profiles/:name/tool-configs/:toolKey', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = {\n ok: true,\n config: await readHermesProfileToolConfig(\n ctx.params.name,\n ctx.params.toolKey,\n ),\n }\n } catch (error) {\n throw toProfileToolConfigHttpError(error)\n }\n })\n\n router.patch('/api/v1/profiles/:name/tool-configs/:toolKey', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n const result = await saveHermesProfileToolConfig(\n ctx.params.name,\n ctx.params.toolKey,\n readProfileToolConfigInput(body),\n )\n ctx.body = {\n ok: true,\n config: await reloadGatewayAfterProfileConfigChange(result, {\n paths,\n logger,\n profileName: ctx.params.name,\n configKind: 'profile_tool_config',\n label: '工具后端配置',\n }),\n }\n } catch (error) {\n throw toProfileToolConfigHttpError(error)\n }\n })\n}\n\nfunction readProfilePermissionsInput(\n body: Record<string, unknown>,\n): SaveHermesProfilePermissionsInput {\n const input: SaveHermesProfilePermissionsInput = {}\n const approvals = readOptionalObject(body, 'approvals')\n if (approvals) {\n input.approvals = {\n mode:\n readString(approvals, 'mode') ??\n readString(approvals, 'approval_mode') ??\n readString(approvals, 'approvalMode') ??\n undefined,\n timeout: readPositiveInteger(approvals.timeout),\n cronMode:\n readString(approvals, 'cron_mode') ??\n readString(approvals, 'cronMode') ??\n undefined,\n }\n }\n\n const terminal = readOptionalObject(body, 'terminal')\n if (terminal) {\n input.terminal = {\n backend: readString(terminal, 'backend') ?? undefined,\n cwd: readString(terminal, 'cwd') ?? undefined,\n containerCpu: readPositiveInteger(\n terminal.container_cpu ?? terminal.containerCpu,\n ),\n containerMemory: readPositiveInteger(\n terminal.container_memory ?? terminal.containerMemory,\n ),\n containerDisk: readPositiveInteger(\n terminal.container_disk ?? terminal.containerDisk,\n ),\n containerPersistent: readBoolean(\n terminal.container_persistent ?? terminal.containerPersistent,\n ),\n }\n }\n\n const toolsets = readOptionalObject(body, 'toolsets')\n if (toolsets) {\n input.toolsets = {\n enabledToolsets:\n readStringListValue(\n toolsets.enabled_toolsets ??\n toolsets.enabledToolsets ??\n toolsets.enabled,\n 'toolsets.enabled',\n ) ?? undefined,\n mcpEnabled: readBoolean(toolsets.mcp_enabled ?? toolsets.mcpEnabled),\n }\n }\n\n if (Object.keys(input).length === 0) {\n throw new LinkHttpError(\n 400,\n 'profile_permissions_update_empty',\n 'No permission fields were provided',\n )\n }\n return input\n}\n\nfunction readOptionalObject(\n body: Record<string, unknown>,\n key: string,\n): Record<string, unknown> | undefined {\n if (!Object.prototype.hasOwnProperty.call(body, key)) {\n return undefined\n }\n const value = body[key]\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new LinkHttpError(\n 400,\n 'profile_permissions_invalid',\n `${key} must be an object`,\n )\n }\n return value as Record<string, unknown>\n}\n\nfunction readStringListValue(value: unknown, field: string): string[] | null {\n if (value === undefined) {\n return null\n }\n if (!Array.isArray(value)) {\n throw new LinkHttpError(\n 400,\n 'profile_permissions_invalid',\n `${field} must be an array of strings`,\n )\n }\n return [\n ...new Set(\n value.map((item) => {\n if (typeof item !== 'string' || !item.trim()) {\n throw new LinkHttpError(\n 400,\n 'profile_permissions_invalid',\n `${field} must contain non-empty strings`,\n )\n }\n return item.trim()\n }),\n ),\n ]\n}\n\nfunction toProfilePermissionsHttpError(error: unknown): LinkHttpError {\n if (isLinkHttpError(error)) {\n return error\n }\n if (error instanceof Error) {\n return new LinkHttpError(400, 'profile_permissions_invalid', error.message)\n }\n return new LinkHttpError(\n 400,\n 'profile_permissions_invalid',\n 'Invalid profile permissions',\n )\n}\n\nfunction readProfileToolConfigInput(\n body: Record<string, unknown>,\n): SaveHermesProfileToolConfigInput {\n const values = readOptionalObject(body, 'values') ?? body\n if (Object.keys(values).length === 0) {\n throw new LinkHttpError(\n 400,\n 'profile_tool_config_update_empty',\n 'No tool config fields were provided',\n )\n }\n return { values }\n}\n\nfunction toProfileToolConfigHttpError(error: unknown): LinkHttpError {\n if (isLinkHttpError(error)) {\n return error\n }\n if (error instanceof Error) {\n return new LinkHttpError(400, 'profile_tool_config_invalid', error.message)\n }\n return new LinkHttpError(\n 400,\n 'profile_tool_config_invalid',\n 'Invalid profile tool config',\n )\n}\n","import {\n access,\n copyFile,\n mkdir,\n readdir,\n readFile,\n rename,\n stat,\n writeFile,\n} from 'node:fs/promises'\nimport path from 'node:path'\nimport YAML from 'yaml'\nimport {\n readHermesEnvFile,\n resolveHermesConfigPath,\n resolveHermesProfileDir,\n} from './config.js'\n\nexport type HermesMemoryTarget = 'memory' | 'user'\n\nexport interface HermesMemoryEntry {\n id: string\n content: string\n}\n\nexport interface HermesMemoryStoreSnapshot {\n target: HermesMemoryTarget\n label: string\n description: string\n fileName: string\n path: string\n exists: boolean\n updatedAt: string | null\n entries: HermesMemoryEntry[]\n entryCount: number\n usage: {\n chars: number\n limit: number\n percent: number\n }\n}\n\nexport interface HermesMemoryProviderSetting {\n key: string\n label: string\n value: boolean | number | string | null\n editable: boolean\n kind: 'boolean' | 'number' | 'string' | 'select' | 'text'\n options?: string[]\n}\n\nexport type HermesKnownMemoryProviderId =\n | 'built-in'\n | 'honcho'\n | 'openviking'\n | 'mem0'\n | 'hindsight'\n | 'holographic'\n | 'retaindb'\n | 'byterover'\n | 'supermemory'\n\nexport interface HermesMemoryProviderSummary {\n id: string\n label: string\n description: string\n active: boolean\n configurable: boolean\n configured: boolean\n configurationIssue: string | null\n providerConfigPath: string | null\n settings: HermesMemoryProviderSetting[]\n}\n\nexport interface HermesMemorySettingsSnapshot {\n provider: string | null\n builtInOnly: boolean\n configPath: string | null\n providerConfigPath: string | null\n settings: HermesMemoryProviderSetting[]\n providers: HermesMemoryProviderSummary[]\n}\n\nexport interface HermesProfileMemorySnapshot {\n ok: true\n profileName: string\n memoryDir: string\n stores: HermesMemoryStoreSnapshot[]\n settings: HermesMemorySettingsSnapshot\n notice: string\n}\n\nexport interface HermesMemorySettingsPatch {\n autoRecall?: boolean\n autoCapture?: boolean\n autoRetain?: boolean\n mode?: string\n apiUrl?: string\n bankId?: string\n llmProvider?: string\n llmModel?: string\n llmBaseUrl?: string\n containerTag?: string\n memoryMode?: string\n recallBudget?: string\n maxRecallResults?: number\n profileFrequency?: number\n captureMode?: string\n searchMode?: string\n providerId?: string\n configJson?: string\n baseUrl?: string\n workspace?: string\n peerName?: string\n aiPeer?: string\n recallMode?: string\n writeFrequency?: string\n saveMessages?: boolean\n sessionStrategy?: string\n contextTokens?: number\n contextCadence?: number\n dialecticCadence?: number\n dialecticDepth?: number\n userId?: string\n agentId?: string\n rerank?: boolean\n endpoint?: string\n account?: string\n user?: string\n agent?: string\n dbPath?: string\n autoExtract?: boolean\n defaultTrust?: number\n hrrDim?: number\n project?: string\n}\n\nconst ENTRY_DELIMITER = '\\n§\\n'\nconst MEMORY_LIMIT = 2200\nconst USER_LIMIT = 1375\nconst CUSTOM_PROVIDER_CARD_ID = '__custom__'\nconst CUSTOM_PROVIDER_REGISTRY_FILE = 'memory-providers.json'\nconst HINDSIGHT_DEFAULT_API_URL = 'https://api.hindsight.vectorize.io'\nconst HINDSIGHT_DEFAULT_LOCAL_URL = 'http://localhost:8888'\nconst OPENVIKING_DEFAULT_ENDPOINT = 'http://127.0.0.1:1933'\nconst RETAINDB_DEFAULT_BASE_URL = 'https://api.retaindb.com'\nconst HINDSIGHT_LLM_PROVIDERS = [\n 'openai',\n 'anthropic',\n 'gemini',\n 'groq',\n 'openrouter',\n 'minimax',\n 'ollama',\n 'lmstudio',\n 'openai_compatible',\n]\nconst MEMORY_PROVIDER_CATALOG: Array<{\n id: HermesKnownMemoryProviderId\n label: string\n description: string\n configurable: boolean\n}> = [\n {\n id: 'built-in',\n label: 'Built-in memory',\n description: '使用当前 Profile 的 USER.md / MEMORY.md,本地文件即可工作。',\n configurable: false,\n },\n {\n id: 'honcho',\n label: 'Honcho',\n description:\n 'AI-native cross-session user modeling provider;这里可编辑 workspace、peer 与召回策略。',\n configurable: true,\n },\n {\n id: 'openviking',\n label: 'OpenViking',\n description:\n '上下文数据库与层级知识库 provider;这里可编辑非敏感 endpoint、account 与 agent 标识。',\n configurable: true,\n },\n {\n id: 'mem0',\n label: 'Mem0',\n description:\n '语义搜索与事实抽取 provider;这里可编辑 user、agent 与 rerank 策略。',\n configurable: true,\n },\n {\n id: 'hindsight',\n label: 'Hindsight',\n description:\n '知识图谱与多策略检索 provider;这里可编辑非敏感连接、bank 与召回策略。',\n configurable: true,\n },\n {\n id: 'holographic',\n label: 'Holographic',\n description:\n '本地 SQLite fact store provider;这里可编辑数据库路径、自动抽取与检索参数。',\n configurable: true,\n },\n {\n id: 'retaindb',\n label: 'RetainDB',\n description:\n 'Cloud memory API provider;这里可编辑非敏感 endpoint 与 project。',\n configurable: true,\n },\n {\n id: 'byterover',\n label: 'ByteRover',\n description:\n '基于 brv CLI 的本地优先知识树 provider;云同步 API key 需在本机配置。',\n configurable: false,\n },\n {\n id: 'supermemory',\n label: 'Supermemory',\n description:\n '语义长期记忆 provider;这里可编辑容器、自动捕获与召回策略。',\n configurable: true,\n },\n]\n\nexport class HermesMemoryError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n ) {\n super(message)\n }\n}\n\nexport async function readHermesProfileMemory(\n profileName = 'default',\n): Promise<HermesProfileMemorySnapshot> {\n const memoryDir = resolveMemoryDir(profileName)\n const [memoryStore, userStore, settings] = await Promise.all([\n readMemoryStore(profileName, 'memory'),\n readMemoryStore(profileName, 'user'),\n readMemorySettings(profileName),\n ])\n return {\n ok: true,\n profileName,\n memoryDir,\n stores: [userStore, memoryStore],\n settings,\n notice:\n '记忆修改会写入当前 Profile 的磁盘文件;已经启动的会话通常要到新会话才会完整读取最新快照。',\n }\n}\n\nexport async function addHermesMemoryEntry(\n profileName: string,\n target: HermesMemoryTarget,\n content: string,\n): Promise<HermesProfileMemorySnapshot> {\n const normalized = normalizeEntryContent(content)\n await mutateMemoryEntries(profileName, target, (entries) => {\n if (entries.includes(normalized)) {\n return entries\n }\n const next = [...entries, normalized]\n assertWithinLimit(target, next)\n return next\n })\n return readHermesProfileMemory(profileName)\n}\n\nexport async function replaceHermesMemoryEntry(\n profileName: string,\n target: HermesMemoryTarget,\n oldText: string,\n content: string,\n): Promise<HermesProfileMemorySnapshot> {\n const needle = normalizeNeedle(oldText)\n const normalized = normalizeEntryContent(content)\n await mutateMemoryEntries(profileName, target, (entries) => {\n const index = findSingleMatch(entries, needle)\n const next = [...entries]\n next[index] = normalized\n assertWithinLimit(target, next)\n return next\n })\n return readHermesProfileMemory(profileName)\n}\n\nexport async function removeHermesMemoryEntry(\n profileName: string,\n target: HermesMemoryTarget,\n oldText: string,\n): Promise<HermesProfileMemorySnapshot> {\n const needle = normalizeNeedle(oldText)\n await mutateMemoryEntries(profileName, target, (entries) => {\n const index = findSingleMatch(entries, needle)\n return entries.filter((_, itemIndex) => itemIndex !== index)\n })\n return readHermesProfileMemory(profileName)\n}\n\nexport async function resetHermesMemoryStore(\n profileName: string,\n target: HermesMemoryTarget | 'all',\n): Promise<HermesProfileMemorySnapshot> {\n if (target === 'all') {\n await Promise.all([\n writeMemoryEntries(profileName, 'memory', []),\n writeMemoryEntries(profileName, 'user', []),\n ])\n } else {\n await writeMemoryEntries(profileName, target, [])\n }\n return readHermesProfileMemory(profileName)\n}\n\nexport async function saveHermesMemorySettings(\n profileName: string,\n patch: HermesMemorySettingsPatch,\n): Promise<HermesProfileMemorySnapshot> {\n const provider = await readActiveMemoryProvider(profileName)\n if (!provider) {\n throw new HermesMemoryError(\n 'memory_settings_builtin_only',\n '当前 Profile 使用 built-in memory,没有可保存的外部 provider 设置。',\n )\n }\n await saveProviderSettings(profileName, provider, patch)\n return readHermesProfileMemory(profileName)\n}\n\nexport async function saveHermesMemoryProviderSettings(\n profileName: string,\n provider: string,\n patch: HermesMemorySettingsPatch,\n): Promise<HermesProfileMemorySnapshot> {\n await saveProviderSettings(\n profileName,\n normalizeConfigurableProvider(provider, patch),\n patch,\n )\n return readHermesProfileMemory(profileName)\n}\n\nexport async function setHermesMemoryProvider(\n profileName: string,\n provider: string,\n): Promise<HermesProfileMemorySnapshot> {\n const providerId = normalizeSelectableProvider(provider)\n await assertProviderCanBeActivated(profileName, providerId)\n await patchHermesMemoryProvider(profileName, providerId)\n return readHermesProfileMemory(profileName)\n}\n\nasync function saveProviderSettings(\n profileName: string,\n provider: string,\n patch: HermesMemorySettingsPatch,\n): Promise<void> {\n if (provider === 'honcho') {\n await patchJsonProviderConfig(profileName, 'honcho.json', {\n baseUrl: patch.baseUrl,\n workspace: patch.workspace,\n peerName: patch.peerName,\n aiPeer: patch.aiPeer,\n recallMode: patch.recallMode,\n writeFrequency: patch.writeFrequency,\n saveMessages: patch.saveMessages,\n sessionStrategy: patch.sessionStrategy,\n contextTokens: patch.contextTokens,\n contextCadence: patch.contextCadence,\n dialecticCadence: patch.dialecticCadence,\n dialecticDepth: patch.dialecticDepth,\n })\n return\n }\n if (provider === 'mem0') {\n await patchJsonProviderConfig(profileName, 'mem0.json', {\n user_id: patch.userId,\n agent_id: patch.agentId,\n rerank: patch.rerank,\n })\n return\n }\n if (provider === 'openviking') {\n await patchHermesMemoryEnv(profileName, {\n OPENVIKING_ENDPOINT: patch.endpoint,\n OPENVIKING_ACCOUNT: patch.account,\n OPENVIKING_USER: patch.user,\n OPENVIKING_AGENT: patch.agent,\n })\n return\n }\n if (provider === 'supermemory') {\n await patchJsonProviderConfig(profileName, 'supermemory.json', {\n container_tag: patch.containerTag,\n auto_recall: patch.autoRecall,\n auto_capture: patch.autoCapture,\n max_recall_results: patch.maxRecallResults,\n profile_frequency: patch.profileFrequency,\n capture_mode: patch.captureMode,\n search_mode: patch.searchMode,\n })\n return\n }\n if (provider === 'hindsight') {\n await patchJsonProviderConfig(\n profileName,\n path.join('hindsight', 'config.json'),\n {\n mode: patch.mode,\n api_url: patch.apiUrl,\n bank_id: patch.bankId,\n llm_provider: patch.llmProvider,\n llm_model: patch.llmModel,\n llm_base_url: patch.llmBaseUrl,\n auto_recall: patch.autoRecall,\n auto_retain: patch.autoRetain,\n memory_mode: patch.memoryMode,\n recall_budget: patch.recallBudget,\n },\n )\n return\n }\n if (provider === 'holographic') {\n await patchHolographicProviderConfig(profileName, {\n db_path: patch.dbPath,\n auto_extract: patch.autoExtract,\n default_trust: patch.defaultTrust,\n hrr_dim: patch.hrrDim,\n })\n return\n }\n if (provider === 'retaindb') {\n await patchHermesMemoryEnv(profileName, {\n RETAINDB_BASE_URL: patch.baseUrl,\n RETAINDB_PROJECT: patch.project,\n })\n return\n }\n if (provider === 'byterover') {\n return\n }\n await patchCustomProviderConfig(profileName, provider, patch)\n}\n\nasync function patchCustomProviderConfig(\n profileName: string,\n provider: string,\n patch: HermesMemorySettingsPatch,\n): Promise<void> {\n const providerId = normalizeCustomProviderId(provider)\n const configJson = patch.configJson?.trim()\n if (!configJson) {\n await saveCustomProviderRegistryEntry(profileName, providerId)\n return\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(configJson)\n } catch {\n throw new HermesMemoryError(\n 'memory_provider_config_invalid',\n '自定义 memory provider 配置必须是有效的 JSON object。',\n )\n }\n const config = toRecord(parsed)\n if (Object.keys(config).length === 0 && parsed !== null) {\n throw new HermesMemoryError(\n 'memory_provider_config_invalid',\n '自定义 memory provider 配置必须是 JSON object。',\n )\n }\n assertNoSensitiveConfigKeys(config)\n await writeCustomProviderConfig(profileName, providerId, config)\n await saveCustomProviderRegistryEntry(profileName, providerId)\n}\n\nfunction assertNoSensitiveConfigKeys(\n value: unknown,\n pathParts: string[] = [],\n): void {\n if (Array.isArray(value)) {\n value.forEach((item, index) =>\n assertNoSensitiveConfigKeys(item, [...pathParts, `${index}`]),\n )\n return\n }\n if (!value || typeof value !== 'object') {\n return\n }\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (isSensitiveConfigKey(key)) {\n throw new HermesMemoryError(\n 'memory_provider_config_sensitive',\n `出于安全边界,App 不能保存自定义 provider 的敏感字段:${[\n ...pathParts,\n key,\n ].join('.')}`,\n )\n }\n assertNoSensitiveConfigKeys(child, [...pathParts, key])\n }\n}\n\nfunction isSensitiveConfigKey(key: string): boolean {\n return /(?:api[_-]?key|token|secret|password|credential|bearer|private[_-]?key)/iu.test(\n key,\n )\n}\n\nasync function writeCustomProviderConfig(\n profileName: string,\n provider: string,\n config: Record<string, unknown>,\n): Promise<void> {\n const configPath = customProviderConfigPath(profileName, provider)\n await mkdir(path.dirname(configPath), { recursive: true, mode: 0o700 })\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, {\n encoding: 'utf8',\n mode: 0o600,\n })\n}\n\nfunction normalizeConfigurableProvider(\n provider: string,\n patch?: HermesMemorySettingsPatch,\n): string {\n if (provider === CUSTOM_PROVIDER_CARD_ID) {\n return normalizeCustomProviderId(patch?.providerId ?? '')\n }\n const providerId = normalizeSelectableProvider(provider)\n if (providerId !== 'built-in') {\n return providerId\n }\n throw new HermesMemoryError(\n 'memory_settings_builtin_only',\n 'Built-in memory 没有额外 provider 设置。',\n )\n}\n\nfunction normalizeSelectableProvider(\n provider: string,\n): string {\n const normalized = provider.trim().toLowerCase()\n if (\n normalized === 'built-in' ||\n normalized === 'builtin' ||\n normalized === 'built_in' ||\n normalized === 'none'\n ) {\n return 'built-in'\n }\n if (knownMemoryProviderIds().has(normalized as HermesKnownMemoryProviderId)) {\n return normalized\n }\n return normalizeCustomProviderId(normalized)\n}\n\nfunction knownMemoryProviderIds(): Set<HermesKnownMemoryProviderId> {\n return new Set(MEMORY_PROVIDER_CATALOG.map((provider) => provider.id))\n}\n\nfunction normalizeCustomProviderId(provider: string): string {\n const normalized = provider.trim().toLowerCase()\n if (!/^[a-z0-9][a-z0-9_-]{0,63}$/u.test(normalized)) {\n throw new HermesMemoryError(\n 'memory_provider_invalid',\n '自定义 memory provider ID 只能包含小写字母、数字、横线和下划线。',\n )\n }\n if (\n normalized === CUSTOM_PROVIDER_CARD_ID ||\n normalized === 'built-in' ||\n normalized === 'builtin' ||\n normalized === 'built_in' ||\n normalized === 'none'\n ) {\n throw new HermesMemoryError(\n 'memory_provider_invalid',\n '这个 memory provider ID 是保留名称。',\n )\n }\n return normalized\n}\n\nasync function patchHermesMemoryProvider(\n profileName: string,\n provider: string,\n): Promise<void> {\n const configPath = resolveHermesConfigPath(profileName)\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n const document = existingRaw\n ? YAML.parseDocument(existingRaw)\n : new YAML.Document({})\n const config = toRecord(document.toJSON())\n const memory = toRecord(config.memory)\n memory.provider = provider === 'built-in' ? '' : provider\n config.memory = memory\n const backupPath = existingRaw ? `${configPath}.bak.${Date.now()}` : null\n await mkdir(path.dirname(configPath), { recursive: true, mode: 0o700 })\n if (backupPath) {\n await copyFile(configPath, backupPath)\n }\n document.contents = document.createNode(config)\n const tempPath = `${configPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, document.toString(), {\n encoding: 'utf8',\n mode: 0o600,\n })\n await rename(tempPath, configPath)\n}\n\nfunction resolveMemoryDir(profileName: string): string {\n return path.join(resolveHermesProfileDir(profileName), 'memories')\n}\n\nasync function readMemoryStore(\n profileName: string,\n target: HermesMemoryTarget,\n): Promise<HermesMemoryStoreSnapshot> {\n const filePath = memoryFilePath(profileName, target)\n const entries = await readMemoryEntries(filePath)\n const fileStat = await stat(filePath).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n })\n const chars = entries.length ? entries.join(ENTRY_DELIMITER).length : 0\n const limit = target === 'user' ? USER_LIMIT : MEMORY_LIMIT\n return {\n target,\n label: target === 'user' ? '关于用户' : 'Agent 笔记',\n description:\n target === 'user'\n ? '用户偏好、沟通方式、长期身份信息。'\n : '环境事实、项目约定、工具习惯和长期经验。',\n fileName: target === 'user' ? 'USER.md' : 'MEMORY.md',\n path: filePath,\n exists: fileStat !== null,\n updatedAt: fileStat?.mtime.toISOString() ?? null,\n entries: entries.map((content, index) => ({\n id: `${target}_${index}_${hashString(content)}`,\n content,\n })),\n entryCount: entries.length,\n usage: {\n chars,\n limit,\n percent: limit > 0 ? Math.min(100, Math.floor((chars / limit) * 100)) : 0,\n },\n }\n}\n\nasync function readMemoryEntries(filePath: string): Promise<string[]> {\n const raw = await readFile(filePath, 'utf8').catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n return parseMemoryEntries(raw)\n}\n\nfunction parseMemoryEntries(raw: string): string[] {\n if (!raw.trim()) {\n return []\n }\n return raw\n .split(ENTRY_DELIMITER)\n .map((entry) => entry.trim())\n .filter(Boolean)\n}\n\nasync function mutateMemoryEntries(\n profileName: string,\n target: HermesMemoryTarget,\n mutate: (entries: string[]) => string[],\n): Promise<void> {\n const current = await readMemoryEntries(memoryFilePath(profileName, target))\n await writeMemoryEntries(profileName, target, mutate([...new Set(current)]))\n}\n\nasync function writeMemoryEntries(\n profileName: string,\n target: HermesMemoryTarget,\n entries: string[],\n): Promise<void> {\n assertWithinLimit(target, entries)\n const filePath = memoryFilePath(profileName, target)\n const dir = path.dirname(filePath)\n await mkdir(dir, { recursive: true, mode: 0o700 })\n const tempPath = path.join(\n dir,\n `.mem_${process.pid}_${Date.now()}_${target}.tmp`,\n )\n await writeFile(tempPath, entries.join(ENTRY_DELIMITER), {\n encoding: 'utf8',\n mode: 0o600,\n })\n await rename(tempPath, filePath)\n}\n\nfunction memoryFilePath(\n profileName: string,\n target: HermesMemoryTarget,\n): string {\n return path.join(\n resolveMemoryDir(profileName),\n target === 'user' ? 'USER.md' : 'MEMORY.md',\n )\n}\n\nasync function readMemorySettings(\n profileName: string,\n): Promise<HermesMemorySettingsSnapshot> {\n const provider = await readActiveMemoryProvider(profileName)\n const providers = await readMemoryProviderSummaries(profileName, provider)\n const activeProvider = providers.find((item) => item.active)\n const settings = activeProvider?.settings ?? []\n const providerConfigPath = activeProvider?.providerConfigPath ?? null\n return {\n provider,\n builtInOnly: !provider,\n configPath: resolveHermesConfigPath(profileName),\n providerConfigPath,\n settings,\n providers,\n }\n}\n\ninterface CustomMemoryProviderDescriptor {\n id: string\n label: string\n description: string\n}\n\nasync function readCustomProviderSummaries(\n profileName: string,\n activeProviderId: string,\n): Promise<HermesMemoryProviderSummary[]> {\n const descriptors = new Map<string, CustomMemoryProviderDescriptor>()\n for (const descriptor of [\n ...(await discoverUserMemoryProviderDescriptors(profileName)),\n ...(await readCustomProviderRegistry(profileName)),\n ]) {\n if (\n descriptor.id === CUSTOM_PROVIDER_CARD_ID ||\n knownMemoryProviderIds().has(descriptor.id as HermesKnownMemoryProviderId)\n ) {\n continue\n }\n descriptors.set(descriptor.id, descriptor)\n }\n return Promise.all(\n [...descriptors.values()].map(async (descriptor) => {\n const installed = await isUserMemoryProviderInstalled(\n profileName,\n descriptor.id,\n )\n return {\n id: descriptor.id,\n label: descriptor.label,\n description: descriptor.description,\n active: descriptor.id === activeProviderId,\n configurable: true,\n configured: installed,\n configurationIssue: installed\n ? null\n : '没有在当前 HERMES_HOME/plugins/ 下发现这个自定义 memory provider。',\n providerConfigPath: customProviderConfigPath(profileName, descriptor.id),\n settings: await readCustomProviderSettings(profileName, descriptor.id),\n }\n }),\n )\n}\n\nasync function readCustomProviderSetupSummary(\n profileName: string,\n): Promise<HermesMemoryProviderSummary> {\n return {\n id: CUSTOM_PROVIDER_CARD_ID,\n label: 'Custom provider',\n description:\n '输入已安装到 HERMES_HOME/plugins/ 的 provider ID,并编辑非敏感 JSON 配置。',\n active: false,\n configurable: true,\n configured: true,\n configurationIssue: null,\n providerConfigPath: path.join(\n resolveHermesProfileDir(profileName),\n '<provider>.json',\n ),\n settings: [\n stringSetting('providerId', 'Provider ID', ''),\n textSetting('configJson', 'JSON 配置', '{}'),\n ],\n }\n}\n\nasync function readCustomProviderSettings(\n profileName: string,\n provider: string,\n): Promise<HermesMemoryProviderSetting[]> {\n const config = await readJsonObject(customProviderConfigPath(profileName, provider))\n return [\n stringSetting('providerId', 'Provider ID', provider, false),\n textSetting('configJson', 'JSON 配置', JSON.stringify(config, null, 2)),\n ]\n}\n\nasync function readMemoryProviderSummaries(\n profileName: string,\n activeProvider: string | null,\n): Promise<HermesMemoryProviderSummary[]> {\n const activeProviderId = activeProvider ?? 'built-in'\n const knownProviders: HermesMemoryProviderSummary[] = await Promise.all(\n MEMORY_PROVIDER_CATALOG.map(async (provider) => {\n const configuration = await readProviderConfigurationStatus(\n profileName,\n provider.id,\n )\n return {\n ...provider,\n active: provider.id === activeProviderId,\n configured: configuration.configured,\n configurationIssue: configuration.issue,\n providerConfigPath: memoryProviderConfigPath(profileName, provider.id),\n settings: provider.configurable\n ? await readProviderSettings(profileName, provider.id)\n : [],\n }\n }),\n )\n const customProviders = await readCustomProviderSummaries(\n profileName,\n activeProviderId,\n )\n const providers = [...knownProviders, ...customProviders]\n if (\n activeProvider &&\n !providers.some((provider) => provider.id === activeProvider)\n ) {\n const providerId = normalizeCustomProviderId(activeProvider)\n providers.push({\n id: providerId,\n label: providerId,\n description:\n '当前启用的自定义 Hermes memory provider;这里可编辑 profile-local JSON 配置。',\n active: true,\n configurable: true,\n configured: await isUserMemoryProviderInstalled(profileName, providerId),\n configurationIssue: (await isUserMemoryProviderInstalled(\n profileName,\n providerId,\n ))\n ? null\n : '没有在当前 HERMES_HOME/plugins/ 下发现这个自定义 memory provider。',\n providerConfigPath: customProviderConfigPath(profileName, providerId),\n settings: await readCustomProviderSettings(profileName, providerId),\n })\n }\n providers.push(await readCustomProviderSetupSummary(profileName))\n return providers\n}\n\nasync function assertProviderCanBeActivated(\n profileName: string,\n provider: string,\n): Promise<void> {\n const status = await readProviderConfigurationStatus(profileName, provider)\n if (!status.configured) {\n throw new HermesMemoryError(\n 'memory_provider_not_configured',\n status.issue ?? `${provider} 尚未配置完整,不能设为当前 Provider。`,\n )\n }\n}\n\nasync function readProviderConfigurationStatus(\n profileName: string,\n provider: string,\n): Promise<{ configured: boolean; issue: string | null }> {\n if (provider === 'built-in') {\n return { configured: true, issue: null }\n }\n const env = await readHermesMemoryEnv(profileName)\n if (provider === 'honcho') {\n const config = await readJsonObject(\n memoryProviderConfigPath(profileName, 'honcho') ?? '',\n )\n return isConfiguredEnvValue(env.HONCHO_API_KEY) ||\n isConfiguredEnvValue(readString(config.apiKey)) ||\n isConfiguredEnvValue(readString(config.api_key)) ||\n isConfiguredEnvValue(readString(config.baseUrl))\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue:\n 'Honcho 需要先配置 HONCHO_API_KEY,或在 honcho.json 配置 self-hosted baseUrl。',\n }\n }\n if (provider === 'mem0') {\n const config = await readJsonObject(\n memoryProviderConfigPath(profileName, 'mem0') ?? '',\n )\n return isConfiguredEnvValue(env.MEM0_API_KEY) ||\n isConfiguredEnvValue(readString(config.api_key))\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue: 'Mem0 需要先在本机 Hermes .env 配置 MEM0_API_KEY。',\n }\n }\n if (provider === 'openviking') {\n return isConfiguredEnvValue(env.OPENVIKING_ENDPOINT)\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue:\n 'OpenViking 需要先配置 OPENVIKING_ENDPOINT,通常是 http://127.0.0.1:1933。',\n }\n }\n if (provider === 'supermemory') {\n return isConfiguredEnvValue(env.SUPERMEMORY_API_KEY)\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue:\n 'Supermemory 需要先在本机 Hermes .env 配置 SUPERMEMORY_API_KEY。',\n }\n }\n if (provider === 'holographic') {\n return { configured: true, issue: null }\n }\n if (provider === 'retaindb') {\n return isConfiguredEnvValue(env.RETAINDB_API_KEY)\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue: 'RetainDB 需要先在本机 Hermes .env 配置 RETAINDB_API_KEY。',\n }\n }\n if (provider === 'byterover') {\n return (await resolveByteRoverCli()) !== null\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue:\n 'ByteRover 需要先在本机安装 brv CLI,例如 npm install -g byterover-cli。',\n }\n }\n if (!knownMemoryProviderIds().has(provider as HermesKnownMemoryProviderId)) {\n return (await isUserMemoryProviderInstalled(profileName, provider))\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue:\n '没有在当前 HERMES_HOME/plugins/ 下发现这个自定义 memory provider。',\n }\n }\n const config = await readJsonObject(\n memoryProviderConfigPath(profileName, provider) ?? '',\n )\n const mode = normalizeHindsightMode(config.mode ?? env.HINDSIGHT_MODE)\n const apiKey =\n readString(config.apiKey) ??\n readString(config.api_key) ??\n env.HINDSIGHT_API_KEY\n if (mode === 'cloud') {\n return isConfiguredEnvValue(apiKey)\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue:\n 'Hindsight Cloud 需要先在本机 Hermes .env 配置 HINDSIGHT_API_KEY。',\n }\n }\n if (mode === 'local_external') {\n const apiUrl =\n readString(config.api_url) ??\n env.HINDSIGHT_API_URL ??\n HINDSIGHT_DEFAULT_LOCAL_URL\n return isConfiguredEnvValue(apiUrl)\n ? { configured: true, issue: null }\n : {\n configured: false,\n issue: 'Hindsight local_external 需要配置可访问的 API URL。',\n }\n }\n if (mode === 'local_embedded') {\n const llmProvider = readString(config.llm_provider) ?? 'openai'\n const llmModel = readString(config.llm_model)\n if (!llmModel) {\n return {\n configured: false,\n issue: 'Hindsight local_embedded 需要先配置 LLM 模型。',\n }\n }\n if (\n llmProvider === 'openai_compatible' &&\n !isConfiguredEnvValue(\n readString(config.llm_base_url) ?? env.HINDSIGHT_API_LLM_BASE_URL,\n )\n ) {\n return {\n configured: false,\n issue: 'Hindsight openai_compatible 需要先配置 LLM Base URL。',\n }\n }\n if (\n !['ollama', 'lmstudio', 'openai_compatible'].includes(llmProvider) &&\n !isConfiguredEnvValue(\n readString(config.llmApiKey) ??\n readString(config.llm_api_key) ??\n env.HINDSIGHT_LLM_API_KEY,\n )\n ) {\n return {\n configured: false,\n issue:\n 'Hindsight local_embedded 需要先在本机 Hermes .env 配置 HINDSIGHT_LLM_API_KEY。',\n }\n }\n return { configured: true, issue: null }\n }\n return {\n configured: false,\n issue: `Hindsight mode \"${mode}\" 暂不支持从 App 激活。`,\n }\n}\n\nasync function readHermesMemoryEnv(\n profileName: string,\n): Promise<Record<string, string>> {\n const values = await readHermesEnvFile(profileName)\n for (const key of [\n 'HONCHO_API_KEY',\n 'MEM0_API_KEY',\n 'HINDSIGHT_API_KEY',\n 'HINDSIGHT_API_URL',\n 'HINDSIGHT_MODE',\n 'HINDSIGHT_LLM_API_KEY',\n 'HINDSIGHT_API_LLM_BASE_URL',\n 'SUPERMEMORY_API_KEY',\n 'OPENVIKING_ENDPOINT',\n 'OPENVIKING_API_KEY',\n 'OPENVIKING_ACCOUNT',\n 'OPENVIKING_USER',\n 'OPENVIKING_AGENT',\n 'RETAINDB_API_KEY',\n 'RETAINDB_BASE_URL',\n 'RETAINDB_PROJECT',\n 'BRV_API_KEY',\n ]) {\n const value = process.env[key]\n if (typeof value === 'string' && value.trim()) {\n values[key] = value\n }\n }\n return values\n}\n\nfunction isConfiguredEnvValue(value: string | null | undefined): boolean {\n return typeof value === 'string' && value.trim().length > 0\n}\n\nasync function readProviderSettings(\n profileName: string,\n provider: HermesKnownMemoryProviderId,\n): Promise<HermesMemoryProviderSetting[]> {\n if (provider === 'honcho') {\n const config = await readJsonObject(\n memoryProviderConfigPath(profileName, provider) ?? '',\n )\n return [\n stringSetting('baseUrl', 'Base URL', config.baseUrl ?? ''),\n stringSetting('workspace', 'Workspace', config.workspace ?? 'hermes'),\n stringSetting('peerName', '用户 Peer', config.peerName ?? ''),\n stringSetting('aiPeer', 'AI Peer', config.aiPeer ?? 'hermes'),\n selectSetting('recallMode', '召回模式', config.recallMode ?? 'hybrid', [\n 'hybrid',\n 'context',\n 'tools',\n ]),\n selectSetting(\n 'writeFrequency',\n '写入频率',\n config.writeFrequency ?? 'async',\n ['async', 'turn', 'session'],\n ),\n booleanSetting('saveMessages', '保存消息', config.saveMessages ?? true),\n selectSetting(\n 'sessionStrategy',\n '会话策略',\n config.sessionStrategy ?? 'per-directory',\n ['per-directory', 'per-repo', 'per-session', 'global'],\n ),\n numberSetting('contextTokens', '上下文 token 预算', config.contextTokens),\n numberSetting('contextCadence', 'Context 刷新间隔', config.contextCadence ?? 1),\n numberSetting(\n 'dialecticCadence',\n 'Dialectic 刷新间隔',\n config.dialecticCadence ?? 2,\n ),\n numberSetting('dialecticDepth', 'Dialectic 深度', config.dialecticDepth ?? 1),\n ]\n }\n if (provider === 'mem0') {\n const config = await readJsonObject(\n memoryProviderConfigPath(profileName, provider) ?? '',\n )\n return [\n stringSetting('userId', 'User ID', config.user_id ?? 'hermes-user'),\n stringSetting('agentId', 'Agent ID', config.agent_id ?? 'hermes'),\n booleanSetting('rerank', '启用 rerank', config.rerank ?? true),\n ]\n }\n if (provider === 'openviking') {\n const env = await readHermesMemoryEnv(profileName)\n return [\n stringSetting(\n 'endpoint',\n 'Endpoint',\n env.OPENVIKING_ENDPOINT ?? OPENVIKING_DEFAULT_ENDPOINT,\n ),\n stringSetting('account', 'Account', env.OPENVIKING_ACCOUNT ?? 'default'),\n stringSetting('user', 'User', env.OPENVIKING_USER ?? 'default'),\n stringSetting('agent', 'Agent', env.OPENVIKING_AGENT ?? 'hermes'),\n ]\n }\n if (provider === 'supermemory') {\n const config = await readJsonObject(\n memoryProviderConfigPath(profileName, provider) ?? '',\n )\n return [\n stringSetting('containerTag', '容器标签', config.container_tag ?? 'hermes'),\n booleanSetting('autoRecall', '自动回忆', config.auto_recall ?? true),\n booleanSetting('autoCapture', '自动捕获', config.auto_capture ?? true),\n numberSetting(\n 'maxRecallResults',\n '最大召回条数',\n config.max_recall_results ?? 10,\n ),\n numberSetting(\n 'profileFrequency',\n 'Profile 注入频率',\n config.profile_frequency ?? 50,\n ),\n selectSetting('captureMode', '捕获模式', config.capture_mode ?? 'all', [\n 'all',\n 'everything',\n ]),\n selectSetting(\n 'searchMode',\n '搜索模式',\n config.search_mode ?? 'hybrid',\n ['hybrid', 'memories', 'documents'],\n ),\n ]\n }\n if (provider === 'hindsight') {\n const config = await readJsonObject(\n memoryProviderConfigPath(profileName, provider) ?? '',\n )\n const banks = toRecord(config.banks)\n const hermesBank = toRecord(banks.hermes)\n const mode = normalizeHindsightMode(config.mode)\n return [\n selectSetting('mode', '连接模式', mode, [\n 'cloud',\n 'local_embedded',\n 'local_external',\n ]),\n stringSetting(\n 'apiUrl',\n 'API URL',\n config.api_url ??\n (mode === 'cloud'\n ? HINDSIGHT_DEFAULT_API_URL\n : HINDSIGHT_DEFAULT_LOCAL_URL),\n ),\n stringSetting(\n 'bankId',\n 'Memory Bank',\n config.bank_id ?? hermesBank.bankId ?? 'hermes',\n ),\n selectSetting(\n 'llmProvider',\n '本地 LLM Provider',\n config.llm_provider ?? 'openai',\n HINDSIGHT_LLM_PROVIDERS,\n ),\n stringSetting('llmModel', '本地 LLM 模型', config.llm_model ?? ''),\n stringSetting(\n 'llmBaseUrl',\n '本地 LLM Base URL',\n config.llm_base_url ?? '',\n ),\n booleanSetting('autoRecall', '自动回忆', config.auto_recall ?? true),\n booleanSetting('autoRetain', '自动沉淀', config.auto_retain ?? true),\n selectSetting(\n 'memoryMode',\n '注入模式',\n config.memory_mode ?? 'hybrid',\n ['hybrid', 'context', 'tools'],\n ),\n selectSetting(\n 'recallBudget',\n '召回强度',\n config.recall_budget ?? config.budget ?? hermesBank.budget ?? 'mid',\n ['low', 'mid', 'high'],\n ),\n ]\n }\n if (provider === 'holographic') {\n const config = await readHolographicProviderConfig(profileName)\n return [\n stringSetting(\n 'dbPath',\n 'SQLite 数据库路径',\n config.db_path ??\n path.join(resolveHermesProfileDir(profileName), 'memory_store.db'),\n ),\n booleanSetting('autoExtract', '会话结束自动抽取', config.auto_extract ?? false),\n numberSetting('defaultTrust', '默认信任分', config.default_trust ?? 0.5),\n numberSetting('hrrDim', 'HRR 维度', config.hrr_dim ?? 1024),\n ]\n }\n if (provider === 'retaindb') {\n const env = await readHermesMemoryEnv(profileName)\n return [\n stringSetting(\n 'baseUrl',\n 'Base URL',\n env.RETAINDB_BASE_URL ?? RETAINDB_DEFAULT_BASE_URL,\n ),\n stringSetting('project', 'Project', env.RETAINDB_PROJECT ?? ''),\n ]\n }\n if (provider === 'byterover') {\n return [\n stringSetting(\n 'workingDirectory',\n '工作目录',\n path.join(resolveHermesProfileDir(profileName), 'byterover'),\n false,\n ),\n ]\n }\n return []\n}\n\nfunction memoryProviderConfigPath(\n profileName: string,\n provider: string,\n): string | null {\n if (provider === 'honcho') {\n return path.join(resolveHermesProfileDir(profileName), 'honcho.json')\n }\n if (provider === 'mem0') {\n return path.join(resolveHermesProfileDir(profileName), 'mem0.json')\n }\n if (provider === 'supermemory') {\n return path.join(resolveHermesProfileDir(profileName), 'supermemory.json')\n }\n if (provider === 'hindsight') {\n return path.join(\n resolveHermesProfileDir(profileName),\n 'hindsight',\n 'config.json',\n )\n }\n return null\n}\n\nfunction customProviderConfigPath(profileName: string, provider: string): string {\n return path.join(\n resolveHermesProfileDir(profileName),\n `${normalizeCustomProviderId(provider)}.json`,\n )\n}\n\nfunction customProviderRegistryPath(profileName: string): string {\n return path.join(\n resolveHermesProfileDir(profileName),\n CUSTOM_PROVIDER_REGISTRY_FILE,\n )\n}\n\nasync function readCustomProviderRegistry(\n profileName: string,\n): Promise<CustomMemoryProviderDescriptor[]> {\n const raw = await readFile(customProviderRegistryPath(profileName), 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n if (!raw.trim()) {\n return []\n }\n try {\n const parsed = JSON.parse(raw) as unknown\n const providers = Array.isArray(parsed)\n ? parsed\n : Array.isArray(toRecord(parsed).providers)\n ? (toRecord(parsed).providers as unknown[])\n : []\n return providers\n .map((item) => {\n if (typeof item === 'string') {\n const id = normalizeCustomProviderId(item)\n return { id, label: id, description: '自定义 memory provider。' }\n }\n const record = toRecord(item)\n const id = normalizeCustomProviderId(readString(record.id) ?? '')\n return {\n id,\n label: readString(record.label) ?? id,\n description:\n readString(record.description) ?? '自定义 memory provider。',\n }\n })\n .filter((item) => item.id)\n } catch {\n return []\n }\n}\n\nasync function saveCustomProviderRegistryEntry(\n profileName: string,\n provider: string,\n): Promise<void> {\n const providerId = normalizeCustomProviderId(provider)\n const current = await readCustomProviderRegistry(profileName)\n const providers = [\n ...current.filter((item) => item.id !== providerId),\n { id: providerId, label: providerId, description: '自定义 memory provider。' },\n ].sort((left, right) => left.id.localeCompare(right.id))\n const registryPath = customProviderRegistryPath(profileName)\n await mkdir(path.dirname(registryPath), { recursive: true, mode: 0o700 })\n await writeFile(\n registryPath,\n `${JSON.stringify({ providers }, null, 2)}\\n`,\n { encoding: 'utf8', mode: 0o600 },\n )\n}\n\nasync function discoverUserMemoryProviderDescriptors(\n profileName: string,\n): Promise<CustomMemoryProviderDescriptor[]> {\n const pluginsDir = path.join(resolveHermesProfileDir(profileName), 'plugins')\n const entries = await readdir(pluginsDir, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n },\n )\n const descriptors: CustomMemoryProviderDescriptor[] = []\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith('.')) {\n continue\n }\n let providerId: string\n try {\n providerId = normalizeCustomProviderId(entry.name)\n } catch {\n continue\n }\n const providerDir = path.join(pluginsDir, entry.name)\n if (!(await isMemoryProviderPluginDir(providerDir))) {\n continue\n }\n const meta = await readPluginMetadata(providerDir)\n descriptors.push({\n id: providerId,\n label: readString(meta.name) ?? providerId,\n description: readString(meta.description) ?? '自定义 memory provider。',\n })\n }\n return descriptors\n}\n\nasync function isUserMemoryProviderInstalled(\n profileName: string,\n provider: string,\n): Promise<boolean> {\n const providerDir = path.join(\n resolveHermesProfileDir(profileName),\n 'plugins',\n normalizeCustomProviderId(provider),\n )\n return isMemoryProviderPluginDir(providerDir)\n}\n\nasync function isMemoryProviderPluginDir(providerDir: string): Promise<boolean> {\n const source = await readFile(path.join(providerDir, '__init__.py'), 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n const sample = source.slice(0, 8192)\n return (\n sample.includes('register_memory_provider') ||\n sample.includes('MemoryProvider')\n )\n}\n\nasync function readPluginMetadata(\n providerDir: string,\n): Promise<Record<string, unknown>> {\n const raw = await readFile(path.join(providerDir, 'plugin.yaml'), 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n return raw ? toRecord(YAML.parse(raw)) : {}\n}\n\nasync function resolveByteRoverCli(): Promise<string | null> {\n const candidates = [\n ...((process.env.PATH ?? '')\n .split(path.delimiter)\n .filter(Boolean)\n .map((dir) => path.join(dir, 'brv'))),\n path.join(process.env.HOME ?? '', '.brv-cli', 'bin', 'brv'),\n '/usr/local/bin/brv',\n path.join(process.env.HOME ?? '', '.npm-global', 'bin', 'brv'),\n ].filter(Boolean)\n for (const candidate of candidates) {\n const found = await access(candidate)\n .then(() => true)\n .catch(() => false)\n if (found) {\n return candidate\n }\n }\n return null\n}\n\nasync function readHolographicProviderConfig(\n profileName: string,\n): Promise<Record<string, unknown>> {\n const raw = await readFile(resolveHermesConfigPath(profileName), 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n const config = raw ? toRecord(YAML.parse(raw)) : {}\n const plugins = toRecord(config.plugins)\n return toRecord(plugins['hermes-memory-store'])\n}\n\nasync function patchHolographicProviderConfig(\n profileName: string,\n patch: Record<string, boolean | number | string | undefined>,\n): Promise<void> {\n const configPath = resolveHermesConfigPath(profileName)\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n const document = existingRaw\n ? YAML.parseDocument(existingRaw)\n : new YAML.Document({})\n const config = toRecord(document.toJSON())\n const plugins = toRecord(config.plugins)\n const memoryStore = toRecord(plugins['hermes-memory-store'])\n for (const [key, value] of Object.entries(patch)) {\n if (value !== undefined) {\n memoryStore[key] = value\n }\n }\n plugins['hermes-memory-store'] = memoryStore\n config.plugins = plugins\n await mkdir(path.dirname(configPath), { recursive: true, mode: 0o700 })\n if (existingRaw) {\n await copyFile(configPath, `${configPath}.bak.${Date.now()}`)\n }\n document.contents = document.createNode(config)\n const tempPath = `${configPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, document.toString(), {\n encoding: 'utf8',\n mode: 0o600,\n })\n await rename(tempPath, configPath)\n}\n\nasync function patchHermesMemoryEnv(\n profileName: string,\n patch: Record<string, string | undefined>,\n): Promise<void> {\n const entries = Object.entries(patch).filter(\n (entry): entry is [string, string] => entry[1] !== undefined,\n )\n if (entries.length === 0) {\n return\n }\n const envPath = path.join(resolveHermesProfileDir(profileName), '.env')\n const existingRaw = await readFile(envPath, 'utf8').catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n const lines = existingRaw ? existingRaw.split(/\\r?\\n/u) : []\n const nextLines = [...lines]\n for (const [key, value] of entries) {\n if (!isMemoryEnvKeyWritable(key)) {\n throw new HermesMemoryError(\n 'memory_provider_env_forbidden',\n `不允许从 App 写入 ${key}。`,\n )\n }\n const keyPattern = new RegExp(`^(?:export\\\\s+)?${escapeRegExp(key)}=`, 'u')\n let replaced = false\n for (let index = 0; index < nextLines.length; index += 1) {\n if (keyPattern.test(nextLines[index].trim())) {\n nextLines[index] = `${key}=${formatEnvValue(value.trim())}`\n replaced = true\n }\n }\n if (!replaced) {\n if (nextLines.length > 0 && nextLines.at(-1) !== '') {\n nextLines.push('')\n }\n nextLines.push(`${key}=${formatEnvValue(value.trim())}`)\n }\n }\n const nextRaw = nextLines.join('\\n').replace(/\\n*$/u, '\\n')\n await mkdir(path.dirname(envPath), { recursive: true, mode: 0o700 })\n if (existingRaw) {\n await copyFile(envPath, `${envPath}.bak.${Date.now()}`)\n }\n const tempPath = `${envPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, nextRaw, { encoding: 'utf8', mode: 0o600 })\n await rename(tempPath, envPath)\n}\n\nfunction isMemoryEnvKeyWritable(key: string): boolean {\n return [\n 'OPENVIKING_ENDPOINT',\n 'OPENVIKING_ACCOUNT',\n 'OPENVIKING_USER',\n 'OPENVIKING_AGENT',\n 'RETAINDB_BASE_URL',\n 'RETAINDB_PROJECT',\n ].includes(key)\n}\n\nfunction normalizeHindsightMode(value: unknown): string {\n const mode = readString(value) ?? 'cloud'\n return mode === 'local' ? 'local_embedded' : mode\n}\n\nasync function readActiveMemoryProvider(\n profileName: string,\n): Promise<string | null> {\n const raw = await readFile(\n resolveHermesConfigPath(profileName),\n 'utf8',\n ).catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n const config = raw ? toRecord(YAML.parse(raw)) : {}\n const memory = toRecord(config.memory)\n const provider = readString(memory.provider)\n if (\n !provider ||\n provider === 'built-in' ||\n provider === 'builtin' ||\n provider === 'built_in'\n ) {\n return null\n }\n return provider\n}\n\nasync function patchJsonProviderConfig(\n profileName: string,\n relativePath: string,\n patch: Record<string, boolean | number | string | undefined>,\n): Promise<void> {\n const configPath = path.join(\n resolveHermesProfileDir(profileName),\n relativePath,\n )\n const current = await readJsonObject(configPath)\n const next: Record<string, unknown> = { ...current }\n for (const [key, value] of Object.entries(patch)) {\n if (value !== undefined) {\n next[key] = value\n }\n }\n await mkdir(path.dirname(configPath), { recursive: true, mode: 0o700 })\n await writeFile(configPath, `${JSON.stringify(next, null, 2)}\\n`, {\n encoding: 'utf8',\n mode: 0o600,\n })\n}\n\nasync function readJsonObject(\n filePath: string,\n): Promise<Record<string, unknown>> {\n const raw = await readFile(filePath, 'utf8').catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return '{}'\n }\n throw error\n })\n try {\n return toRecord(JSON.parse(raw || '{}'))\n } catch {\n throw new HermesMemoryError(\n 'memory_provider_config_invalid',\n `${path.basename(filePath)} 不是有效的 JSON 配置文件。`,\n )\n }\n}\n\nfunction booleanSetting(\n key: string,\n label: string,\n value: unknown,\n): HermesMemoryProviderSetting {\n return {\n key,\n label,\n value: readBoolean(value) ?? false,\n editable: true,\n kind: 'boolean',\n }\n}\n\nfunction numberSetting(\n key: string,\n label: string,\n value: unknown,\n): HermesMemoryProviderSetting {\n const numberValue =\n typeof value === 'number' && Number.isFinite(value) ? value : null\n return { key, label, value: numberValue, editable: true, kind: 'number' }\n}\n\nfunction stringSetting(\n key: string,\n label: string,\n value: unknown,\n editable = true,\n): HermesMemoryProviderSetting {\n return {\n key,\n label,\n value: readString(value) ?? '',\n editable,\n kind: 'string',\n }\n}\n\nfunction textSetting(\n key: string,\n label: string,\n value: unknown,\n editable = true,\n): HermesMemoryProviderSetting {\n return {\n key,\n label,\n value: typeof value === 'string' ? value : '',\n editable,\n kind: 'text',\n }\n}\n\nfunction selectSetting(\n key: string,\n label: string,\n value: unknown,\n options: string[],\n editable = true,\n): HermesMemoryProviderSetting {\n const stringValue = readString(value) ?? options[0] ?? null\n return { key, label, value: stringValue, editable, kind: 'select', options }\n}\n\nfunction assertWithinLimit(\n target: HermesMemoryTarget,\n entries: string[],\n): void {\n const limit = target === 'user' ? USER_LIMIT : MEMORY_LIMIT\n const chars = entries.length ? entries.join(ENTRY_DELIMITER).length : 0\n if (chars > limit) {\n throw new HermesMemoryError(\n 'memory_limit_exceeded',\n `记忆内容超过 ${limit} 字符上限,请先缩短或删除部分条目。`,\n )\n }\n}\n\nfunction findSingleMatch(entries: string[], needle: string): number {\n const matches = entries\n .map((entry, index) => ({ entry, index }))\n .filter(({ entry }) => entry.includes(needle))\n if (matches.length === 0) {\n throw new HermesMemoryError(\n 'memory_entry_not_found',\n '没有找到匹配的记忆条目。',\n )\n }\n if (new Set(matches.map(({ entry }) => entry)).size > 1) {\n throw new HermesMemoryError(\n 'memory_entry_ambiguous',\n '有多条记忆匹配这个片段,请输入更具体的内容后再试。',\n )\n }\n return matches[0].index\n}\n\nfunction normalizeEntryContent(content: string): string {\n const normalized = content.trim()\n if (!normalized) {\n throw new HermesMemoryError('memory_content_empty', '记忆内容不能为空。')\n }\n return normalized\n}\n\nfunction normalizeNeedle(value: string): string {\n const normalized = value.trim()\n if (!normalized) {\n throw new HermesMemoryError('memory_match_empty', '匹配内容不能为空。')\n }\n return normalized\n}\n\nfunction hashString(value: string): string {\n let hash = 0\n for (let index = 0; index < value.length; index += 1) {\n hash = (hash * 31 + value.charCodeAt(index)) >>> 0\n }\n return hash.toString(16)\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction readBoolean(value: unknown): boolean | undefined {\n if (typeof value === 'boolean') {\n return value\n }\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase()\n if (['1', 'true', 'yes', 'on'].includes(normalized)) {\n return true\n }\n if (['0', 'false', 'no', 'off'].includes(normalized)) {\n return false\n }\n }\n return undefined\n}\n\nfunction formatEnvValue(value: string): string {\n return /^[A-Za-z0-9_./:@-]*$/u.test(value)\n ? value\n : JSON.stringify(value)\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&')\n}\n\nfunction isNodeError(\n error: unknown,\n code: string,\n): error is NodeJS.ErrnoException {\n return (\n error instanceof Error &&\n 'code' in error &&\n (error as NodeJS.ErrnoException).code === code\n )\n}\n","import type Router from '@koa/router'\nimport {\n addHermesMemoryEntry,\n HermesMemoryError,\n readHermesProfileMemory,\n removeHermesMemoryEntry,\n replaceHermesMemoryEntry,\n resetHermesMemoryStore,\n saveHermesMemoryProviderSettings,\n saveHermesMemorySettings,\n setHermesMemoryProvider,\n type HermesMemorySettingsPatch,\n type HermesMemoryTarget,\n} from '../../hermes/memory.js'\nimport { getHermesProfileStatus } from '../../hermes/profiles.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { isLinkHttpError, LinkHttpError } from '../errors.js'\nimport {\n readBoolean,\n readJsonBody,\n readPositiveInteger,\n readString,\n} from '../request.js'\n\nexport function registerProfileMemoryRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n },\n): void {\n const { paths } = options\n\n router.get('/api/v1/profiles/:name/memory', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n await getHermesProfileStatus(ctx.params.name, paths)\n ctx.body = await readHermesProfileMemory(ctx.params.name)\n })\n\n router.post('/api/v1/profiles/:name/memory/entries', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = await addHermesMemoryEntry(\n ctx.params.name,\n readMemoryTarget(body),\n readRequiredMemoryContent(body),\n )\n } catch (error) {\n throw toMemoryHttpError(error)\n }\n })\n\n router.patch('/api/v1/profiles/:name/memory/entries', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = await replaceHermesMemoryEntry(\n ctx.params.name,\n readMemoryTarget(body),\n readRequiredMemoryMatch(body),\n readRequiredMemoryContent(body),\n )\n } catch (error) {\n throw toMemoryHttpError(error)\n }\n })\n\n router.delete('/api/v1/profiles/:name/memory/entries', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = await removeHermesMemoryEntry(\n ctx.params.name,\n readMemoryTarget(body),\n readRequiredMemoryMatch(body),\n )\n } catch (error) {\n throw toMemoryHttpError(error)\n }\n })\n\n router.delete('/api/v1/profiles/:name/memory', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = await resetHermesMemoryStore(\n ctx.params.name,\n readMemoryResetTarget(body),\n )\n } catch (error) {\n throw toMemoryHttpError(error)\n }\n })\n\n router.patch('/api/v1/profiles/:name/memory/settings', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = await saveHermesMemorySettings(\n ctx.params.name,\n readMemorySettingsPatch(body),\n )\n } catch (error) {\n throw toMemoryHttpError(error)\n }\n })\n\n router.patch('/api/v1/profiles/:name/memory/provider', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = await setHermesMemoryProvider(\n ctx.params.name,\n readRequiredMemoryProvider(body),\n )\n } catch (error) {\n throw toMemoryHttpError(error)\n }\n })\n\n router.patch(\n '/api/v1/profiles/:name/memory/providers/:provider/settings',\n async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n await getHermesProfileStatus(ctx.params.name, paths)\n try {\n ctx.body = await saveHermesMemoryProviderSettings(\n ctx.params.name,\n ctx.params.provider,\n readMemorySettingsPatch(body),\n )\n } catch (error) {\n throw toMemoryHttpError(error)\n }\n },\n )\n}\n\nfunction readMemoryTarget(body: Record<string, unknown>): HermesMemoryTarget {\n const raw = readString(body, 'target')\n if (raw === 'memory' || raw === 'user') {\n return raw\n }\n throw new LinkHttpError(\n 400,\n 'memory_target_invalid',\n 'target must be \"memory\" or \"user\"',\n )\n}\n\nfunction readMemoryResetTarget(\n body: Record<string, unknown>,\n): HermesMemoryTarget | 'all' {\n const raw = readString(body, 'target') ?? 'all'\n if (raw === 'all' || raw === 'memory' || raw === 'user') {\n return raw\n }\n throw new LinkHttpError(\n 400,\n 'memory_target_invalid',\n 'target must be \"all\", \"memory\", or \"user\"',\n )\n}\n\nfunction readRequiredMemoryContent(body: Record<string, unknown>): string {\n const content = readString(body, 'content') ?? readString(body, 'text')\n if (!content) {\n throw new LinkHttpError(\n 400,\n 'memory_content_required',\n 'content is required',\n )\n }\n return content\n}\n\nfunction readRequiredMemoryMatch(body: Record<string, unknown>): string {\n const oldText =\n readString(body, 'old_text') ??\n readString(body, 'oldText') ??\n readString(body, 'match')\n if (!oldText) {\n throw new LinkHttpError(\n 400,\n 'memory_match_required',\n 'old_text is required',\n )\n }\n return oldText\n}\n\nfunction readRequiredMemoryProvider(body: Record<string, unknown>): string {\n const provider =\n readString(body, 'provider') ??\n readString(body, 'provider_id') ??\n readString(body, 'providerId')\n if (!provider) {\n throw new LinkHttpError(\n 400,\n 'memory_provider_required',\n 'provider is required',\n )\n }\n return provider\n}\n\nfunction readMemorySettingsPatch(\n body: Record<string, unknown>,\n): HermesMemorySettingsPatch {\n const input: HermesMemorySettingsPatch = {}\n const mode = readString(body, 'mode')\n if (mode) {\n input.mode = mode\n }\n const apiUrl = readOptionalString(body, 'api_url', 'apiUrl')\n if (apiUrl !== undefined) {\n input.apiUrl = apiUrl\n }\n const bankId = readOptionalString(body, 'bank_id', 'bankId')\n if (bankId !== undefined) {\n input.bankId = bankId\n }\n const llmProvider =\n readString(body, 'llm_provider') ?? readString(body, 'llmProvider')\n if (llmProvider) {\n input.llmProvider = llmProvider\n }\n const llmModel = readOptionalString(body, 'llm_model', 'llmModel')\n if (llmModel !== undefined) {\n input.llmModel = llmModel\n }\n const llmBaseUrl = readOptionalString(body, 'llm_base_url', 'llmBaseUrl')\n if (llmBaseUrl !== undefined) {\n input.llmBaseUrl = llmBaseUrl\n }\n const containerTag = readOptionalString(body, 'container_tag', 'containerTag')\n if (containerTag !== undefined) {\n input.containerTag = containerTag\n }\n const autoRecall = readBoolean(body.auto_recall ?? body.autoRecall)\n if (autoRecall !== undefined) {\n input.autoRecall = autoRecall\n }\n const autoCapture = readBoolean(body.auto_capture ?? body.autoCapture)\n if (autoCapture !== undefined) {\n input.autoCapture = autoCapture\n }\n const autoRetain = readBoolean(body.auto_retain ?? body.autoRetain)\n if (autoRetain !== undefined) {\n input.autoRetain = autoRetain\n }\n const memoryMode =\n readString(body, 'memory_mode') ?? readString(body, 'memoryMode')\n if (memoryMode) {\n input.memoryMode = memoryMode\n }\n const recallBudget =\n readString(body, 'recall_budget') ?? readString(body, 'recallBudget')\n if (recallBudget) {\n input.recallBudget = recallBudget\n }\n const maxRecallResults = readPositiveInteger(\n body.max_recall_results ?? body.maxRecallResults,\n )\n if (maxRecallResults !== undefined) {\n input.maxRecallResults = maxRecallResults\n }\n const profileFrequency = readPositiveInteger(\n body.profile_frequency ?? body.profileFrequency,\n )\n if (profileFrequency !== undefined) {\n input.profileFrequency = profileFrequency\n }\n const captureMode =\n readString(body, 'capture_mode') ?? readString(body, 'captureMode')\n if (captureMode) {\n input.captureMode = captureMode\n }\n const searchMode =\n readString(body, 'search_mode') ?? readString(body, 'searchMode')\n if (searchMode) {\n input.searchMode = searchMode\n }\n const providerId = readOptionalString(\n body,\n 'provider_id',\n 'providerId',\n 'custom_provider_id',\n 'customProviderId',\n )\n if (providerId !== undefined) {\n input.providerId = providerId\n }\n const configJson = readOptionalString(body, 'config_json', 'configJson')\n if (configJson !== undefined) {\n input.configJson = configJson\n }\n const baseUrl = readOptionalString(body, 'base_url', 'baseUrl')\n if (baseUrl !== undefined) {\n input.baseUrl = baseUrl\n }\n const workspace = readOptionalString(body, 'workspace')\n if (workspace !== undefined) {\n input.workspace = workspace\n }\n const peerName = readOptionalString(body, 'peer_name', 'peerName')\n if (peerName !== undefined) {\n input.peerName = peerName\n }\n const aiPeer = readOptionalString(body, 'ai_peer', 'aiPeer')\n if (aiPeer !== undefined) {\n input.aiPeer = aiPeer\n }\n const recallMode =\n readString(body, 'recall_mode') ?? readString(body, 'recallMode')\n if (recallMode) {\n input.recallMode = recallMode\n }\n const writeFrequency =\n readString(body, 'write_frequency') ?? readString(body, 'writeFrequency')\n if (writeFrequency) {\n input.writeFrequency = writeFrequency\n }\n const saveMessages = readBoolean(body.save_messages ?? body.saveMessages)\n if (saveMessages !== undefined) {\n input.saveMessages = saveMessages\n }\n const sessionStrategy =\n readString(body, 'session_strategy') ?? readString(body, 'sessionStrategy')\n if (sessionStrategy) {\n input.sessionStrategy = sessionStrategy\n }\n const contextTokens = readPositiveInteger(\n body.context_tokens ?? body.contextTokens,\n )\n if (contextTokens !== undefined) {\n input.contextTokens = contextTokens\n }\n const contextCadence = readPositiveInteger(\n body.context_cadence ?? body.contextCadence,\n )\n if (contextCadence !== undefined) {\n input.contextCadence = contextCadence\n }\n const dialecticCadence = readPositiveInteger(\n body.dialectic_cadence ?? body.dialecticCadence,\n )\n if (dialecticCadence !== undefined) {\n input.dialecticCadence = dialecticCadence\n }\n const dialecticDepth = readPositiveInteger(\n body.dialectic_depth ?? body.dialecticDepth,\n )\n if (dialecticDepth !== undefined) {\n input.dialecticDepth = dialecticDepth\n }\n const userId = readOptionalString(body, 'user_id', 'userId')\n if (userId !== undefined) {\n input.userId = userId\n }\n const agentId = readOptionalString(body, 'agent_id', 'agentId')\n if (agentId !== undefined) {\n input.agentId = agentId\n }\n const rerank = readBoolean(body.rerank)\n if (rerank !== undefined) {\n input.rerank = rerank\n }\n const endpoint = readOptionalString(body, 'endpoint')\n if (endpoint !== undefined) {\n input.endpoint = endpoint\n }\n const account = readOptionalString(body, 'account')\n if (account !== undefined) {\n input.account = account\n }\n const user = readOptionalString(body, 'user')\n if (user !== undefined) {\n input.user = user\n }\n const agent = readOptionalString(body, 'agent')\n if (agent !== undefined) {\n input.agent = agent\n }\n const dbPath = readOptionalString(body, 'db_path', 'dbPath')\n if (dbPath !== undefined) {\n input.dbPath = dbPath\n }\n const autoExtract = readBoolean(body.auto_extract ?? body.autoExtract)\n if (autoExtract !== undefined) {\n input.autoExtract = autoExtract\n }\n const defaultTrust = readOptionalNumber(\n body.default_trust ?? body.defaultTrust,\n 'default_trust',\n )\n if (defaultTrust !== undefined) {\n input.defaultTrust = defaultTrust\n }\n const hrrDim = readPositiveInteger(body.hrr_dim ?? body.hrrDim)\n if (hrrDim !== undefined) {\n input.hrrDim = hrrDim\n }\n const project = readOptionalString(body, 'project')\n if (project !== undefined) {\n input.project = project\n }\n if (Object.keys(input).length === 0) {\n throw new LinkHttpError(\n 400,\n 'memory_settings_empty',\n 'No supported memory settings were provided',\n )\n }\n return input\n}\n\nfunction readOptionalNumber(value: unknown, key: string): number | undefined {\n if (value === undefined) {\n return undefined\n }\n const numberValue =\n typeof value === 'number'\n ? value\n : typeof value === 'string'\n ? Number(value.trim())\n : NaN\n if (!Number.isFinite(numberValue)) {\n throw new LinkHttpError(400, 'memory_settings_invalid', `${key} must be a number`)\n }\n return numberValue\n}\n\nfunction readOptionalString(\n body: Record<string, unknown>,\n ...keys: string[]\n): string | undefined {\n for (const key of keys) {\n if (Object.prototype.hasOwnProperty.call(body, key)) {\n const value = body[key]\n if (typeof value !== 'string') {\n throw new LinkHttpError(\n 400,\n 'memory_settings_invalid',\n `${key} must be a string`,\n )\n }\n return value.trim()\n }\n }\n return undefined\n}\n\nfunction toMemoryHttpError(error: unknown): LinkHttpError {\n if (error instanceof HermesMemoryError) {\n return new LinkHttpError(400, error.code, error.message)\n }\n if (isLinkHttpError(error)) {\n return error\n }\n if (error instanceof Error) {\n return new LinkHttpError(400, 'memory_update_failed', error.message)\n }\n return new LinkHttpError(400, 'memory_update_failed', 'Memory update failed')\n}\n","import {\n copyFile,\n mkdir,\n readFile,\n readdir,\n rename,\n writeFile,\n} from 'node:fs/promises'\nimport path from 'node:path'\nimport YAML from 'yaml'\nimport { type RuntimePaths, resolveRuntimePaths } from '../runtime/paths.js'\nimport {\n resolveHermesConfigPath,\n resolveHermesProfileDir,\n} from './config.js'\nimport { getHermesProfileStatus, type HermesProfile } from './profiles.js'\n\nexport interface HermesProfileSkill {\n name: string\n category: string | null\n description: string\n enabled: boolean\n source: string\n trust: string | null\n relativePath: string\n}\n\nexport interface HermesProfileSkillCategory {\n name: string | null\n label: string\n total: number\n enabled: number\n disabled: number\n}\n\nexport interface HermesProfileSkillListResult {\n ok: true\n profile: HermesProfile\n skills: HermesProfileSkill[]\n categories: HermesProfileSkillCategory[]\n}\n\nexport interface HermesProfileSkillUpdateResult\n extends HermesProfileSkillListResult {\n skill: HermesProfileSkill\n backupPath: string | null\n}\n\nexport class HermesSkillNotFoundError extends Error {\n constructor(skillName: string) {\n super(`skill \"${skillName}\" does not exist`)\n this.name = 'HermesSkillNotFoundError'\n }\n}\n\nconst MAX_SKILL_NAME_LENGTH = 64\nconst MAX_DESCRIPTION_LENGTH = 1024\nconst EXCLUDED_SKILL_DIRS = new Set(['.git', '.github', '.hub'])\ntype HermesYamlDocument = ReturnType<typeof YAML.parseDocument>\n\nexport async function listHermesProfileSkills(\n profileName: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfileSkillListResult> {\n const profile = await readExistingProfile(profileName, paths)\n const profileDir = resolveHermesProfileDir(profile.name)\n const skillsRoot = path.join(profileDir, 'skills')\n const [skillFiles, disabled, provenance] = await Promise.all([\n findSkillFiles(skillsRoot),\n readDisabledSkillNames(resolveHermesConfigPath(profile.name)),\n readSkillProvenance(skillsRoot),\n ])\n const seenNames = new Set<string>()\n const skills: HermesProfileSkill[] = []\n for (const skillFile of skillFiles) {\n const skill = await readSkillMetadata({\n skillFile,\n skillsRoot,\n disabled,\n provenance,\n })\n if (!skill || seenNames.has(skill.name)) {\n continue\n }\n seenNames.add(skill.name)\n skills.push(skill)\n }\n skills.sort(compareSkills)\n return {\n ok: true,\n profile,\n skills,\n categories: summarizeCategories(skills),\n }\n}\n\nexport async function setHermesProfileSkillEnabled(\n profileName: string,\n skillName: string,\n enabled: boolean,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<HermesProfileSkillUpdateResult> {\n const current = await listHermesProfileSkills(profileName, paths)\n const target = current.skills.find((skill) => skill.name === skillName)\n if (!target) {\n throw new HermesSkillNotFoundError(skillName)\n }\n\n const configPath = resolveHermesConfigPath(current.profile.name)\n const { document, config, existingRaw } =\n await readHermesConfigDocument(configPath)\n const skillsConfig = ensureRecord(config, 'skills')\n const disabled = new Set(readStringList(skillsConfig.disabled))\n if (enabled) {\n disabled.delete(target.name)\n } else {\n disabled.add(target.name)\n }\n skillsConfig.disabled = [...disabled].sort((left, right) =>\n left.localeCompare(right),\n )\n const backupPath = await writeHermesConfigDocument({\n configPath,\n document,\n config,\n existingRaw,\n })\n const updated = await listHermesProfileSkills(current.profile.name, paths)\n const skill = updated.skills.find((item) => item.name === target.name)\n if (!skill) {\n throw new HermesSkillNotFoundError(target.name)\n }\n return {\n ...updated,\n skill,\n backupPath,\n }\n}\n\nasync function readExistingProfile(\n profileName: string,\n paths: RuntimePaths,\n): Promise<HermesProfile> {\n const profile = await getHermesProfileStatus(profileName, paths)\n if (!profile.exists && profile.name !== 'default') {\n throw new Error('profile does not exist')\n }\n return profile\n}\n\nasync function findSkillFiles(root: string): Promise<string[]> {\n const results: string[] = []\n await collectSkillFiles(root, results)\n return results.sort((left, right) => left.localeCompare(right))\n}\n\nasync function collectSkillFiles(\n directory: string,\n results: string[],\n): Promise<void> {\n const entries = await readdir(directory, { withFileTypes: true }).catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return []\n }\n throw error\n },\n )\n for (const entry of entries.sort((left, right) =>\n left.name.localeCompare(right.name),\n )) {\n if (EXCLUDED_SKILL_DIRS.has(entry.name)) {\n continue\n }\n const entryPath = path.join(directory, entry.name)\n if (entry.isDirectory()) {\n await collectSkillFiles(entryPath, results)\n continue\n }\n if (entry.isFile() && entry.name === 'SKILL.md') {\n results.push(entryPath)\n }\n }\n}\n\nasync function readSkillMetadata(input: {\n skillFile: string\n skillsRoot: string\n disabled: Set<string>\n provenance: Map<string, SkillProvenance>\n}): Promise<HermesProfileSkill | null> {\n const raw = await readFile(input.skillFile, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT') || isNodeError(error, 'EACCES')) {\n return null\n }\n throw error\n },\n )\n if (raw === null) {\n return null\n }\n const skillDir = path.dirname(input.skillFile)\n const { frontmatter, body } = parseSkillDocument(raw.slice(0, 4000))\n const name = normalizeSkillName(\n readString(frontmatter.name) ?? path.basename(skillDir),\n )\n if (!name) {\n return null\n }\n const description = normalizeDescription(\n readString(frontmatter.description) ?? firstBodyDescription(body),\n )\n const provenance = input.provenance.get(name) ?? {\n source: 'local',\n trust: 'local',\n }\n return {\n name,\n category: categoryFromPath(input.skillsRoot, input.skillFile),\n description,\n enabled: !input.disabled.has(name),\n source: provenance.source,\n trust: provenance.trust,\n relativePath: path.relative(input.skillsRoot, skillDir),\n }\n}\n\nfunction parseSkillDocument(raw: string): {\n frontmatter: Record<string, unknown>\n body: string\n} {\n const content = raw.replace(/^\\uFEFF/u, '')\n const match = /^---[ \\t]*\\r?\\n([\\s\\S]*?)\\r?\\n---[ \\t]*(?:\\r?\\n|$)/u.exec(\n content,\n )\n if (!match) {\n return { frontmatter: {}, body: content }\n }\n try {\n return {\n frontmatter: toRecord(YAML.parse(match[1] ?? '')),\n body: content.slice(match[0].length),\n }\n } catch {\n return { frontmatter: {}, body: content.slice(match[0].length) }\n }\n}\n\nfunction categoryFromPath(\n skillsRoot: string,\n skillFile: string,\n): string | null {\n const relative = path.relative(skillsRoot, skillFile)\n const parts = relative.split(path.sep).filter(Boolean)\n return parts.length >= 3 ? parts[0] : null\n}\n\nfunction firstBodyDescription(body: string): string {\n for (const line of body.split(/\\r?\\n/u)) {\n const text = line.trim()\n if (text && !text.startsWith('#')) {\n return text\n }\n }\n return ''\n}\n\nfunction normalizeSkillName(value: string): string {\n return value.trim().slice(0, MAX_SKILL_NAME_LENGTH)\n}\n\nfunction normalizeDescription(value: string): string {\n const description = value.trim().replace(/\\s+/gu, ' ')\n if (description.length <= MAX_DESCRIPTION_LENGTH) {\n return description\n }\n return `${description.slice(0, MAX_DESCRIPTION_LENGTH - 3)}...`\n}\n\nasync function readDisabledSkillNames(configPath: string): Promise<Set<string>> {\n const raw = await readFile(configPath, 'utf8').catch((error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n })\n if (!raw.trim()) {\n return new Set()\n }\n const config = toRecord(YAML.parse(raw))\n const skills = toRecord(config.skills)\n return new Set(readStringList(skills.disabled))\n}\n\ninterface SkillProvenance {\n source: string\n trust: string | null\n}\n\nasync function readSkillProvenance(\n root: string,\n): Promise<Map<string, SkillProvenance>> {\n const provenance = new Map<string, SkillProvenance>()\n for (const name of await readBundledSkillNames(root)) {\n provenance.set(name, { source: 'builtin', trust: 'builtin' })\n }\n for (const [name, entry] of await readHubInstalledSkills(root)) {\n provenance.set(name, entry)\n }\n return provenance\n}\n\nasync function readBundledSkillNames(root: string): Promise<Set<string>> {\n const raw = await readFile(path.join(root, '.bundled_manifest'), 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n const names = new Set<string>()\n for (const line of raw.split(/\\r?\\n/u)) {\n const value = line.trim()\n if (!value) {\n continue\n }\n const [name] = value.split(':', 1)\n const normalized = normalizeSkillName(name ?? '')\n if (normalized) {\n names.add(normalized)\n }\n }\n return names\n}\n\nasync function readHubInstalledSkills(\n root: string,\n): Promise<Map<string, SkillProvenance>> {\n const raw = await readFile(path.join(root, '.hub', 'lock.json'), 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return ''\n }\n throw error\n },\n )\n if (!raw.trim()) {\n return new Map()\n }\n let lock: Record<string, unknown>\n try {\n lock = toRecord(JSON.parse(raw))\n } catch {\n return new Map()\n }\n const installed = toRecord(lock.installed)\n const result = new Map<string, SkillProvenance>()\n for (const [name, rawEntry] of Object.entries(installed)) {\n const entry = toRecord(rawEntry)\n result.set(normalizeSkillName(name), {\n source: readString(entry.source) ?? 'hub',\n trust: readString(entry.trust_level) ?? null,\n })\n }\n return result\n}\n\nfunction summarizeCategories(\n skills: HermesProfileSkill[],\n): HermesProfileSkillCategory[] {\n const categories = new Map<string, HermesProfileSkillCategory>()\n for (const skill of skills) {\n const key = skill.category ?? ''\n const current =\n categories.get(key) ??\n {\n name: skill.category,\n label: skill.category ?? '未分类',\n total: 0,\n enabled: 0,\n disabled: 0,\n }\n current.total += 1\n if (skill.enabled) {\n current.enabled += 1\n } else {\n current.disabled += 1\n }\n categories.set(key, current)\n }\n return [...categories.values()].sort(compareCategories)\n}\n\nfunction compareSkills(\n left: HermesProfileSkill,\n right: HermesProfileSkill,\n): number {\n const category = compareCategoryNames(left.category, right.category)\n if (category !== 0) {\n return category\n }\n return left.name.localeCompare(right.name)\n}\n\nfunction compareCategories(\n left: HermesProfileSkillCategory,\n right: HermesProfileSkillCategory,\n): number {\n return compareCategoryNames(left.name, right.name)\n}\n\nfunction compareCategoryNames(\n left: string | null,\n right: string | null,\n): number {\n if (left === right) {\n return 0\n }\n if (left === null) {\n return 1\n }\n if (right === null) {\n return -1\n }\n return left.localeCompare(right)\n}\n\nasync function readHermesConfigDocument(configPath: string): Promise<{\n document: HermesYamlDocument\n config: Record<string, unknown>\n existingRaw: string | null\n}> {\n const existingRaw = await readFile(configPath, 'utf8').catch(\n (error: unknown) => {\n if (isNodeError(error, 'ENOENT')) {\n return null\n }\n throw error\n },\n )\n const document = (\n existingRaw ? YAML.parseDocument(existingRaw) : new YAML.Document({})\n ) as HermesYamlDocument\n return {\n document,\n config: toRecord(document.toJSON()),\n existingRaw,\n }\n}\n\nasync function writeHermesConfigDocument(input: {\n configPath: string\n document: HermesYamlDocument\n config: Record<string, unknown>\n existingRaw: string | null\n}): Promise<string | null> {\n const backupPath = input.existingRaw\n ? `${input.configPath}.bak.${Date.now()}`\n : null\n await mkdir(path.dirname(input.configPath), { recursive: true, mode: 0o700 })\n if (backupPath) {\n await copyFile(input.configPath, backupPath)\n }\n input.document.contents = input.document.createNode(input.config)\n const tempPath = `${input.configPath}.tmp.${process.pid}.${Date.now()}`\n await writeFile(tempPath, input.document.toString(), { mode: 0o600 })\n await rename(tempPath, input.configPath)\n return backupPath\n}\n\nfunction readStringList(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return []\n }\n return value\n .filter((item): item is string => typeof item === 'string')\n .map((item) => item.trim())\n .filter(Boolean)\n}\n\nfunction readString(value: unknown): string | null {\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction ensureRecord(\n target: Record<string, unknown>,\n key: string,\n): Record<string, unknown> {\n const current = toRecord(target[key])\n if (current === target[key]) {\n return current\n }\n target[key] = current\n return current\n}\n\nfunction isNodeError(error: unknown, code: string): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === code\n )\n}\n","import type Router from '@koa/router'\nimport {\n HermesSkillNotFoundError,\n listHermesProfileSkills,\n setHermesProfileSkillEnabled,\n} from '../../hermes/skills.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { LinkHttpError } from '../errors.js'\nimport { readBoolean, readJsonBody } from '../request.js'\n\nexport function registerProfileSkillRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n },\n): void {\n const { paths } = options\n\n router.get('/api/v1/profiles/:name/skills', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await listHermesProfileSkills(ctx.params.name, paths)\n })\n\n router.patch('/api/v1/profiles/:name/skills/:skillName', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const enabled = readBoolean(body.enabled)\n if (enabled === undefined) {\n throw new LinkHttpError(\n 400,\n 'skill_enabled_required',\n 'enabled must be a boolean',\n )\n }\n try {\n ctx.body = await setHermesProfileSkillEnabled(\n ctx.params.name,\n ctx.params.skillName,\n enabled,\n paths,\n )\n } catch (error) {\n if (error instanceof HermesSkillNotFoundError) {\n throw new LinkHttpError(404, 'skill_not_found', error.message)\n }\n throw error\n }\n })\n}\n","import type Router from '@koa/router'\nimport type { ServerResponse } from 'node:http'\nimport type { ConversationService } from '../../conversations/conversation-service.js'\nimport {\n deleteHermesProfile,\n getHermesProfileStatus,\n listHermesProfiles,\n readHermesProfileCapabilities,\n renameHermesProfile,\n updateHermesProfileMetadata,\n type HermesProfileMetadataInput,\n} from '../../hermes/profiles.js'\nimport {\n readHermesProfileCreationStatus,\n startHermesProfileCreation,\n subscribeHermesProfileCreationStatus,\n type HermesProfileCreationJobStatus,\n type HermesProfileCreationScope,\n type StartHermesProfileCreationInput,\n} from '../../hermes/profile-creation.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { LinkHttpError } from '../errors.js'\nimport { readJsonBody } from '../request.js'\nimport { registerProfileConfigRoutes } from './profile-configs.js'\nimport { registerProfileMemoryRoutes } from './profile-memory.js'\nimport { registerProfileSkillRoutes } from './profile-skills.js'\n\nexport function registerProfileRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n conversations: ConversationService\n },\n): void {\n const { paths, logger, conversations } = options\n\n router.get('/api/v1/profiles', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = {\n ok: true,\n profiles: await listHermesProfiles(paths),\n }\n })\n\n router.get('/api/v1/profile-creation/status', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await readHermesProfileCreationStatus(paths)\n })\n\n router.get('/api/v1/profile-creation/events', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.respond = false\n const response = ctx.res\n response.statusCode = 200\n response.setHeader('content-type', 'text/event-stream; charset=utf-8')\n response.setHeader('cache-control', 'no-store')\n response.setHeader('connection', 'keep-alive')\n\n writeProfileCreationSseEvent(\n response,\n await readHermesProfileCreationStatus(paths),\n )\n const unsubscribe = subscribeHermesProfileCreationStatus((status) => {\n writeProfileCreationSseEvent(response, status)\n })\n const cleanup = () => {\n unsubscribe()\n response.end()\n }\n ctx.req.on('close', cleanup)\n })\n\n router.get('/api/v1/profiles/:name/status', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = {\n ok: true,\n profile: await getHermesProfileStatus(ctx.params.name, paths),\n }\n })\n\n router.get('/api/v1/profiles/:name/statistics', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n const [profile, capabilities] = await Promise.all([\n getHermesProfileStatus(ctx.params.name, paths),\n readHermesProfileCapabilities(ctx.params.name),\n ])\n const statistics = await conversations.getStatistics({\n profileUid: profile.uid,\n profileName: profile.name,\n })\n statistics.models.total = capabilities.modelCount\n statistics.skills.total = capabilities.skillCount\n statistics.tools.total = capabilities.toolCount\n statistics.profiles.total = 1\n ctx.body = {\n ok: true,\n profile,\n capabilities,\n statistics,\n }\n })\n\n registerProfileSkillRoutes(router, { paths })\n registerProfileMemoryRoutes(router, { paths })\n registerProfileConfigRoutes(router, { paths, logger })\n\n router.post('/api/v1/profiles', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n ctx.status = 202\n ctx.body = await startHermesProfileCreation(\n readProfileCreationInput(body),\n { paths, logger },\n )\n })\n\n router.patch('/api/v1/profiles/:name', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n if (hasProfileRenameInput(body)) {\n const name = readProfileName(body)\n ctx.body = {\n ok: true,\n profile: await renameHermesProfile(ctx.params.name, name, paths),\n }\n return\n }\n ctx.body = {\n ok: true,\n profile: await updateHermesProfileMetadata(\n ctx.params.name,\n readProfileMetadataInput(body),\n paths,\n ),\n }\n })\n\n router.delete('/api/v1/profiles/:name', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const profile = await deleteHermesProfile(ctx.params.name, paths)\n const cleanup = await conversations.deleteLocalConversationsForProfile({\n profileName: profile.name,\n profileUid: profile.uid,\n })\n void logger.info('profile_deleted', {\n profile: profile.name,\n profile_uid: profile.uid,\n deleted_conversations: cleanup.deleted_count,\n })\n ctx.status = 204\n })\n}\n\nfunction readProfileName(body: Record<string, unknown>): string {\n if (typeof body.name !== 'string') {\n throw new Error('invalid profile name')\n }\n return body.name\n}\n\nfunction readProfileCreationInput(\n body: Record<string, unknown>,\n): StartHermesProfileCreationInput {\n const copyFrom =\n readOptionalProfileText(body, 'copyFrom', 'copy_from').value ??\n readOptionalProfileText(body, 'sourceProfile', 'source_profile').value\n return {\n name: readOptionalProfileText(body, 'name').value,\n displayName: readOptionalProfileText(\n body,\n 'displayName',\n 'display_name',\n ).value,\n description: readOptionalProfileText(body, 'description').value,\n avatarType: readProfileCreationAvatarType(body),\n avatarUrl: readOptionalProfileText(body, 'avatarUrl', 'avatar_url').value,\n copyFrom,\n copyScopes: readProfileCreationCopyScopes(body),\n }\n}\n\nfunction readProfileCreationAvatarType(\n body: Record<string, unknown>,\n): 'default' | 'url' | null {\n const value = readOptionalProfileText(body, 'avatarType', 'avatar_type').value\n if (!value) {\n return null\n }\n if (value !== 'default' && value !== 'url') {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_avatar_type',\n 'avatar_type must be \"default\" or \"url\"',\n )\n }\n return value\n}\n\nfunction readProfileCreationCopyScopes(\n body: Record<string, unknown>,\n): HermesProfileCreationScope[] | undefined {\n const raw = body.copyScopes ?? body.copy_scopes\n if (raw === undefined || raw === null) {\n return undefined\n }\n if (!Array.isArray(raw)) {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_copy_scopes',\n 'copy_scopes must be an array of strings',\n )\n }\n return raw.map((item) => {\n if (typeof item !== 'string' || !item.trim()) {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_copy_scopes',\n 'copy_scopes must contain non-empty strings',\n )\n }\n return item.trim() as HermesProfileCreationScope\n })\n}\n\nfunction hasProfileRenameInput(body: Record<string, unknown>): boolean {\n return Object.prototype.hasOwnProperty.call(body, 'name')\n}\n\nfunction readProfileMetadataInput(\n body: Record<string, unknown>,\n): HermesProfileMetadataInput {\n const metadata: HermesProfileMetadataInput = {}\n const displayName = readOptionalProfileText(\n body,\n 'displayName',\n 'display_name',\n )\n if (displayName.present) {\n metadata.displayName = displayName.value\n }\n\n const description = readOptionalProfileText(body, 'description')\n if (description.present) {\n metadata.description = description.value\n }\n\n const avatarType = readOptionalProfileText(body, 'avatarType', 'avatar_type')\n if (avatarType.present) {\n const value = avatarType.value ?? 'default'\n if (value !== 'default' && value !== 'url') {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_avatar_type',\n 'avatar_type must be \"default\" or \"url\"',\n )\n }\n metadata.avatarType = value\n }\n\n const avatarUrl = readOptionalProfileText(body, 'avatarUrl', 'avatar_url')\n if (avatarUrl.present) {\n if (avatarUrl.value && !isProfileAvatarUrl(avatarUrl.value)) {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_avatar_url',\n 'avatar_url must be an http(s) URL or a small image data URL',\n )\n }\n metadata.avatarUrl = avatarUrl.value\n }\n if (metadata.avatarType === 'default') {\n metadata.avatarUrl = null\n }\n return metadata\n}\n\nfunction readOptionalProfileText(\n body: Record<string, unknown>,\n ...keys: string[]\n): { present: boolean; value: string | null } {\n for (const key of keys) {\n if (!Object.prototype.hasOwnProperty.call(body, key)) {\n continue\n }\n const value = body[key]\n if (value === null || value === undefined) {\n return { present: true, value: null }\n }\n if (typeof value !== 'string') {\n throw new LinkHttpError(\n 400,\n 'invalid_profile_metadata',\n `${key} must be a string or null`,\n )\n }\n const trimmed = value.trim()\n return { present: true, value: trimmed || null }\n }\n return { present: false, value: null }\n}\n\nfunction isHttpUrl(value: string): boolean {\n try {\n const url = new URL(value)\n return url.protocol === 'http:' || url.protocol === 'https:'\n } catch {\n return false\n }\n}\n\nfunction isProfileAvatarUrl(value: string): boolean {\n return isHttpUrl(value) || /^data:image\\/[a-z0-9.+-]+;base64,/iu.test(value)\n}\n\nfunction writeProfileCreationSseEvent(\n response: ServerResponse,\n status: HermesProfileCreationJobStatus,\n): void {\n response.write('event: profile.creation.status\\n')\n response.write(`data: ${JSON.stringify(status)}\\n\\n`)\n}\n","import type Router from '@koa/router'\nimport { Readable } from 'node:stream'\nimport {\n cancelHermesRun,\n createHermesRun,\n streamHermesRunEvents,\n} from '../../hermes/api-server.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport type { ConversationService } from '../../conversations/conversation-service.js'\nimport { authenticateRequest } from '../auth.js'\nimport { isLinkHttpError, LinkHttpError } from '../errors.js'\nimport {\n readConversationHistory,\n readJsonBody,\n readOptionalProfileName,\n readQueryString,\n readString,\n} from '../request.js'\n\nexport function registerRunRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n conversations: ConversationService\n },\n): void {\n const { paths, logger, conversations } = options\n\n router.post('/api/v1/runs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const input = readString(body, 'input')\n if (!input) {\n throw new LinkHttpError(400, 'run_input_required', 'input is required')\n }\n ctx.status = 202\n ctx.body = await createHermesRun(\n {\n input,\n instructions: readString(body, 'instructions') ?? undefined,\n conversation_history: readConversationHistory(\n body.conversation_history ?? body.conversationHistory,\n ),\n session_id:\n readString(body, 'session_id') ??\n readString(body, 'sessionId') ??\n undefined,\n },\n { logger, profileName: readOptionalProfileName(body) },\n )\n })\n\n router.get('/api/v1/runs/:runId/events', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const response = await streamHermesRunEvents(ctx.params.runId, {\n logger,\n profileName: readQueryString(ctx.query.profile),\n })\n ctx.status = response.status\n for (const [key, value] of response.headers.entries()) {\n ctx.set(key, value)\n }\n ctx.respond = false\n const nodeResponse = ctx.res\n nodeResponse.statusCode = response.status\n for (const [key, value] of response.headers.entries()) {\n nodeResponse.setHeader(key, value)\n }\n if (response.body) {\n Readable.fromWeb(\n response.body as Parameters<typeof Readable.fromWeb>[0],\n ).pipe(nodeResponse)\n } else {\n nodeResponse.end()\n }\n })\n\n router.post('/api/v1/runs/:runId/cancel', async (ctx) => {\n await authenticateRequest(ctx, paths)\n try {\n ctx.body = {\n ok: true,\n ...(await conversations.cancelRunById(ctx.params.runId)),\n }\n } catch (error) {\n if (isLinkHttpError(error) && error.code !== 'run_not_found') {\n throw error\n }\n await cancelHermesRun(ctx.params.runId, {\n logger,\n profileName: readQueryString(ctx.query.profile),\n })\n ctx.body = { ok: true }\n }\n })\n}\n","import type Router from '@koa/router'\nimport type { ConversationService } from '../../conversations/conversation-service.js'\nimport {\n readLinkUsageStatistics,\n type LinkUsageStatistics,\n} from '../../database/link-database.js'\nimport { listHermesModels } from '../../hermes/api-server.js'\nimport { listHermesModelConfigs } from '../../hermes/config.js'\nimport { listHermesProfiles } from '../../hermes/profiles.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { readInteger, readQueryString } from '../request.js'\n\nexport function registerStatisticsRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n conversations: ConversationService\n },\n): void {\n const { paths, logger, conversations } = options\n\n router.get('/api/v1/statistics', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n const profileName = readQueryString(ctx.query.profile)\n const statistics = await conversations.getStatistics({\n profileUid: readQueryString(ctx.query.profile_uid),\n profileName,\n })\n if (!profileName && !readQueryString(ctx.query.profile_uid)) {\n statistics.profiles.total = await listHermesProfiles(paths)\n .then((profiles) => profiles.length)\n .catch(() => statistics.profiles.total)\n }\n const availableModelCount = await readAvailableModelCount(logger).catch(\n () => null,\n )\n if (availableModelCount !== null) {\n statistics.models.total = availableModelCount\n }\n ctx.body = {\n ok: true,\n statistics,\n }\n })\n\n router.get('/api/v1/statistics/usage', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n const usage = await readLinkUsageStatistics(paths, {\n days: readInteger(ctx.query.days),\n from: readQueryString(ctx.query.from),\n to: readQueryString(ctx.query.to),\n })\n ctx.body = {\n ok: true,\n usage: await enrichUsageModelProviderNames(usage, paths),\n }\n })\n}\n\nasync function readAvailableModelCount(\n logger: FileLogger,\n): Promise<number | null> {\n const payload = await listHermesModels({ logger })\n const models = readModelList(payload)\n return models ? models.length : null\n}\n\nasync function enrichUsageModelProviderNames(\n usage: LinkUsageStatistics,\n paths: RuntimePaths,\n): Promise<LinkUsageStatistics> {\n const providerNames = await readUsageProviderNameMap(paths).catch(\n () => new Map<string, string>(),\n )\n if (providerNames.size === 0) {\n return usage\n }\n return {\n ...usage,\n models: usage.models.map((model) => {\n const provider = model.provider?.trim()\n if (!provider) {\n return model\n }\n const providerName = providerNames.get(\n usageModelProviderKey(model.model, provider),\n )\n if (!providerName || providerName === provider) {\n return model\n }\n return { ...model, provider: providerName }\n }),\n }\n}\n\nasync function readUsageProviderNameMap(\n paths: RuntimePaths,\n): Promise<Map<string, string>> {\n const profiles = await listHermesProfiles(paths).catch(() => [])\n const profileNames = new Set([\n 'default',\n ...profiles.map((item) => item.name),\n ])\n const results = await Promise.allSettled(\n [...profileNames].map((profileName) => listHermesModelConfigs(profileName)),\n )\n const providerNames = new Map<string, string>()\n const ambiguousKeys = new Set<string>()\n for (const result of results) {\n if (result.status !== 'fulfilled') {\n continue\n }\n for (const model of result.value.models) {\n const providerName = model.providerName.trim()\n if (!providerName || providerName === model.provider) {\n continue\n }\n const key = usageModelProviderKey(model.id, model.provider)\n const current = providerNames.get(key)\n if (current && current !== providerName) {\n ambiguousKeys.add(key)\n continue\n }\n providerNames.set(key, providerName)\n }\n }\n for (const key of ambiguousKeys) {\n providerNames.delete(key)\n }\n return providerNames\n}\n\nfunction usageModelProviderKey(model: string, provider: string): string {\n return `${model.trim()}\\u0000${provider.trim()}`\n}\n\nfunction readModelList(payload: unknown): unknown[] | null {\n if (!payload || typeof payload !== 'object') {\n return null\n }\n const record = payload as Record<string, unknown>\n if (Array.isArray(record.data)) {\n return record.data\n }\n if (Array.isArray(record.models)) {\n return record.models\n }\n return null\n}\n","import { EventEmitter } from 'node:events'\nimport { spawn } from 'node:child_process'\nimport { mkdir, readFile, rm } from 'node:fs/promises'\nimport path from 'node:path'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\nimport { loadConfig } from '../config/config.js'\nimport { createRotatingTextLogWriter, type FileLogger } from '../runtime/logger.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { readHermesVersion } from './gateway.js'\nimport { resolveHermesBin } from './cli.js'\n\nconst SERVER_HERMES_RELEASES_LATEST_PATH =\n '/api/v1/hermes-agent/releases/latest'\nconst RELEASE_CACHE_TTL_MS = 6 * 60 * 60 * 1000\nconst RELEASE_FETCH_TIMEOUT_MS = 5_000\nconst UPDATE_LOG_FILE = 'hermes-update.log'\nconst UPDATE_LOG_MAX_FILES = 3\nconst MAX_UPDATE_LOG_LINES = 240\nconst MAX_OUTPUT_LINE_LENGTH = 1_200\n\nexport interface HermesReleaseInfo {\n version: string | null\n tag: string | null\n name: string | null\n releaseUrl: string | null\n publishedAt: string | null\n fetchedAt: string\n}\n\ninterface ServerReleaseSnapshot {\n ok?: boolean\n remote?: {\n version?: unknown\n tag?: unknown\n name?: unknown\n releaseUrl?: unknown\n release_url?: unknown\n publishedAt?: unknown\n published_at?: unknown\n fetchedAt?: unknown\n fetched_at?: unknown\n } | null\n cache_state?: unknown\n cacheState?: unknown\n issue?: unknown\n}\n\nexport interface HermesUpdateCheckSnapshot {\n ok: true\n local: {\n version: string | null\n raw: string | null\n }\n remote: HermesReleaseInfo | null\n update_available: boolean\n check_state: 'fresh' | 'cached' | 'unavailable'\n issue: string | null\n}\n\nexport type HermesUpdateJobState =\n | 'idle'\n | 'running'\n | 'succeeded'\n | 'failed'\n\nexport interface HermesUpdateJobStatus {\n ok: true\n state: HermesUpdateJobState\n job_id: string | null\n pid: number | null\n started_at: string | null\n finished_at: string | null\n exit_code: number | null\n signal: string | null\n log_path: string\n lines: string[]\n error: string | null\n}\n\ninterface ReleaseCacheFile {\n fetched_at: string\n remote: Omit<HermesReleaseInfo, 'fetchedAt'>\n}\n\ninterface UpdateStateFile {\n state: HermesUpdateJobState\n job_id: string | null\n pid: number | null\n started_at: string | null\n finished_at: string | null\n exit_code: number | null\n signal: string | null\n error: string | null\n}\n\ninterface ReadUpdateCheckOptions {\n paths: RuntimePaths\n logger?: FileLogger\n fetchImpl?: typeof fetch\n refreshRemote?: boolean\n now?: () => Date\n}\n\ninterface StartHermesUpdateOptions {\n paths: RuntimePaths\n logger?: FileLogger\n now?: () => Date\n}\n\nconst updateEvents = new EventEmitter()\nlet runningUpdate: Promise<HermesUpdateJobStatus> | null = null\n\nexport async function readHermesUpdateCheck(\n options: ReadUpdateCheckOptions,\n): Promise<HermesUpdateCheckSnapshot> {\n const now = options.now ?? (() => new Date())\n const [local, remoteResult] = await Promise.all([\n readHermesVersion().catch((error: unknown) => ({\n raw: error instanceof Error ? error.message : String(error),\n version: null,\n })),\n readRemoteRelease(options, now),\n ])\n const remote = remoteResult.remote\n const updateAvailable = Boolean(\n local.version && remote?.version && compareSemver(local.version, remote.version) < 0,\n )\n return {\n ok: true,\n local: {\n version: local.version,\n raw: local.raw,\n },\n remote,\n update_available: updateAvailable,\n check_state: remoteResult.state,\n issue: remoteResult.issue,\n }\n}\n\nexport async function startHermesUpdate(\n options: StartHermesUpdateOptions,\n): Promise<HermesUpdateJobStatus> {\n const current = await readHermesUpdateStatus(options.paths)\n if (runningUpdate || current.state === 'running') {\n return current\n }\n\n const now = options.now ?? (() => new Date())\n const jobId = `hermes_update_${now().getTime().toString(36)}`\n await clearUpdateLogFiles(options.paths)\n const writer = createRotatingTextLogWriter({\n paths: options.paths,\n fileName: UPDATE_LOG_FILE,\n maxFileBytes: 512 * 1024,\n maxFiles: UPDATE_LOG_MAX_FILES,\n })\n const startedAt = now().toISOString()\n const started: UpdateStateFile = {\n state: 'running',\n job_id: jobId,\n pid: null,\n started_at: startedAt,\n finished_at: null,\n exit_code: null,\n signal: null,\n error: null,\n }\n await mkdir(options.paths.runDir, { recursive: true, mode: 0o700 })\n await writer.write(`\\n=== hermes update started ${startedAt} ===\\n`)\n await writeUpdateState(options.paths, started)\n\n const child = spawn(resolveHermesBin(), ['update'], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, HERMES_NONINTERACTIVE: '1' },\n windowsHide: true,\n detached: false,\n })\n started.pid = child.pid ?? null\n\n const appendChunk = async (chunk: Buffer | string) => {\n await writer.write(chunk)\n await emitUpdateStatus(options.paths)\n }\n child.stdout?.on('data', (chunk: Buffer) => {\n void appendChunk(chunk)\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n void appendChunk(chunk)\n })\n\n runningUpdate = new Promise<HermesUpdateJobStatus>((resolve) => {\n child.on('error', (error) => {\n void (async () => {\n const failed: UpdateStateFile = {\n ...started,\n state: 'failed',\n finished_at: now().toISOString(),\n error: error.message,\n }\n await writer.write(`\\n[failed] hermes update failed to start: ${error.message}\\n`)\n await writeUpdateState(options.paths, failed)\n await emitUpdateStatus(options.paths)\n void options.logger?.error('hermes_update_spawn_failed', {\n job_id: jobId,\n error: error.message,\n })\n resolve(await readHermesUpdateStatus(options.paths))\n })()\n })\n child.on('close', (code, signal) => {\n void (async () => {\n const state: UpdateStateFile = {\n ...started,\n state: code === 0 ? 'succeeded' : 'failed',\n finished_at: now().toISOString(),\n exit_code: code,\n signal,\n error: code === 0 ? null : `hermes update exited with code ${code ?? 'unknown'}`,\n }\n await writer.write(\n `\\n=== hermes update finished ${state.finished_at} exit=${code ?? 'null'} signal=${signal ?? 'null'} ===\\n`,\n )\n await writeUpdateState(options.paths, state)\n await emitUpdateStatus(options.paths)\n void options.logger?.info(\n code === 0 ? 'hermes_update_succeeded' : 'hermes_update_failed',\n {\n job_id: jobId,\n exit_code: code,\n signal: signal ?? null,\n },\n )\n resolve(await readHermesUpdateStatus(options.paths))\n })()\n })\n }).finally(() => {\n runningUpdate = null\n })\n\n await emitUpdateStatus(options.paths)\n void options.logger?.info('hermes_update_started', {\n job_id: jobId,\n pid: child.pid ?? null,\n log_path: writer.filePath,\n })\n\n return readHermesUpdateStatus(options.paths)\n}\n\nexport async function readHermesUpdateStatus(\n paths: RuntimePaths,\n): Promise<HermesUpdateJobStatus> {\n let state = await readJsonFile<UpdateStateFile>(updateStatePath(paths))\n if (\n state?.state === 'running' &&\n !runningUpdate &&\n !isRecentRunningState(state) &&\n !isProcessAlive(state.pid)\n ) {\n state = {\n ...state,\n state: 'failed',\n finished_at: new Date().toISOString(),\n error:\n state.error ??\n 'Hermes update was interrupted before Link could observe completion.',\n }\n await writeUpdateState(paths, state)\n }\n const lines = await readUpdateLogLines(paths)\n return {\n ok: true,\n state: state?.state ?? 'idle',\n job_id: state?.job_id ?? null,\n pid: state?.pid ?? null,\n started_at: state?.started_at ?? null,\n finished_at: state?.finished_at ?? null,\n exit_code: state?.exit_code ?? null,\n signal: state?.signal ?? null,\n log_path: updateLogPath(paths),\n lines,\n error: state?.error ?? null,\n }\n}\n\nexport function subscribeHermesUpdateStatus(\n listener: (status: HermesUpdateJobStatus) => void,\n): () => void {\n updateEvents.on('status', listener)\n return () => updateEvents.off('status', listener)\n}\n\nasync function readRemoteRelease(\n options: ReadUpdateCheckOptions,\n now: () => Date,\n): Promise<{\n remote: HermesReleaseInfo | null\n state: HermesUpdateCheckSnapshot['check_state']\n issue: string | null\n}> {\n const cached = await readReleaseCache(options.paths)\n const cacheFresh = cached\n ? now().getTime() - Date.parse(cached.fetched_at) < RELEASE_CACHE_TTL_MS\n : false\n if (!options.refreshRemote || cacheFresh) {\n return cached\n ? { remote: fromCache(cached), state: cacheFresh ? 'fresh' : 'cached', issue: null }\n : { remote: null, state: 'unavailable', issue: null }\n }\n\n try {\n const response = await fetchLatestReleaseFromServer(options, options.fetchImpl ?? fetch)\n if (!response.ok) {\n throw new Error(`HermesPilot Server returned HTTP ${response.status}`)\n }\n const snapshot = normalizeServerReleaseSnapshot(await response.json())\n if (snapshot.issue) {\n void options.logger?.warn('hermes_release_server_cache_issue', {\n error: snapshot.issue,\n })\n }\n if (!snapshot.remote) {\n return cached\n ? { remote: fromCache(cached), state: 'cached', issue: snapshot.issue }\n : {\n remote: null,\n state: 'unavailable',\n issue: snapshot.issue ?? 'HermesPilot Server has no release cache',\n }\n }\n const remote = snapshot.remote\n await writeJsonFile(releaseCachePath(options.paths), {\n fetched_at: remote.fetchedAt,\n remote: {\n version: remote.version,\n tag: remote.tag,\n name: remote.name,\n releaseUrl: remote.releaseUrl,\n publishedAt: remote.publishedAt,\n },\n } satisfies ReleaseCacheFile)\n return {\n remote,\n state: snapshot.cacheState === 'fresh' ? 'fresh' : 'cached',\n issue: snapshot.issue,\n }\n } catch (error) {\n const issue = error instanceof Error ? error.message : String(error)\n void options.logger?.warn('hermes_release_server_check_failed', {\n error: issue,\n })\n return cached\n ? { remote: fromCache(cached), state: 'cached', issue }\n : { remote: null, state: 'unavailable', issue }\n }\n}\n\nfunction normalizeServerReleaseSnapshot(\n payload: unknown,\n): { remote: HermesReleaseInfo | null; cacheState: string | null; issue: string | null } {\n const snapshot = toRecord(payload) as ServerReleaseSnapshot\n const remote = toNullableRecord(snapshot.remote)\n return {\n remote: remote ? normalizeServerRelease(remote) : null,\n cacheState:\n readString(snapshot as Record<string, unknown>, 'cache_state') ??\n readString(snapshot as Record<string, unknown>, 'cacheState'),\n issue: readString(snapshot as Record<string, unknown>, 'issue'),\n }\n}\n\nfunction normalizeServerRelease(payload: Record<string, unknown>): HermesReleaseInfo {\n const tag = readString(payload, 'tag')\n const name = readString(payload, 'name')\n return {\n version: readString(payload, 'version') ?? extractSemver(name) ?? extractTagSemver(tag),\n tag,\n name,\n releaseUrl:\n readString(payload, 'releaseUrl') ?? readString(payload, 'release_url'),\n publishedAt:\n readString(payload, 'publishedAt') ?? readString(payload, 'published_at'),\n fetchedAt:\n readString(payload, 'fetchedAt') ??\n readString(payload, 'fetched_at') ??\n new Date().toISOString(),\n }\n}\n\nasync function readReleaseCache(paths: RuntimePaths): Promise<ReleaseCacheFile | null> {\n return readJsonFile<ReleaseCacheFile>(releaseCachePath(paths)).catch(() => null)\n}\n\nfunction fromCache(cache: ReleaseCacheFile): HermesReleaseInfo {\n return {\n ...cache.remote,\n fetchedAt: cache.fetched_at,\n }\n}\n\nasync function emitUpdateStatus(paths: RuntimePaths): Promise<void> {\n updateEvents.emit('status', await readHermesUpdateStatus(paths))\n}\n\nasync function writeUpdateState(\n paths: RuntimePaths,\n state: UpdateStateFile,\n): Promise<void> {\n await writeJsonFile(updateStatePath(paths), state)\n}\n\nasync function readUpdateLogLines(paths: RuntimePaths): Promise<string[]> {\n const raw = await readFile(updateLogPath(paths), 'utf8').catch(() => '')\n if (!raw.trim()) {\n return []\n }\n return raw\n .split(/\\r?\\n/u)\n .map((line) => line.trimEnd())\n .filter(Boolean)\n .slice(-MAX_UPDATE_LOG_LINES)\n .map((line) =>\n line.length > MAX_OUTPUT_LINE_LENGTH\n ? `${line.slice(0, MAX_OUTPUT_LINE_LENGTH)}...`\n : line,\n )\n}\n\nfunction releaseCachePath(paths: RuntimePaths): string {\n return path.join(paths.indexesDir, 'hermes-release-check.json')\n}\n\nfunction updateStatePath(paths: RuntimePaths): string {\n return path.join(paths.runDir, 'hermes-update-state.json')\n}\n\nfunction updateLogPath(paths: RuntimePaths): string {\n return path.join(paths.logsDir, UPDATE_LOG_FILE)\n}\n\nasync function clearUpdateLogFiles(paths: RuntimePaths): Promise<void> {\n const primary = updateLogPath(paths)\n await Promise.all([\n rm(primary, { force: true }).catch(() => undefined),\n ...Array.from({ length: UPDATE_LOG_MAX_FILES }, (_, index) =>\n rm(`${primary}.${index + 1}`, { force: true }).catch(() => undefined),\n ),\n ])\n}\n\nfunction extractSemver(value: string | null): string | null {\n if (!value) {\n return null\n }\n const match = /\\bv?(\\d+\\.\\d+\\.\\d+)(?:[-+][0-9A-Za-z.-]+)?\\b/u.exec(value)\n return match?.[1] ?? null\n}\n\nfunction extractTagSemver(value: string | null): string | null {\n const version = extractSemver(value)\n if (!version) {\n return null\n }\n const major = Number.parseInt(version.split('.')[0] ?? '', 10)\n return major >= 1000 ? null : version\n}\n\nfunction compareSemver(left: string, right: string): number {\n const leftParts = left.split('.').map((part) => Number.parseInt(part, 10))\n const rightParts = right.split('.').map((part) => Number.parseInt(part, 10))\n for (let index = 0; index < 3; index += 1) {\n const diff = (leftParts[index] || 0) - (rightParts[index] || 0)\n if (diff !== 0) {\n return diff\n }\n }\n return 0\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction toNullableRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : null\n}\n\nasync function fetchLatestReleaseFromServer(\n options: ReadUpdateCheckOptions,\n fetcher: typeof fetch,\n): Promise<Response> {\n const config = await loadConfig(options.paths)\n const url = new URL(SERVER_HERMES_RELEASES_LATEST_PATH, config.serverBaseUrl)\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), RELEASE_FETCH_TIMEOUT_MS)\n try {\n return await fetcher(url, {\n headers: {\n accept: 'application/json',\n 'user-agent': 'HermesPilot-Link',\n },\n signal: controller.signal,\n })\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error('HermesPilot Server release check timed out')\n }\n throw error\n } finally {\n clearTimeout(timer)\n }\n}\n\nfunction isProcessAlive(pid: number | null): boolean {\n if (!pid || pid <= 0) {\n return false\n }\n try {\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\nfunction isRecentRunningState(state: UpdateStateFile): boolean {\n if (!state.started_at) {\n return false\n }\n const startedAt = Date.parse(state.started_at)\n return Number.isFinite(startedAt) && Date.now() - startedAt < 30_000\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n","import { spawn } from 'node:child_process'\nimport { EventEmitter } from 'node:events'\nimport { mkdir, readFile, rm } from 'node:fs/promises'\nimport path from 'node:path'\nimport { LINK_COMMAND, LINK_VERSION } from '../constants.js'\nimport { loadConfig } from '../config/config.js'\nimport { currentCliScriptPath } from '../daemon/process.js'\nimport {\n createRotatingTextLogWriter,\n type FileLogger,\n} from '../runtime/logger.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\n\nconst SERVER_LINK_CURRENT_RELEASE_PATH = '/api/v1/link/releases/current'\nconst LINK_NPM_PACKAGE = '@hermespilot/link'\nconst UPDATE_LOG_FILE = 'link-update.log'\nconst UPDATE_LOG_MAX_FILES = 3\nconst UPDATE_FETCH_TIMEOUT_MS = 5_000\nconst MAX_UPDATE_LOG_LINES = 240\nconst MAX_OUTPUT_LINE_LENGTH = 1_200\nconst AUTO_RESTART_DELAY_MS = 1_500\n\nexport type LinkUpdateState =\n | 'current'\n | 'update_available'\n | 'unsafe'\n | 'blocked'\n | 'ahead_of_current'\n | 'unknown'\n\nexport type LinkUpdateJobState =\n | 'idle'\n | 'running'\n | 'succeeded'\n | 'failed'\n | 'restart_required'\n\nexport interface LinkReleasePolicy {\n current_version: string | null\n min_safe_version: string | null\n target_version: string | null\n release_url: string | null\n published_at: string | null\n}\n\nexport interface LinkUpdateCheckSnapshot {\n ok: true\n local: {\n version: string\n raw: string\n }\n remote: LinkReleasePolicy | null\n state: LinkUpdateState\n update_available: boolean\n unsafe: boolean\n blocked: boolean\n check_state: 'fresh' | 'unavailable'\n issue: string | null\n manual: {\n command: string | null\n package: string\n version: string | null\n }\n}\n\nexport interface LinkUpdateJobStatus {\n ok: true\n state: LinkUpdateJobState\n job_id: string | null\n pid: number | null\n target_version: string | null\n started_at: string | null\n finished_at: string | null\n exit_code: number | null\n signal: string | null\n log_path: string\n lines: string[]\n error: string | null\n manual_command: string | null\n}\n\ninterface StartLinkUpdateOptions {\n paths: RuntimePaths\n logger?: FileLogger\n targetVersion?: string | null\n fetchImpl?: typeof fetch\n now?: () => Date\n}\n\ninterface ReadLinkUpdateCheckOptions {\n paths: RuntimePaths\n logger?: FileLogger\n fetchImpl?: typeof fetch\n}\n\ninterface LinkReleaseServerSnapshot {\n ok?: boolean\n policy?: {\n current_version?: unknown\n currentVersion?: unknown\n min_safe_version?: unknown\n minSafeVersion?: unknown\n } | null\n release?: {\n version?: unknown\n release_url?: unknown\n releaseUrl?: unknown\n published_at?: unknown\n publishedAt?: unknown\n } | null\n cache_state?: unknown\n cacheState?: unknown\n issue?: unknown\n}\n\ninterface LinkUpdateStateFile {\n state: LinkUpdateJobState\n job_id: string | null\n pid: number | null\n target_version: string | null\n started_at: string | null\n finished_at: string | null\n exit_code: number | null\n signal: string | null\n error: string | null\n manual_command: string | null\n}\n\nconst updateEvents = new EventEmitter()\nlet runningUpdate: Promise<LinkUpdateJobStatus> | null = null\n\nexport async function readLinkUpdateCheck(\n options: ReadLinkUpdateCheckOptions,\n): Promise<LinkUpdateCheckSnapshot> {\n const remoteResult = await readRemoteLinkPolicy(options)\n const remote = remoteResult.remote\n const state = computeLinkUpdateState(LINK_VERSION, remote)\n const targetVersion = remote?.target_version ?? null\n return {\n ok: true,\n local: {\n version: LINK_VERSION,\n raw: LINK_VERSION,\n },\n remote,\n state,\n update_available:\n state === 'update_available' || state === 'unsafe' || state === 'blocked',\n unsafe: state === 'unsafe',\n blocked: state === 'blocked',\n check_state: remoteResult.state,\n issue: remoteResult.issue,\n manual: {\n command: targetVersion ? manualInstallCommand(targetVersion) : null,\n package: LINK_NPM_PACKAGE,\n version: targetVersion,\n },\n }\n}\n\nexport async function startLinkUpdate(\n options: StartLinkUpdateOptions,\n): Promise<LinkUpdateJobStatus> {\n const current = await readLinkUpdateStatus(options.paths)\n if (runningUpdate || current.state === 'running') {\n return current\n }\n const check = await readLinkUpdateCheck(options)\n const targetVersion = check.remote?.target_version ?? null\n if (!targetVersion) {\n return writeFailedStartState(\n options,\n 'HermesPilot Server has no Link target version.',\n )\n }\n if (options.targetVersion && options.targetVersion !== targetVersion) {\n return writeFailedStartState(\n options,\n `Requested target ${options.targetVersion} does not match current Link target ${targetVersion}.`,\n targetVersion,\n )\n }\n if (check.state === 'current') {\n return writeFailedStartState(\n options,\n 'Hermes Link is already on the current version.',\n targetVersion,\n )\n }\n\n const now = options.now ?? (() => new Date())\n const jobId = `link_update_${now().getTime().toString(36)}`\n await clearUpdateLogFiles(options.paths)\n const writer = createRotatingTextLogWriter({\n paths: options.paths,\n fileName: UPDATE_LOG_FILE,\n maxFileBytes: 512 * 1024,\n maxFiles: UPDATE_LOG_MAX_FILES,\n })\n const startedAt = now().toISOString()\n const manualCommand = manualInstallCommand(targetVersion)\n const started: LinkUpdateStateFile = {\n state: 'running',\n job_id: jobId,\n pid: null,\n target_version: targetVersion,\n started_at: startedAt,\n finished_at: null,\n exit_code: null,\n signal: null,\n error: null,\n manual_command: manualCommand,\n }\n await mkdir(options.paths.runDir, { recursive: true, mode: 0o700 })\n await writer.write(\n `\\n=== link update started ${startedAt} target=${targetVersion} ===\\n`,\n )\n await writer.write(`$ ${manualCommand}\\n`)\n await writeUpdateState(options.paths, started)\n\n const child = spawn(\n resolveNpmBin(),\n ['install', '-g', `${LINK_NPM_PACKAGE}@${targetVersion}`],\n {\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n detached: false,\n shell: false,\n },\n )\n started.pid = child.pid ?? null\n await writeUpdateState(options.paths, started)\n\n const appendChunk = async (chunk: Buffer | string) => {\n await writer.write(chunk)\n await emitUpdateStatus(options.paths)\n }\n child.stdout?.on('data', (chunk: Buffer) => {\n void appendChunk(chunk)\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n void appendChunk(chunk)\n })\n\n runningUpdate = new Promise<LinkUpdateJobStatus>((resolve) => {\n child.on('error', (error) => {\n void (async () => {\n const failed: LinkUpdateStateFile = {\n ...started,\n state: 'failed',\n finished_at: now().toISOString(),\n error: error.message,\n }\n await writer.write(\n `\\n[failed] link update failed to start: ${error.message}\\n`,\n )\n await writeUpdateState(options.paths, failed)\n await emitUpdateStatus(options.paths)\n void options.logger?.error('link_update_spawn_failed', {\n job_id: jobId,\n target_version: targetVersion,\n error: error.message,\n })\n resolve(await readLinkUpdateStatus(options.paths))\n })()\n })\n child.on('close', (code, signal) => {\n void (async () => {\n const succeeded = code === 0\n const state: LinkUpdateStateFile = {\n ...started,\n state: succeeded ? 'restart_required' : 'failed',\n finished_at: now().toISOString(),\n exit_code: code,\n signal,\n error: succeeded\n ? null\n : `npm install exited with code ${code ?? 'unknown'}`,\n }\n await writer.write(\n `\\n=== link update finished ${state.finished_at} exit=${code ?? 'null'} signal=${signal ?? 'null'} ===\\n`,\n )\n if (succeeded) {\n await writer.write(\n `\\n[restart-scheduled] Hermes Link will restart automatically. If it does not reconnect, run \\`${LINK_COMMAND} restart\\` on this computer.\\n`,\n )\n }\n await writeUpdateState(options.paths, state)\n await emitUpdateStatus(options.paths)\n if (succeeded) {\n await writer.flush()\n scheduleAutomaticRestart(options)\n }\n void options.logger?.info(\n succeeded ? 'link_update_restart_required' : 'link_update_failed',\n {\n job_id: jobId,\n target_version: targetVersion,\n exit_code: code,\n signal: signal ?? null,\n },\n )\n resolve(await readLinkUpdateStatus(options.paths))\n })()\n })\n }).finally(() => {\n runningUpdate = null\n })\n\n await emitUpdateStatus(options.paths)\n void options.logger?.info('link_update_started', {\n job_id: jobId,\n pid: child.pid ?? null,\n target_version: targetVersion,\n log_path: writer.filePath,\n })\n\n return readLinkUpdateStatus(options.paths)\n}\n\nfunction scheduleAutomaticRestart(options: StartLinkUpdateOptions): void {\n const scriptPath = currentCliScriptPath()\n setTimeout(() => {\n const child = spawn(process.execPath, [scriptPath, 'restart'], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n windowsHide: true,\n })\n child.unref()\n void options.logger?.info('link_update_restart_scheduled', {\n delay_ms: AUTO_RESTART_DELAY_MS,\n command: `${LINK_COMMAND} restart`,\n })\n }, AUTO_RESTART_DELAY_MS).unref()\n}\n\nexport async function readLinkUpdateStatus(\n paths: RuntimePaths,\n): Promise<LinkUpdateJobStatus> {\n let state = await readJsonFile<LinkUpdateStateFile>(updateStatePath(paths))\n if (state?.state === 'restart_required' && state.target_version) {\n if (compareSemver(LINK_VERSION, state.target_version) >= 0) {\n state = {\n ...state,\n state: 'succeeded',\n finished_at: state.finished_at ?? new Date().toISOString(),\n }\n await writeUpdateState(paths, state)\n }\n }\n if (\n state?.state === 'running' &&\n !runningUpdate &&\n !isRecentRunningState(state) &&\n !isProcessAlive(state.pid)\n ) {\n state = {\n ...state,\n state: 'failed',\n finished_at: new Date().toISOString(),\n error:\n state.error ??\n 'Link update was interrupted before Hermes Link could observe completion.',\n }\n await writeUpdateState(paths, state)\n }\n return {\n ok: true,\n state: state?.state ?? 'idle',\n job_id: state?.job_id ?? null,\n pid: state?.pid ?? null,\n target_version: state?.target_version ?? null,\n started_at: state?.started_at ?? null,\n finished_at: state?.finished_at ?? null,\n exit_code: state?.exit_code ?? null,\n signal: state?.signal ?? null,\n log_path: updateLogPath(paths),\n lines: await readUpdateLogLines(paths),\n error: state?.error ?? null,\n manual_command: state?.manual_command ?? null,\n }\n}\n\nexport function subscribeLinkUpdateStatus(\n listener: (status: LinkUpdateJobStatus) => void,\n): () => void {\n updateEvents.on('status', listener)\n return () => updateEvents.off('status', listener)\n}\n\nasync function writeFailedStartState(\n options: StartLinkUpdateOptions,\n error: string,\n targetVersion: string | null = null,\n): Promise<LinkUpdateJobStatus> {\n const now = options.now ?? (() => new Date())\n const state: LinkUpdateStateFile = {\n state: 'failed',\n job_id: `link_update_${now().getTime().toString(36)}`,\n pid: null,\n target_version: targetVersion,\n started_at: now().toISOString(),\n finished_at: now().toISOString(),\n exit_code: null,\n signal: null,\n error,\n manual_command: targetVersion ? manualInstallCommand(targetVersion) : null,\n }\n await writeUpdateState(options.paths, state)\n await emitUpdateStatus(options.paths)\n return readLinkUpdateStatus(options.paths)\n}\n\nasync function readRemoteLinkPolicy(\n options: ReadLinkUpdateCheckOptions,\n): Promise<{\n remote: LinkReleasePolicy | null\n state: LinkUpdateCheckSnapshot['check_state']\n issue: string | null\n}> {\n try {\n const response = await fetchCurrentLinkReleaseFromServer(\n options,\n options.fetchImpl ?? fetch,\n )\n if (!response.ok) {\n throw new Error(`HermesPilot Server returned HTTP ${response.status}`)\n }\n const snapshot = normalizeServerSnapshot(await response.json())\n if (!snapshot.remote) {\n return {\n remote: null,\n state: 'unavailable',\n issue:\n snapshot.issue ?? 'HermesPilot Server has no Link release policy',\n }\n }\n return {\n remote: snapshot.remote,\n state: 'fresh',\n issue: snapshot.issue,\n }\n } catch (error) {\n const issue = error instanceof Error ? error.message : String(error)\n void options.logger?.warn('link_release_server_check_failed', {\n error: issue,\n })\n return { remote: null, state: 'unavailable', issue }\n }\n}\n\nfunction normalizeServerSnapshot(payload: unknown): {\n remote: LinkReleasePolicy | null\n issue: string | null\n} {\n const snapshot = toRecord(payload) as LinkReleaseServerSnapshot\n const policy = toNullableRecord(snapshot.policy)\n if (!policy) {\n return {\n remote: null,\n issue: readString(snapshot as Record<string, unknown>, 'issue'),\n }\n }\n const release = toNullableRecord(snapshot.release)\n const currentVersion =\n readString(policy, 'current_version') ??\n readString(policy, 'currentVersion')\n const minSafeVersion =\n readString(policy, 'min_safe_version') ??\n readString(policy, 'minSafeVersion')\n if (!currentVersion) {\n return {\n remote: null,\n issue: readString(snapshot as Record<string, unknown>, 'issue'),\n }\n }\n return {\n remote: {\n current_version: currentVersion,\n min_safe_version: minSafeVersion,\n target_version: currentVersion,\n release_url: release\n ? (readString(release, 'release_url') ??\n readString(release, 'releaseUrl'))\n : null,\n published_at: release\n ? (readString(release, 'published_at') ??\n readString(release, 'publishedAt'))\n : null,\n },\n issue: readString(snapshot as Record<string, unknown>, 'issue'),\n }\n}\n\nasync function fetchCurrentLinkReleaseFromServer(\n options: ReadLinkUpdateCheckOptions,\n fetcher: typeof fetch,\n): Promise<Response> {\n const config = await loadConfig(options.paths)\n const url = new URL(SERVER_LINK_CURRENT_RELEASE_PATH, config.serverBaseUrl)\n url.searchParams.set('channel', 'stable')\n url.searchParams.set('lang', 'en')\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), UPDATE_FETCH_TIMEOUT_MS)\n try {\n return await fetcher(url, {\n headers: {\n accept: 'application/json',\n 'user-agent': `HermesPilot-Link/${LINK_VERSION}`,\n },\n signal: controller.signal,\n })\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error('HermesPilot Server Link release check timed out')\n }\n throw error\n } finally {\n clearTimeout(timer)\n }\n}\n\nfunction computeLinkUpdateState(\n localVersion: string,\n remote: LinkReleasePolicy | null,\n): LinkUpdateState {\n if (!remote?.current_version) {\n return 'unknown'\n }\n if (\n remote.min_safe_version &&\n compareSemver(localVersion, remote.min_safe_version) < 0\n ) {\n return 'unsafe'\n }\n const diff = compareSemver(localVersion, remote.current_version)\n if (diff < 0) {\n return 'update_available'\n }\n if (diff > 0) {\n return 'ahead_of_current'\n }\n return 'current'\n}\n\nasync function emitUpdateStatus(paths: RuntimePaths): Promise<void> {\n updateEvents.emit('status', await readLinkUpdateStatus(paths))\n}\n\nasync function writeUpdateState(\n paths: RuntimePaths,\n state: LinkUpdateStateFile,\n): Promise<void> {\n await writeJsonFile(updateStatePath(paths), state)\n}\n\nasync function readUpdateLogLines(paths: RuntimePaths): Promise<string[]> {\n const raw = await readFile(updateLogPath(paths), 'utf8').catch(() => '')\n if (!raw.trim()) {\n return []\n }\n return raw\n .split(/\\r?\\n/u)\n .map((line) => line.trimEnd())\n .filter(Boolean)\n .slice(-MAX_UPDATE_LOG_LINES)\n .map((line) =>\n line.length > MAX_OUTPUT_LINE_LENGTH\n ? `${line.slice(0, MAX_OUTPUT_LINE_LENGTH)}...`\n : line,\n )\n}\n\nfunction updateStatePath(paths: RuntimePaths): string {\n return path.join(paths.runDir, 'link-update-state.json')\n}\n\nfunction updateLogPath(paths: RuntimePaths): string {\n return path.join(paths.logsDir, UPDATE_LOG_FILE)\n}\n\nasync function clearUpdateLogFiles(paths: RuntimePaths): Promise<void> {\n const primary = updateLogPath(paths)\n await Promise.all([\n rm(primary, { force: true }).catch(() => undefined),\n ...Array.from({ length: UPDATE_LOG_MAX_FILES }, (_, index) =>\n rm(`${primary}.${index + 1}`, { force: true }).catch(() => undefined),\n ),\n ])\n}\n\nfunction manualInstallCommand(version: string): string {\n return `npm install -g ${LINK_NPM_PACKAGE}@${version}`\n}\n\nfunction resolveNpmBin(): string {\n return process.platform === 'win32' ? 'npm.cmd' : 'npm'\n}\n\nfunction compareSemver(left: string, right: string): number {\n const leftParts = parseSemver(left)\n const rightParts = parseSemver(right)\n for (let index = 0; index < 3; index += 1) {\n const diff = leftParts[index] - rightParts[index]\n if (diff !== 0) {\n return diff\n }\n }\n return 0\n}\n\nfunction parseSemver(value: string): [number, number, number] {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)/u.exec(value.trim())\n return [\n Number.parseInt(match?.[1] ?? '0', 10),\n Number.parseInt(match?.[2] ?? '0', 10),\n Number.parseInt(match?.[3] ?? '0', 10),\n ]\n}\n\nfunction isRecentRunningState(\n state: LinkUpdateStateFile,\n now = Date.now(),\n): boolean {\n const startedAt = state.started_at ? Date.parse(state.started_at) : Number.NaN\n return Number.isFinite(startedAt) && now - startedAt < 10_000\n}\n\nfunction isProcessAlive(pid: number | null): boolean {\n if (!pid || pid <= 0) {\n return false\n }\n try {\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : {}\n}\n\nfunction toNullableRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : null\n}\n\nfunction readString(\n payload: Record<string, unknown>,\n key: string,\n): string | null {\n const value = payload[key]\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n","import { spawn } from 'node:child_process'\nimport { mkdir, readFile, rm } from 'node:fs/promises'\nimport path from 'node:path'\nimport { pidFilePath } from './service.js'\nimport { loadConfig } from '../config/config.js'\nimport {\n createRotatingTextLogWriter,\n getDaemonLogFile,\n} from '../runtime/logger.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\n\nexport interface DaemonStatus {\n running: boolean\n pid: number | null\n pidFile: string\n logFile: string\n}\n\nexport interface LocalLinkServiceProbe {\n reachable: boolean\n reusable: boolean\n linkId: string | null\n version: string | null\n}\n\nexport async function startDaemonProcess(paths: RuntimePaths = resolveRuntimePaths()): Promise<DaemonStatus> {\n const config = await loadConfig(paths)\n let status = await getDaemonStatus(paths)\n if (status.running) {\n const probe = await probeLocalLinkService({ port: config.port, timeoutMs: 500 })\n if (probe.reachable) {\n return status\n }\n await stopDaemonProcess(paths)\n status = await getDaemonStatus(paths)\n if (status.running) {\n return status\n }\n }\n await mkdir(paths.logsDir, { recursive: true, mode: 0o700 })\n await mkdir(paths.runDir, { recursive: true, mode: 0o700 })\n const scriptPath = currentCliScriptPath()\n const child = spawn(process.execPath, [scriptPath, 'daemon-supervisor'], {\n detached: true,\n stdio: 'ignore',\n env: process.env,\n })\n child.unref()\n for (let index = 0; index < 12; index += 1) {\n await wait(250)\n const next = await getDaemonStatus(paths)\n if (next.running && (await probeLocalLinkService({ port: config.port, timeoutMs: 500 })).reachable) {\n return next\n }\n }\n return await getDaemonStatus(paths)\n}\n\nexport async function runDaemonSupervisor(paths: RuntimePaths = resolveRuntimePaths()): Promise<number> {\n await mkdir(paths.logsDir, { recursive: true, mode: 0o700 })\n const log = createRotatingTextLogWriter({\n paths,\n fileName: path.basename(daemonLogFile(paths)),\n })\n const scriptPath = currentCliScriptPath()\n const child = spawn(process.execPath, [scriptPath, 'daemon', '--foreground'], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: process.env,\n })\n const write = (chunk: Buffer | string) => {\n void log.write(chunk)\n }\n write(`[${new Date().toISOString()}] daemon supervisor started\\n`)\n child.stdout?.on('data', write)\n child.stderr?.on('data', write)\n\n const forwardStop = () => {\n if (child.pid && isProcessAlive(child.pid)) {\n child.kill('SIGTERM')\n }\n }\n process.once('SIGINT', forwardStop)\n process.once('SIGTERM', forwardStop)\n const result = await new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve, reject) => {\n child.once('error', reject)\n child.once('exit', (code, signal) => resolve({ code, signal }))\n }).catch((error: unknown) => {\n write(`[${new Date().toISOString()}] daemon supervisor failed: ${error instanceof Error ? error.message : String(error)}\\n`)\n return { code: 1, signal: null }\n })\n process.off('SIGINT', forwardStop)\n process.off('SIGTERM', forwardStop)\n write(\n `[${new Date().toISOString()}] daemon supervisor stopped code=${result.code ?? 'null'} signal=${result.signal ?? 'null'}\\n`,\n )\n await log.flush()\n return result.code ?? (result.signal ? 0 : 1)\n}\n\nexport async function probeLocalLinkService(options: {\n port: number\n linkId?: string\n timeoutMs?: number\n}): Promise<LocalLinkServiceProbe> {\n const unreachable: LocalLinkServiceProbe = {\n reachable: false,\n reusable: false,\n linkId: null,\n version: null,\n }\n let response: Response\n try {\n response = await fetch(`http://127.0.0.1:${options.port}/api/v1/bootstrap`, {\n headers: { accept: 'application/json' },\n signal: AbortSignal.timeout(options.timeoutMs ?? 1_000),\n })\n } catch {\n return unreachable\n }\n if (!response.ok) {\n return unreachable\n }\n const payload = (await response.json().catch(() => null)) as Record<string, unknown> | null\n if (!payload || payload.api_version !== 1) {\n return unreachable\n }\n const linkId = typeof payload.link_id === 'string' ? payload.link_id : null\n return {\n reachable: true,\n reusable: options.linkId ? linkId === options.linkId : true,\n linkId,\n version: typeof payload.version === 'string' ? payload.version : null,\n }\n}\n\nexport async function stopDaemonProcess(paths: RuntimePaths = resolveRuntimePaths()): Promise<DaemonStatus> {\n const status = await getDaemonStatus(paths)\n if (!status.running || !status.pid) {\n return status\n }\n try {\n process.kill(status.pid, 'SIGTERM')\n } catch {\n await rm(pidFilePath(paths), { force: true }).catch(() => undefined)\n return await getDaemonStatus(paths)\n }\n for (let index = 0; index < 20; index += 1) {\n await wait(250)\n if (!isProcessAlive(status.pid)) {\n break\n }\n }\n if (isProcessAlive(status.pid)) {\n try {\n process.kill(status.pid, 'SIGKILL')\n } catch {\n // The process may have exited between the liveness check and the forced kill.\n }\n for (let index = 0; index < 10; index += 1) {\n await wait(250)\n if (!isProcessAlive(status.pid)) {\n break\n }\n }\n }\n if (!isProcessAlive(status.pid) || !(await pidBackedServiceIsReachable(paths))) {\n await rm(pidFilePath(paths), { force: true }).catch(() => undefined)\n }\n return await getDaemonStatus(paths)\n}\n\nexport async function getDaemonStatus(paths: RuntimePaths = resolveRuntimePaths()): Promise<DaemonStatus> {\n const pidFile = pidFilePath(paths)\n const pid = await readPid(pidFile)\n if (pid && !isProcessAlive(pid)) {\n await rm(pidFile, { force: true }).catch(() => undefined)\n return {\n running: false,\n pid: null,\n pidFile,\n logFile: daemonLogFile(paths),\n }\n }\n return {\n running: Boolean(pid),\n pid,\n pidFile,\n logFile: daemonLogFile(paths),\n }\n}\n\nexport function daemonLogFile(paths: RuntimePaths = resolveRuntimePaths()): string {\n return getDaemonLogFile(paths)\n}\n\nexport function currentCliScriptPath(): string {\n return process.argv[1]\n}\n\nasync function readPid(filePath: string): Promise<number | null> {\n const raw = await readFile(filePath, 'utf8').catch(() => null)\n if (!raw) {\n return null\n }\n const pid = Number.parseInt(raw.trim(), 10)\n return Number.isInteger(pid) && pid > 0 ? pid : null\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n } catch {\n return false\n }\n}\n\nasync function pidBackedServiceIsReachable(paths: RuntimePaths): Promise<boolean> {\n const config = await loadConfig(paths).catch(() => null)\n if (!config) {\n return false\n }\n return (await probeLocalLinkService({ port: config.port, timeoutMs: 500 })).reachable\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import { createServer, type Server } from 'node:http'\nimport { mkdir, rm, writeFile } from 'node:fs/promises'\nimport { createApp, type CreateAppOptions } from '../http/app.js'\nimport { loadConfig } from '../config/config.js'\nimport { ConversationService } from '../conversations/conversation-service.js'\nimport { loadIdentity } from '../identity/identity.js'\nimport { connectRelayControl, type RelayControlClient } from '../relay/control-client.js'\nimport { createFileLogger } from '../runtime/logger.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport { migrateLinkDatabase } from '../database/link-database.js'\nimport { startCronDeliveryScheduler } from './scheduler.js'\n\nexport interface LinkService {\n close(): Promise<void>\n}\n\nexport interface StartLinkServiceOptions extends CreateAppOptions {\n paths?: RuntimePaths\n writePidFile?: boolean\n relayMaxReconnectAttempts?: number\n}\n\nexport async function startLinkService(options: StartLinkServiceOptions = {}): Promise<LinkService> {\n const paths = options.paths ?? resolveRuntimePaths()\n const logger = createFileLogger({ paths })\n const [identity, config] = await Promise.all([loadIdentity(paths), loadConfig(paths)])\n await logger.info('service_starting', {\n port: config.port,\n mode: identity?.link_id ? 'paired' : 'local-only',\n })\n const migration = await migrateLinkDatabase(paths)\n if (migration.appliedVersions.length > 0) {\n await logger.info('database_migrated', {\n database_file: migration.databaseFile,\n applied_versions: migration.appliedVersions,\n current_version: migration.currentVersion,\n })\n }\n const conversations = new ConversationService(paths, logger)\n await conversations.rebuildStatisticsIndex()\n const app = await createApp({\n paths,\n logger,\n conversations,\n onPairingClaimed: options.onPairingClaimed,\n })\n const server = createServer(app.callback())\n try {\n await listenServer(server, config.port)\n } catch (error) {\n await logger.error('service_start_failed', {\n port: config.port,\n error: error instanceof Error ? error.message : String(error),\n })\n await logger.flush()\n throw error\n }\n server.on('error', (error) => {\n void logger.error('service_error', { error: error.message })\n })\n void logger.info('service_started', {\n port: config.port,\n link_id: identity?.link_id ?? null,\n })\n const scheduler = startCronDeliveryScheduler({\n paths,\n conversations,\n logger,\n })\n let relay: RelayControlClient | null = null\n if (identity?.link_id) {\n relay = connectRelayControl({\n relayBaseUrl: config.relayBaseUrl,\n linkId: identity.link_id,\n localPort: config.port,\n maxReconnectAttempts: options.relayMaxReconnectAttempts ?? 5,\n backoffBaseMs: 1_000,\n backoffMaxMs: 30_000,\n onStatus: (status) => {\n void logger.info('relay_status', status)\n },\n })\n } else {\n void logger.info('relay_skipped', { reason: 'link_not_paired' })\n }\n if (options.writePidFile) {\n await writePidFile(paths)\n }\n return {\n async close() {\n scheduler.close()\n relay?.close()\n await closeServer(server)\n await logger.info('service_stopped')\n await logger.flush()\n if (options.writePidFile) {\n await rm(pidFilePath(paths), { force: true }).catch(() => undefined)\n }\n },\n }\n}\n\nexport function pidFilePath(paths: RuntimePaths = resolveRuntimePaths()): string {\n return `${paths.runDir}/hermeslink.pid`\n}\n\nasync function writePidFile(paths: RuntimePaths): Promise<void> {\n await mkdir(paths.runDir, { recursive: true, mode: 0o700 })\n await writeFile(pidFilePath(paths), `${process.pid}\\n`, { mode: 0o600 })\n}\n\nasync function closeServer(server: Server): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n let settled = false\n let forceCloseTimer: ReturnType<typeof setTimeout>\n let timeoutTimer: ReturnType<typeof setTimeout>\n const settle = (error?: Error) => {\n if (settled) {\n return\n }\n settled = true\n clearTimeout(forceCloseTimer)\n clearTimeout(timeoutTimer)\n if (error) {\n reject(error)\n return\n }\n resolve()\n }\n forceCloseTimer = setTimeout(() => {\n server.closeIdleConnections?.()\n server.closeAllConnections?.()\n }, 250)\n timeoutTimer = setTimeout(() => {\n server.closeAllConnections?.()\n settle()\n }, 5_000)\n server.close((error) => {\n if (error) {\n settle(error)\n return\n }\n settle()\n })\n server.closeIdleConnections?.()\n })\n}\n\nasync function listenServer(server: Server, port: number): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const cleanup = () => {\n server.off('error', onError)\n server.off('listening', onListening)\n }\n const onError = (error: Error) => {\n cleanup()\n reject(error)\n }\n const onListening = () => {\n cleanup()\n resolve()\n }\n\n server.once('error', onError)\n server.once('listening', onListening)\n server.listen(port)\n })\n}\n","import WebSocket from 'ws'\nimport { LINK_VERSION } from '../constants.js'\n\ninterface RelayRequestFrame {\n type: 'http.request'\n id: string\n method: string\n path: string\n headers?: Record<string, string>\n bodyBase64?: string | null\n}\n\ninterface RelayCancelFrame {\n type: 'http.cancel'\n id: string\n}\n\ntype RelayFrame = RelayRequestFrame | RelayCancelFrame\n\nexport interface RelayControlClient {\n close(): void\n}\n\nexport function connectRelayControl(options: {\n relayBaseUrl: string\n linkId: string\n localPort: number\n maxReconnectAttempts?: number\n backoffBaseMs?: number\n backoffMaxMs?: number\n onStatus?: (status: { state: 'connecting' | 'connected' | 'disconnected' | 'retrying' | 'failed'; attempt: number; message?: string }) => void\n}): RelayControlClient {\n const wsUrl = new URL(`${options.relayBaseUrl.replace(/\\/+$/u, '')}/api/v1/relay/link/connect`)\n wsUrl.protocol = wsUrl.protocol === 'https:' ? 'wss:' : 'ws:'\n wsUrl.searchParams.set('link_id', options.linkId)\n\n const maxReconnectAttempts = options.maxReconnectAttempts ?? 5\n const backoffBaseMs = options.backoffBaseMs ?? 1_000\n const backoffMaxMs = options.backoffMaxMs ?? 30_000\n let reconnectAttempts = 0\n let closedByUser = false\n let socket: WebSocket | null = null\n let retryTimer: ReturnType<typeof setTimeout> | null = null\n let abortControllers = new Map<string, AbortController>()\n let fatalRelayRejection: string | null = null\n\n const connect = () => {\n options.onStatus?.({ state: 'connecting', attempt: reconnectAttempts })\n fatalRelayRejection = null\n socket = new WebSocket(wsUrl, {\n headers: {\n 'x-hermes-link-version': LINK_VERSION,\n },\n })\n socket.on('open', () => {\n reconnectAttempts = 0\n options.onStatus?.({ state: 'connected', attempt: reconnectAttempts })\n })\n socket.on('message', (raw) => {\n if (!socket || (typeof raw !== 'string' && !Buffer.isBuffer(raw))) {\n return\n }\n void handleFrame(socket, String(raw), options.localPort, abortControllers).catch((error) => {\n const message = error instanceof Error ? error.message : 'Relay request failed'\n socket?.send(JSON.stringify({ type: 'http.error', id: 'unknown', status: 502, message }))\n })\n })\n socket.on('error', (error) => {\n const message = error instanceof Error ? error.message : 'Relay websocket error'\n fatalRelayRejection = resolveFatalRelayRejection(message)\n options.onStatus?.({\n state: 'disconnected',\n attempt: reconnectAttempts,\n message: fatalRelayRejection ?? message,\n })\n })\n socket.on('close', () => {\n abortAll(abortControllers)\n abortControllers = new Map<string, AbortController>()\n if (fatalRelayRejection) {\n options.onStatus?.({\n state: 'failed',\n attempt: reconnectAttempts,\n message: fatalRelayRejection,\n })\n return\n }\n if (closedByUser) {\n options.onStatus?.({ state: 'disconnected', attempt: reconnectAttempts })\n return\n }\n if (reconnectAttempts >= maxReconnectAttempts) {\n options.onStatus?.({ state: 'failed', attempt: reconnectAttempts, message: 'Relay reconnect attempts exhausted' })\n return\n }\n reconnectAttempts += 1\n const delay = computeBackoffMs(reconnectAttempts, backoffBaseMs, backoffMaxMs)\n options.onStatus?.({ state: 'retrying', attempt: reconnectAttempts, message: `Retrying in ${delay}ms` })\n retryTimer = setTimeout(connect, delay)\n retryTimer.unref?.()\n })\n }\n\n connect()\n\n return {\n close() {\n closedByUser = true\n if (retryTimer) {\n clearTimeout(retryTimer)\n retryTimer = null\n }\n abortAll(abortControllers)\n socket?.terminate()\n },\n }\n}\n\nfunction resolveFatalRelayRejection(message: string): string | null {\n if (!/Unexpected server response:\\s*(400|401|403|426)\\b/u.test(message)) {\n return null\n }\n return 'Relay refused the Hermes Link connection. Check Link version and pairing state before retrying.'\n}\n\nfunction abortAll(abortControllers: Map<string, AbortController>): void {\n for (const controller of abortControllers.values()) {\n controller.abort()\n }\n abortControllers.clear()\n}\n\nfunction computeBackoffMs(attempt: number, baseMs: number, maxMs: number): number {\n const exponential = Math.min(maxMs, baseMs * 2 ** Math.max(0, attempt - 1))\n const jitter = Math.floor(Math.random() * Math.min(1_000, exponential * 0.2))\n return exponential + jitter\n}\n\nasync function handleFrame(\n socket: WebSocket,\n raw: string,\n localPort: number,\n abortControllers: Map<string, AbortController>,\n): Promise<void> {\n const frame = JSON.parse(raw) as RelayFrame\n if (frame.type === 'http.cancel') {\n abortControllers.get(frame.id)?.abort()\n abortControllers.delete(frame.id)\n return\n }\n if (frame.type !== 'http.request') {\n return\n }\n const abortController = new AbortController()\n abortControllers.set(frame.id, abortController)\n try {\n const response = await fetch(`http://127.0.0.1:${localPort}${frame.path}`, {\n method: frame.method,\n headers: frame.headers ?? {},\n body: frame.bodyBase64 ? Buffer.from(frame.bodyBase64, 'base64') : undefined,\n signal: abortController.signal,\n })\n const headers = Object.fromEntries(response.headers.entries())\n const contentType = response.headers.get('content-type') ?? ''\n if (response.body && contentType.includes('text/event-stream')) {\n socket.send(JSON.stringify({ type: 'http.stream.start', id: frame.id, status: response.status, headers }))\n const reader = response.body.getReader()\n while (true) {\n const next = await reader.read()\n if (next.done) {\n break\n }\n socket.send(JSON.stringify({ type: 'http.stream.chunk', id: frame.id, bodyBase64: Buffer.from(next.value).toString('base64') }))\n }\n socket.send(JSON.stringify({ type: 'http.stream.end', id: frame.id }))\n return\n }\n const body = Buffer.from(await response.arrayBuffer()).toString('base64')\n socket.send(JSON.stringify({ type: 'http.response', id: frame.id, status: response.status, headers, bodyBase64: body }))\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Relay request failed'\n socket.send(JSON.stringify({ type: 'http.error', id: frame.id, status: 502, message }))\n } finally {\n abortControllers.delete(frame.id)\n }\n}\n","import type { ConversationService } from '../conversations/conversation-service.js'\nimport { syncHermesLinkCronDeliveries } from '../hermes/cron-link-delivery.js'\nimport type { FileLogger } from '../runtime/logger.js'\nimport type { RuntimePaths } from '../runtime/paths.js'\n\nexport interface LinkScheduler {\n close(): void\n}\n\nexport function startCronDeliveryScheduler(options: {\n paths: RuntimePaths\n conversations: ConversationService\n logger: FileLogger\n intervalMs?: number\n}): LinkScheduler {\n let running = false\n const syncCronDeliveries = async () => {\n if (running) {\n return\n }\n running = true\n try {\n await syncHermesLinkCronDeliveries(\n options.paths,\n options.conversations,\n options.logger,\n )\n } catch (error) {\n void options.logger.warn('cron_link_delivery_sync_failed', {\n error: error instanceof Error ? error.message : String(error),\n })\n } finally {\n running = false\n }\n }\n\n const timer = setInterval(() => {\n void syncCronDeliveries()\n }, options.intervalMs ?? 30_000)\n timer.unref?.()\n\n return {\n close() {\n clearInterval(timer)\n },\n }\n}\n","import path from 'node:path'\nimport { rm } from 'node:fs/promises'\nimport { loadConfig } from '../config/config.js'\nimport { createDeviceSession } from '../security/devices.js'\nimport { ensureIdentity, loadIdentity, type LinkIdentity } from '../identity/identity.js'\nimport { bootstrapRelayLink } from '../relay/bootstrap.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\nimport { discoverRouteCandidates, type RouteDiscoveryResult } from '../topology/network.js'\nimport { LinkHttpError } from '../core/errors.js'\nimport { LINK_VERSION } from '../constants.js'\nimport { readJsonFile, writeJsonFile } from '../storage/atomic-json.js'\n\nexport interface PreparedPairing {\n sessionId: string\n code: string\n pairingToken: string\n relayBootstrapToken: string\n relayBaseUrl: string\n displayName: string\n linkId: string\n routes: RouteDiscoveryResult\n qrPayload: Record<string, unknown>\n expiresAt: string\n}\n\nexport interface PairingClaimRecord {\n session_id: string\n device_id: string\n device_label: string\n device_platform: string\n claimed_at: string\n}\n\nexport interface PairingSessionRecord {\n session_id: string\n code: string\n link_id: string\n display_name: string\n local_api_url: string\n server_base_url: string\n relay_base_url: string\n preferred_urls: string[]\n created_at: string\n expires_at: string\n}\n\nexport async function preparePairing(paths: RuntimePaths = resolveRuntimePaths()): Promise<PreparedPairing> {\n const config = await loadConfig(paths)\n const identity = await ensureIdentity(paths)\n const created = await postServerJson<{\n sessionId: string\n code: string\n pairingToken: string\n relayBootstrapToken: string\n relayBaseUrl: string\n }>(config.serverBaseUrl, '/api/v1/link-pairings', {\n install_id: identity.install_id,\n link_id: identity.link_id ?? undefined,\n display_name: defaultDisplayName(),\n public_key_pem: identity.public_key_pem,\n })\n const relayBaseUrl = created.relayBaseUrl || config.relayBaseUrl\n const assigned = await bootstrapRelayLink({\n relayBaseUrl,\n relayBootstrapToken: created.relayBootstrapToken,\n identity,\n paths,\n })\n const updatedIdentity = (await loadIdentity(paths)) ?? identity\n const routes = await discoverRouteCandidates({\n port: config.port,\n relayBaseUrl,\n relayBootstrapToken: created.relayBootstrapToken,\n linkId: assigned.linkId,\n installId: updatedIdentity.install_id,\n publicKeyPem: updatedIdentity.public_key_pem,\n })\n await patchServerJson(config.serverBaseUrl, `/api/v1/link-pairings/${created.sessionId}/link`, created.pairingToken, {\n install_id: updatedIdentity.install_id,\n link_id: assigned.linkId,\n link_version: LINK_VERSION,\n display_name: defaultDisplayName(),\n lan_ips: routes.lanIps,\n public_ipv4s: routes.publicIpv4s,\n public_ipv6s: routes.publicIpv6s,\n preferred_urls: routes.preferredUrls,\n })\n const qrPayload = {\n kind: 'hermes_link_pairing',\n version: 1,\n link_id: assigned.linkId,\n display_name: defaultDisplayName(),\n session_id: created.sessionId,\n code: created.code,\n preferred_urls: qrPreferredUrls(routes),\n }\n const expiresAt = new Date(Date.now() + 10 * 60 * 1000).toISOString()\n await writePairingSession(\n {\n session_id: created.sessionId,\n code: created.code,\n link_id: assigned.linkId,\n display_name: defaultDisplayName(),\n local_api_url: `http://127.0.0.1:${config.port}`,\n server_base_url: config.serverBaseUrl,\n relay_base_url: relayBaseUrl,\n preferred_urls: qrPreferredUrls(routes),\n created_at: new Date().toISOString(),\n expires_at: expiresAt,\n },\n paths,\n )\n return {\n sessionId: created.sessionId,\n code: created.code,\n pairingToken: created.pairingToken,\n relayBootstrapToken: created.relayBootstrapToken,\n relayBaseUrl,\n displayName: defaultDisplayName(),\n linkId: assigned.linkId,\n routes,\n qrPayload,\n expiresAt,\n }\n}\n\nexport async function writePairingSession(\n input: PairingSessionRecord,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<PairingSessionRecord> {\n await writeJsonFile(pairingSessionPath(input.session_id, paths), input)\n return input\n}\n\nexport async function readPairingSession(\n sessionId: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<PairingSessionRecord | null> {\n const record = await readJsonFile<Partial<PairingSessionRecord>>(pairingSessionPath(sessionId, paths))\n if (\n !record ||\n record.session_id !== sessionId ||\n typeof record.code !== 'string' ||\n typeof record.link_id !== 'string' ||\n typeof record.display_name !== 'string' ||\n typeof record.local_api_url !== 'string' ||\n typeof record.server_base_url !== 'string' ||\n typeof record.relay_base_url !== 'string' ||\n !Array.isArray(record.preferred_urls) ||\n typeof record.created_at !== 'string' ||\n typeof record.expires_at !== 'string'\n ) {\n return null\n }\n return {\n session_id: record.session_id,\n code: record.code,\n link_id: record.link_id,\n display_name: record.display_name,\n local_api_url: record.local_api_url,\n server_base_url: record.server_base_url,\n relay_base_url: record.relay_base_url,\n preferred_urls: record.preferred_urls.filter((value): value is string => typeof value === 'string'),\n created_at: record.created_at,\n expires_at: record.expires_at,\n }\n}\n\nexport async function clearPairingSession(\n sessionId: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<void> {\n await rm(pairingSessionPath(sessionId, paths), { force: true }).catch(() => undefined)\n}\n\nexport async function recordPairingClaim(\n input: {\n sessionId: string\n deviceId: string\n deviceLabel: string\n devicePlatform: string\n },\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<PairingClaimRecord> {\n const record: PairingClaimRecord = {\n session_id: input.sessionId,\n device_id: input.deviceId,\n device_label: input.deviceLabel,\n device_platform: input.devicePlatform,\n claimed_at: new Date().toISOString(),\n }\n await writeJsonFile(pairingClaimPath(input.sessionId, paths), record)\n return record\n}\n\nexport async function readPairingClaim(\n sessionId: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<PairingClaimRecord | null> {\n const record = await readJsonFile<Partial<PairingClaimRecord>>(pairingClaimPath(sessionId, paths))\n if (!record || record.session_id !== sessionId || typeof record.device_id !== 'string') {\n return null\n }\n return {\n session_id: record.session_id,\n device_id: record.device_id,\n device_label: typeof record.device_label === 'string' ? record.device_label : '',\n device_platform: typeof record.device_platform === 'string' ? record.device_platform : 'unknown',\n claimed_at: typeof record.claimed_at === 'string' ? record.claimed_at : '',\n }\n}\n\nexport async function clearPairingClaim(\n sessionId: string,\n paths: RuntimePaths = resolveRuntimePaths(),\n): Promise<void> {\n await rm(pairingClaimPath(sessionId, paths), { force: true }).catch(() => undefined)\n}\n\nexport async function claimPairing(input: {\n sessionId: string\n claimToken: string\n deviceLabel: string\n devicePlatform: string\n deviceModel?: string | null\n appInstanceId?: string | null\n paths?: RuntimePaths\n}): Promise<{\n link: { link_id: string; display_name: string }\n device: ReturnType<typeof formatDevice>\n access_token: { token: string; expires_at: string }\n refresh_token: { token: string; expires_at: string }\n}> {\n const paths = input.paths ?? resolveRuntimePaths()\n const [identity, config] = await Promise.all([loadRequiredIdentity(paths), loadConfig(paths)])\n const verified = await postServerJson<{ ok: boolean; linkId: string; appInstanceId?: string | null }>(\n config.serverBaseUrl,\n `/api/v1/link-pairings/${input.sessionId}/claim/verify`,\n {\n claim_token: input.claimToken,\n app_instance_id: input.appInstanceId ?? undefined,\n },\n )\n if (verified.ok !== true || verified.linkId !== identity.link_id) {\n throw new LinkHttpError(409, 'pairing_claim_mismatch', 'Pairing claim does not match this Link')\n }\n const session = await createDeviceSession(\n {\n label: input.deviceLabel || 'HermesPilot App',\n platform: input.devicePlatform || 'unknown',\n model: input.deviceModel ?? null,\n appInstanceId: verified.appInstanceId ?? null,\n },\n paths,\n )\n return {\n link: {\n link_id: identity.link_id,\n display_name: defaultDisplayName(),\n },\n device: formatDevice(session.device),\n access_token: {\n token: session.accessToken.token,\n expires_at: session.accessToken.expiresAt,\n },\n refresh_token: {\n token: session.refreshToken.token,\n expires_at: session.refreshToken.expiresAt,\n },\n }\n}\n\nasync function loadRequiredIdentity(paths: RuntimePaths): Promise<LinkIdentity & { link_id: string }> {\n const identity = await loadIdentity(paths)\n if (!identity?.link_id) {\n throw new LinkHttpError(409, 'link_not_paired', 'Hermes Link is not paired')\n }\n return identity as LinkIdentity & { link_id: string }\n}\n\nasync function postServerJson<T>(serverBaseUrl: string, path: string, body: Record<string, unknown>): Promise<T> {\n const response = await fetch(`${serverBaseUrl.replace(/\\/+$/u, '')}${path}`, {\n method: 'POST',\n headers: {\n accept: 'application/json',\n 'content-type': 'application/json',\n },\n body: JSON.stringify(body),\n })\n return readJsonResponse<T>(response)\n}\n\nasync function patchServerJson<T>(\n serverBaseUrl: string,\n path: string,\n token: string,\n body: Record<string, unknown>,\n): Promise<T> {\n const response = await fetch(`${serverBaseUrl.replace(/\\/+$/u, '')}${path}`, {\n method: 'PATCH',\n headers: {\n accept: 'application/json',\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n },\n body: JSON.stringify(body),\n })\n return readJsonResponse<T>(response)\n}\n\nasync function readJsonResponse<T>(response: Response): Promise<T> {\n const payload = (await response.json().catch(() => null)) as T | null\n if (!response.ok || !payload) {\n const message = readErrorMessage(payload) ?? `HermesPilot Server request failed with HTTP ${response.status}`\n throw new LinkHttpError(response.status, 'server_request_failed', message)\n }\n return payload\n}\n\nfunction readErrorMessage(payload: unknown): string | null {\n if (typeof payload !== 'object' || payload === null) {\n return null\n }\n const error = (payload as { error?: unknown }).error\n if (typeof error !== 'object' || error === null) {\n return null\n }\n const message = (error as { message?: unknown }).message\n return typeof message === 'string' ? message : null\n}\n\nfunction defaultDisplayName(): string {\n return `Hermes Link ${process.platform}`\n}\n\nfunction pairingClaimPath(sessionId: string, paths: RuntimePaths): string {\n return path.join(paths.pairingDir, `${Buffer.from(sessionId).toString('base64url')}.claimed.json`)\n}\n\nfunction pairingSessionPath(sessionId: string, paths: RuntimePaths): string {\n return path.join(paths.pairingDir, `${Buffer.from(sessionId).toString('base64url')}.json`)\n}\n\nfunction qrPreferredUrls(routes: RouteDiscoveryResult): string[] {\n return routes.preferredUrls.filter((url) => !url.includes('/api/v1/relay/links/')).slice(0, 1)\n}\n\nfunction formatDevice(device: {\n id: string\n device_id: string\n label: string\n platform: string\n model?: string | null\n scope: 'admin'\n}) {\n return {\n id: device.id,\n device_id: device.device_id,\n label: device.label,\n platform: device.platform,\n model: device.model ?? null,\n scope: device.scope,\n }\n}\n","import { saveAssignedLinkId, signRelayNonce, type LinkIdentity } from '../identity/identity.js'\nimport { resolveRuntimePaths, type RuntimePaths } from '../runtime/paths.js'\n\nexport interface RelayBootstrapOptions {\n relayBaseUrl: string\n relayBootstrapToken: string\n identity: LinkIdentity\n paths?: RuntimePaths\n fetchImpl?: typeof fetch\n}\n\nexport interface RelayBootstrapResult {\n linkId: string\n reused: boolean\n}\n\ninterface RelayChallengeResponse {\n ok?: unknown\n nonce?: unknown\n expires_at?: unknown\n}\n\ninterface RelayBootstrapResponse {\n ok?: unknown\n link_id?: unknown\n reused?: unknown\n}\n\nexport async function bootstrapRelayLink(options: RelayBootstrapOptions): Promise<RelayBootstrapResult> {\n const fetcher = options.fetchImpl ?? fetch\n const baseUrl = options.relayBaseUrl.replace(/\\/+$/u, '')\n const commonPayload = {\n install_id: options.identity.install_id,\n link_id: options.identity.link_id ?? undefined,\n public_key_pem: options.identity.public_key_pem,\n }\n const challenge = await postJson<RelayChallengeResponse>(\n fetcher,\n `${baseUrl}/api/v1/relay/link/challenge`,\n options.relayBootstrapToken,\n commonPayload,\n )\n if (challenge.ok !== true || typeof challenge.nonce !== 'string') {\n throw new Error('Relay did not return a valid install challenge')\n }\n\n const proof = {\n nonce: challenge.nonce,\n signature: signRelayNonce(options.identity, challenge.nonce),\n }\n const assigned = await postJson<RelayBootstrapResponse>(\n fetcher,\n `${baseUrl}/api/v1/relay/link/bootstrap`,\n options.relayBootstrapToken,\n {\n ...commonPayload,\n proof,\n },\n )\n if (assigned.ok !== true || typeof assigned.link_id !== 'string') {\n throw new Error('Relay did not return a valid link_id')\n }\n\n await saveAssignedLinkId(assigned.link_id, options.paths ?? resolveRuntimePaths())\n return {\n linkId: assigned.link_id,\n reused: assigned.reused === true,\n }\n}\n\nasync function postJson<T>(\n fetcher: typeof fetch,\n url: string,\n token: string,\n body: Record<string, unknown>,\n): Promise<T> {\n const response = await fetcher(url, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n },\n body: JSON.stringify(body),\n })\n const payload = (await response.json().catch(() => null)) as T | null\n if (!response.ok) {\n const message = readErrorMessage(payload) ?? `Relay request failed with HTTP ${response.status}`\n throw new Error(message)\n }\n if (!payload) {\n throw new Error('Relay returned an empty response')\n }\n return payload\n}\n\nfunction readErrorMessage(payload: unknown): string | null {\n if (typeof payload !== 'object' || payload === null) {\n return null\n }\n const error = (payload as { error?: unknown }).error\n if (typeof error !== 'object' || error === null) {\n return null\n }\n const message = (error as { message?: unknown }).message\n return typeof message === 'string' ? message : null\n}\n","import os from 'node:os'\nimport type { NetworkInterfaceInfo } from 'node:os'\n\nexport interface RouteDiscoveryResult {\n lanIps: string[]\n publicIpv4s: string[]\n publicIpv6s: string[]\n preferredUrls: string[]\n}\n\nconst VIRTUAL_INTERFACE_NAME_PATTERN =\n /(docker|veth|vmnet|vmenet|vbox|virtualbox|vmware|tailscale|zerotier|wireguard|utun|virbr|hyper-v|vethernet|loopback|\\blo\\b|^lo\\d*$|^br-|^bridge\\d+$|^zt|^tun|^tap|awdl|llw|anpi|gif|stf|ipsec|ppp)/iu\n\nconst MAX_LAN_IPS = 4\nconst MAX_PUBLIC_IPV4S = 2\nconst MAX_PUBLIC_IPV6S = 2\n\nexport async function discoverRouteCandidates(options: {\n port: number\n relayBaseUrl: string\n linkId: string\n installId: string\n publicKeyPem: string\n relayBootstrapToken?: string\n fetchImpl?: typeof fetch\n}): Promise<RouteDiscoveryResult> {\n const lanIps = discoverLanIps()\n const publicIps = options.relayBootstrapToken\n ? await observePublicRoute(options).catch(() => ({ publicIpv4s: [], publicIpv6s: [] }))\n : { publicIpv4s: [], publicIpv6s: [] }\n const publicIpv4s = unique(publicIps.publicIpv4s.filter(isUsablePublicIpv4)).slice(0, MAX_PUBLIC_IPV4S)\n const publicIpv6s = unique(publicIps.publicIpv6s.filter(isUsablePublicIpv6)).slice(0, MAX_PUBLIC_IPV6S)\n const preferredUrls = [\n ...lanIps.map((ip) => buildDirectUrl(ip, options.port)),\n ...publicIpv4s.map((ip) => buildDirectUrl(ip, options.port)),\n ...publicIpv6s.map((ip) => buildDirectUrl(ip, options.port)),\n `${options.relayBaseUrl.replace(/\\/+$/u, '')}/api/v1/relay/links/${options.linkId}`,\n ]\n return {\n lanIps,\n publicIpv4s,\n publicIpv6s,\n preferredUrls,\n }\n}\n\nfunction discoverLanIps(): string[] {\n return discoverLanIpsFromInterfaces(os.networkInterfaces())\n}\n\nexport function discoverLanIpsFromInterfaces(interfaces: NodeJS.Dict<NetworkInterfaceInfo[]>): string[] {\n const result = new Set<string>()\n const candidates: Array<{ name: string; address: string }> = []\n for (const [name, items] of Object.entries(interfaces)) {\n if (shouldIgnoreInterface(name)) {\n continue\n }\n for (const item of items ?? []) {\n if (!item.internal && item.address && item.family === 'IPv4' && isUsableLanIpv4(item.address, item.netmask)) {\n candidates.push({ name, address: item.address })\n }\n }\n }\n for (const candidate of candidates.sort(compareLanCandidate)) {\n result.add(candidate.address)\n }\n return [...result].slice(0, MAX_LAN_IPS)\n}\n\nasync function observePublicRoute(options: {\n relayBaseUrl: string\n installId: string\n linkId: string\n publicKeyPem: string\n relayBootstrapToken?: string\n fetchImpl?: typeof fetch\n}): Promise<{ publicIpv4s: string[]; publicIpv6s: string[] }> {\n const fetcher = options.fetchImpl ?? fetch\n const response = await fetcher(`${options.relayBaseUrl.replace(/\\/+$/u, '')}/api/v1/relay/public-route/observe`, {\n method: 'POST',\n headers: {\n authorization: `Bearer ${options.relayBootstrapToken}`,\n 'content-type': 'application/json',\n },\n body: JSON.stringify({\n install_id: options.installId,\n link_id: options.linkId,\n public_key_pem: options.publicKeyPem,\n }),\n })\n const payload = (await response.json().catch(() => null)) as Record<string, unknown> | null\n const record = typeof payload?.record === 'object' && payload.record !== null\n ? (payload.record as Record<string, unknown>)\n : null\n const observed = typeof payload?.observed === 'object' && payload.observed !== null\n ? (payload.observed as Record<string, unknown>)\n : null\n const values = [\n readIpRecord(record?.ipv4),\n readIpRecord(record?.ipv6),\n typeof observed?.ip === 'string' ? observed.ip : null,\n ].filter((value): value is string => Boolean(value))\n return {\n publicIpv4s: unique(values.filter(isUsablePublicIpv4)),\n publicIpv6s: unique(values.filter(isUsablePublicIpv6)),\n }\n}\n\nfunction readIpRecord(value: unknown): string | null {\n if (typeof value !== 'object' || value === null) {\n return null\n }\n const ip = (value as { ip?: unknown }).ip\n return typeof ip === 'string' && ip.trim() ? ip.trim() : null\n}\n\nfunction buildDirectUrl(ip: string, port: number): string {\n return `http://${ip.includes(':') ? `[${ip}]` : ip}:${port}`\n}\n\nfunction shouldIgnoreInterface(name: string): boolean {\n return !name.trim() || VIRTUAL_INTERFACE_NAME_PATTERN.test(name)\n}\n\nfunction compareLanCandidate(left: { name: string; address: string }, right: { name: string; address: string }): number {\n const priority = interfacePriority(left.name) - interfacePriority(right.name)\n return priority || left.name.localeCompare(right.name) || left.address.localeCompare(right.address)\n}\n\nfunction interfacePriority(name: string): number {\n if (/^(en|eth|wlan|wi-fi|wifi)/iu.test(name)) {\n return 0\n }\n return 1\n}\n\nfunction isUsableLanIpv4(address: string, netmask?: string): boolean {\n return isPrivateIpv4(address) && !isNetworkOrBroadcastIpv4Address(address, netmask)\n}\n\nfunction isUsablePublicIpv4(address: string): boolean {\n return isValidIpv4(address) && !isSpecialIpv4(address)\n}\n\nfunction isUsablePublicIpv6(address: string): boolean {\n const normalized = address.toLowerCase()\n return (\n normalized.includes(':') &&\n !normalized.startsWith('fe80:') &&\n !normalized.startsWith('fc') &&\n !normalized.startsWith('fd') &&\n !normalized.startsWith('ff') &&\n normalized !== '::' &&\n normalized !== '::1'\n )\n}\n\nfunction isPrivateIpv4(address: string): boolean {\n const parts = parseIpv4Segments(address)\n if (!parts) {\n return false\n }\n const [first, second] = parts\n return first === 10 || (first === 172 && second >= 16 && second <= 31) || (first === 192 && second === 168)\n}\n\nfunction isSpecialIpv4(address: string): boolean {\n const parts = parseIpv4Segments(address)\n if (!parts) {\n return true\n }\n const [first, second, third, fourth] = parts\n return (\n first === 0 ||\n first === 10 ||\n first === 127 ||\n first >= 224 ||\n (first === 100 && second >= 64 && second <= 127) ||\n (first === 169 && second === 254) ||\n (first === 172 && second >= 16 && second <= 31) ||\n (first === 192 && second === 168) ||\n (first === 192 && second === 0 && third === 2) ||\n (first === 198 && (second === 18 || second === 19)) ||\n (first === 198 && second === 51 && third === 100) ||\n (first === 203 && second === 0 && third === 113) ||\n (first === 255 && second === 255 && third === 255 && fourth === 255)\n )\n}\n\nfunction isNetworkOrBroadcastIpv4Address(address: string, netmask?: string): boolean {\n const addressParts = parseIpv4Segments(address)\n const netmaskParts = netmask ? parseIpv4Segments(netmask) : null\n if (!addressParts) {\n return true\n }\n if (!netmaskParts) {\n const last = addressParts[3]\n return last === 0 || last === 255\n }\n const addressInt = ipv4SegmentsToInt(addressParts)\n const netmaskInt = ipv4SegmentsToInt(netmaskParts)\n const hostMask = (~netmaskInt) >>> 0\n if (hostMask === 0) {\n return false\n }\n const networkInt = addressInt & netmaskInt\n const broadcastInt = (networkInt | hostMask) >>> 0\n return addressInt === networkInt || addressInt === broadcastInt\n}\n\nfunction isValidIpv4(address: string): boolean {\n return Boolean(parseIpv4Segments(address))\n}\n\nfunction parseIpv4Segments(address: string): [number, number, number, number] | null {\n if (!/^\\d{1,3}(?:\\.\\d{1,3}){3}$/u.test(address)) {\n return null\n }\n const parts = address.split('.').map((part) => Number.parseInt(part, 10))\n if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) {\n return null\n }\n return parts as [number, number, number, number]\n}\n\nfunction ipv4SegmentsToInt(parts: [number, number, number, number]): number {\n return (((parts[0] << 24) >>> 0) | (parts[1] << 16) | (parts[2] << 8) | parts[3]) >>> 0\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)]\n}\n","import type Router from '@koa/router'\nimport { LINK_VERSION } from '../../constants.js'\nimport { loadConfig } from '../../config/config.js'\nimport { readLinkUsageStatistics } from '../../database/link-database.js'\nimport { listHermesCronJobs } from '../../hermes/api-server.js'\nimport { readHermesApiServerHealth } from '../../hermes/gateway.js'\nimport {\n listHermesProfiles,\n type HermesProfile,\n} from '../../hermes/profiles.js'\nimport {\n readHermesUpdateCheck,\n readHermesUpdateStatus,\n} from '../../hermes/updates.js'\nimport { readLinkUpdateCheck } from '../../link/updates.js'\nimport { loadIdentity } from '../../identity/identity.js'\nimport { claimPairing, recordPairingClaim } from '../../pairing/pairing.js'\nimport {\n createDeviceSession,\n hideRevokedDeviceFromAppList,\n listDevices,\n readDeviceSummary,\n recordDeviceSeen,\n renameDeviceById,\n refreshDeviceSession,\n revokeDeviceById,\n revokeDeviceRefreshToken,\n} from '../../security/devices.js'\nimport {\n type LogEntry,\n readRecentGatewayLogEntries,\n readRecentLogEntries,\n type FileLogger,\n} from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { discoverRouteCandidates } from '../../topology/network.js'\nimport { authenticateRequest, loadRequiredIdentity } from '../auth.js'\nimport { LinkHttpError } from '../errors.js'\nimport {\n readJsonBody,\n readLimit,\n readLogSource,\n readBoolean,\n readString,\n routeObjects,\n} from '../request.js'\n\nconst GATEWAY_ERROR_LOOKBACK_HOURS = 12\n\nexport function registerSystemRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n onPairingClaimed?: () => void | Promise<void>\n },\n): void {\n const { paths, logger } = options\n\n router.get('/api/v1/bootstrap', async (ctx) => {\n const [identity, config] = await Promise.all([\n loadIdentity(paths),\n loadConfig(paths),\n ])\n const routes = identity?.link_id\n ? await discoverRouteCandidates({\n port: config.port,\n relayBaseUrl: config.relayBaseUrl,\n linkId: identity.link_id,\n installId: identity.install_id,\n publicKeyPem: identity.public_key_pem,\n })\n : null\n ctx.set('cache-control', 'no-store')\n ctx.body = {\n link_id: identity?.link_id ?? null,\n display_name: identity?.link_id ? 'Hermes Link' : 'Unpaired Hermes Link',\n version: LINK_VERSION,\n api_version: 1,\n paired: Boolean(identity?.link_id),\n pairing_supported: Boolean(identity?.link_id),\n preferred_pairing_urls: routes?.preferredUrls ?? [],\n routes: routes ? routeObjects(routes.preferredUrls) : [],\n capabilities: {\n runs: true,\n sse: true,\n relay: true,\n profiles: true,\n logs: true,\n statistics: true,\n conversations: true,\n conversation_events: true,\n conversation_delete: true,\n conversation_bulk_delete: true,\n conversation_cancel: true,\n conversation_rename: true,\n blobs: true,\n devices: true,\n device_delete: true,\n device_revoke: true,\n device_rename: true,\n device_session_enroll: true,\n cron_jobs: true,\n profile_skills: true,\n profile_memory: true,\n hermes_updates: true,\n },\n }\n })\n\n router.post('/api/v1/pairing/claim', async (ctx) => {\n const body = await readJsonBody(ctx.req)\n const sessionId =\n readString(body, 'session_id') ?? readString(body, 'sessionId')\n const claimToken =\n readString(body, 'claim_token') ?? readString(body, 'claimToken')\n if (!sessionId || !claimToken) {\n throw new LinkHttpError(\n 400,\n 'pairing_claim_invalid',\n 'session_id and claim_token are required',\n )\n }\n const claimed = await claimPairing({\n sessionId,\n claimToken,\n deviceLabel:\n readString(body, 'device_label') ??\n readString(body, 'deviceLabel') ??\n 'HermesPilot App',\n devicePlatform:\n readString(body, 'device_platform') ??\n readString(body, 'devicePlatform') ??\n 'unknown',\n deviceModel:\n readString(body, 'device_model') ?? readString(body, 'deviceModel'),\n appInstanceId:\n readString(body, 'app_instance_id') ??\n readString(body, 'appInstanceId'),\n paths,\n })\n ctx.body = claimed\n void logger.info('pairing_claimed', {\n device_id: claimed.device.device_id,\n device_platform: claimed.device.platform,\n })\n const timer = setTimeout(() => {\n void recordPairingClaim(\n {\n sessionId,\n deviceId: claimed.device.device_id,\n deviceLabel: claimed.device.label,\n devicePlatform: claimed.device.platform,\n },\n paths,\n ).catch((error: unknown) => {\n void logger.warn('pairing_claim_record_failed', {\n session_id: sessionId,\n error: error instanceof Error ? error.message : String(error),\n })\n })\n void options.onPairingClaimed?.()\n }, 250)\n timer.unref?.()\n })\n\n router.get('/api/v1/auth/me', async (ctx) => {\n const auth = await authenticateRequest(ctx, paths)\n const identity = await loadRequiredIdentity(paths)\n const device = auth.device\n ? (await recordDeviceSeen(\n auth.device.id,\n {\n appInstanceId: readAppInstanceIdHeader(ctx),\n model: readDeviceModelHeader(ctx),\n },\n paths,\n )) ?? auth.device\n : null\n ctx.body = {\n ok: true,\n auth: { kind: auth.kind, account_id: auth.accountId ?? null },\n link: {\n link_id: identity.link_id,\n display_name: 'Hermes Link',\n },\n device: device\n ? {\n id: device.id,\n device_id: device.id,\n label: device.label,\n platform: device.platform,\n model: device.model ?? null,\n scope: device.scope,\n }\n : null,\n }\n })\n\n router.post('/api/v1/auth/device-session', async (ctx) => {\n const auth = await authenticateRequest(ctx, paths)\n if (auth.kind !== 'app-connect') {\n throw new LinkHttpError(\n 403,\n 'app_connect_required',\n 'App connect token is required to create a device session',\n )\n }\n if (auth.scopes && auth.scopes.length > 0 && !auth.scopes.includes('device:enroll')) {\n throw new LinkHttpError(\n 403,\n 'device_enroll_scope_required',\n 'App connect token cannot enroll a device',\n )\n }\n\n const identity = await loadRequiredIdentity(paths)\n const body = await readJsonBody(ctx.req)\n const session = await createDeviceSession(\n {\n label:\n readString(body, 'device_label') ??\n readString(body, 'deviceLabel') ??\n 'HermesPilot App',\n platform:\n readString(body, 'device_platform') ??\n readString(body, 'devicePlatform') ??\n 'unknown',\n model:\n readString(body, 'device_model') ?? readString(body, 'deviceModel'),\n appInstanceId: auth.appInstanceId,\n },\n paths,\n )\n ctx.body = {\n ok: true,\n link: {\n link_id: identity.link_id,\n display_name: 'Hermes Link',\n },\n device: session.device,\n access_token: {\n token: session.accessToken.token,\n expires_at: session.accessToken.expiresAt,\n },\n refresh_token: {\n token: session.refreshToken.token,\n expires_at: session.refreshToken.expiresAt,\n },\n }\n void logger.info('device_session_enrolled', {\n account_id: auth.accountId ?? null,\n device_id: session.device.device_id,\n device_platform: session.device.platform,\n })\n })\n\n router.post('/api/v1/auth/refresh', async (ctx) => {\n const body = await readJsonBody(ctx.req)\n const refreshToken =\n readString(body, 'refresh_token') ?? readString(body, 'refreshToken')\n if (!refreshToken) {\n throw new LinkHttpError(\n 400,\n 'refresh_token_required',\n 'refresh_token is required',\n )\n }\n const session = await refreshDeviceSession(\n refreshToken,\n {\n appInstanceId:\n readString(body, 'app_instance_id') ??\n readString(body, 'appInstanceId'),\n label:\n readString(body, 'device_label') ?? readString(body, 'deviceLabel'),\n platform:\n readString(body, 'device_platform') ??\n readString(body, 'devicePlatform'),\n model:\n readString(body, 'device_model') ?? readString(body, 'deviceModel'),\n },\n paths,\n )\n ctx.body = {\n ok: true,\n device: session.device,\n access_token: {\n token: session.accessToken.token,\n expires_at: session.accessToken.expiresAt,\n },\n refresh_token: {\n token: session.refreshToken.token,\n expires_at: session.refreshToken.expiresAt,\n },\n }\n })\n\n router.post('/api/v1/auth/logout', async (ctx) => {\n const body = await readJsonBody(ctx.req)\n const refreshToken =\n readString(body, 'refresh_token') ?? readString(body, 'refreshToken')\n if (refreshToken) {\n await revokeDeviceRefreshToken(refreshToken, paths)\n }\n ctx.body = { ok: true }\n })\n\n router.get('/api/v1/status', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n const [\n identity,\n config,\n health,\n devices,\n profiles,\n hermesUpdate,\n hermesUpdateStatus,\n linkUpdate,\n usage,\n gatewayLogs,\n ] = await Promise.all([\n loadIdentity(paths),\n loadConfig(paths),\n readHermesApiServerHealth().catch((error: unknown) => ({\n healthy: false,\n issue: error instanceof Error ? error.message : String(error),\n })),\n readDeviceSummary(paths),\n listHermesProfiles(paths).catch(() => []),\n readHermesUpdateCheck({ paths, logger, refreshRemote: true }).catch(\n (error: unknown) => ({\n ok: true as const,\n local: {\n version: null,\n raw: error instanceof Error ? error.message : String(error),\n },\n remote: null,\n update_available: false,\n check_state: 'unavailable' as const,\n issue: error instanceof Error ? error.message : String(error),\n }),\n ),\n readHermesUpdateStatus(paths).catch((error: unknown) => ({\n ok: true as const,\n state: 'failed' as const,\n job_id: null,\n pid: null,\n started_at: null,\n finished_at: null,\n exit_code: null,\n signal: null,\n log_path: '',\n lines: [],\n error: error instanceof Error ? error.message : String(error),\n })),\n readLinkUpdateCheck({ paths, logger }).catch((error: unknown) => ({\n ok: true as const,\n local: { version: LINK_VERSION, raw: LINK_VERSION },\n remote: null,\n state: 'unknown' as const,\n update_available: false,\n unsafe: false,\n blocked: false,\n check_state: 'unavailable' as const,\n issue: error instanceof Error ? error.message : String(error),\n manual: {\n command: null,\n package: '@hermespilot/link',\n version: null,\n },\n })),\n readLinkUsageStatistics(paths, { days: 7 }).catch(() => null),\n readRecentGatewayLogEntries({ paths, limit: 1000 }).catch(() => []),\n ])\n const hermesUpdateRunning = hermesUpdateStatus.state === 'running'\n const activeCronJobs = await readActiveCronJobCount(profiles, logger).catch(\n () => 0,\n )\n const gatewayLogsWithinWindow = filterLogsWithinHours(\n gatewayLogs,\n GATEWAY_ERROR_LOOKBACK_HOURS,\n )\n const gatewayLogErrorCount = gatewayLogsWithinWindow.filter(\n (entry) => entry.level === 'error',\n ).length\n ctx.body = {\n ok: true,\n version: LINK_VERSION,\n paired: Boolean(identity?.link_id),\n link_id: identity?.link_id ?? null,\n port: config.port,\n link: {\n state: 'online',\n version: LINK_VERSION,\n update_available: linkUpdate.update_available,\n update: linkUpdate,\n },\n hermes: {\n local_version: hermesUpdate.local.version,\n local_raw: hermesUpdate.local.raw,\n latest_release_version: hermesUpdate.remote?.version ?? null,\n latest_release_tag: hermesUpdate.remote?.tag ?? null,\n latest_release_url: hermesUpdate.remote?.releaseUrl ?? null,\n update_available: hermesUpdate.update_available,\n check_state: hermesUpdate.check_state,\n issue: hermesUpdate.issue,\n update: hermesUpdateStatus,\n },\n gateway: {\n state: hermesUpdateRunning\n ? 'updating'\n : health.healthy\n ? 'running'\n : 'unavailable',\n issue: hermesUpdateRunning\n ? 'Hermes Agent 正在升级,Gateway 暂时处于维护状态。'\n : (health.issue ?? null),\n },\n api_server: {\n state: hermesUpdateRunning\n ? 'updating'\n : health.healthy\n ? 'available'\n : 'unavailable',\n issue: hermesUpdateRunning\n ? 'Hermes Agent 正在升级,API Server 暂时不可用于新请求。'\n : (health.issue ?? null),\n },\n devices,\n profiles: {\n total: profiles.length,\n },\n summary: {\n profiles: {\n total: profiles.length,\n },\n cron_jobs: {\n active: activeCronJobs,\n },\n usage: {\n range: {\n days: usage?.range.days ?? 7,\n },\n total_tokens: usage?.totals.total_tokens ?? 0,\n },\n gateway_logs: {\n checked: gatewayLogsWithinWindow.length,\n error_count: gatewayLogErrorCount,\n state: gatewayLogErrorCount > 0 ? 'error' : 'normal',\n },\n },\n }\n })\n\n router.get('/api/v1/logs', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const source = readLogSource(ctx.query.source)\n ctx.set('cache-control', 'no-store')\n ctx.body = {\n ok: true,\n source,\n logs:\n source === 'gateway'\n ? await readRecentGatewayLogEntries({\n paths,\n limit: readLimit(ctx.query.limit),\n })\n : await readRecentLogEntries({\n paths,\n limit: readLimit(ctx.query.limit),\n }),\n }\n })\n\n router.get('/api/v1/devices', async (ctx) => {\n const auth = await authenticateRequest(ctx, paths)\n const currentDevice = auth.device\n ? (await recordDeviceSeen(\n auth.device.id,\n {\n appInstanceId: readAppInstanceIdHeader(ctx),\n model: readDeviceModelHeader(ctx),\n },\n paths,\n )) ?? auth.device\n : null\n const [devices, summary] = await Promise.all([\n listDevices(paths),\n readDeviceSummary(paths),\n ])\n const currentDeviceId = currentDevice?.id ?? null\n ctx.set('cache-control', 'no-store')\n ctx.body = {\n ok: true,\n current_device_id: currentDeviceId,\n devices: devices.map((device) => ({\n ...device,\n current: currentDeviceId === device.id,\n })),\n summary,\n }\n })\n\n router.delete('/api/v1/devices/:deviceId', async (ctx) => {\n const auth = await authenticateRequest(ctx, paths)\n const device = await revokeDeviceById(ctx.params.deviceId, paths)\n const summary = await readDeviceSummary(paths)\n ctx.body = {\n ok: true,\n current_device_revoked: auth.device?.id === device.id,\n device: {\n ...device,\n current: auth.device?.id === device.id,\n },\n summary,\n }\n void logger.info('device_revoked', {\n device_id: device.id,\n current_device_revoked: auth.device?.id === device.id,\n auth_kind: auth.kind,\n })\n })\n\n router.delete('/api/v1/devices/:deviceId/app-listing', async (ctx) => {\n const auth = await authenticateRequest(ctx, paths)\n const device = await hideRevokedDeviceFromAppList(\n ctx.params.deviceId,\n paths,\n )\n const summary = await readDeviceSummary(paths)\n ctx.body = {\n ok: true,\n device: {\n ...device,\n current: auth.device?.id === device.id,\n },\n summary,\n }\n void logger.info('device_app_listing_deleted', {\n device_id: device.id,\n auth_kind: auth.kind,\n })\n })\n\n router.patch('/api/v1/devices/:deviceId', async (ctx) => {\n const auth = await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n const label = readString(body, 'label') ?? readString(body, 'device_label')\n if (!label) {\n throw new LinkHttpError(\n 400,\n 'device_label_required',\n 'Device label is required',\n )\n }\n const device = await renameDeviceById(ctx.params.deviceId, label, paths)\n ctx.body = {\n ok: true,\n device: {\n ...device,\n current: auth.device?.id === device.id,\n },\n }\n void logger.info('device_renamed', {\n device_id: device.id,\n auth_kind: auth.kind,\n })\n })\n}\n\nasync function readActiveCronJobCount(\n profiles: HermesProfile[],\n logger: FileLogger,\n): Promise<number> {\n const results = await Promise.allSettled(\n profiles.map((profile) =>\n listHermesCronJobs({\n logger,\n profileName: profile.name,\n includeDisabled: true,\n }),\n ),\n )\n return results.reduce((total, result) => {\n if (result.status !== 'fulfilled') {\n return total\n }\n return total + result.value.filter(isActiveCronJob).length\n }, 0)\n}\n\nfunction isActiveCronJob(job: Record<string, unknown>): boolean {\n const enabled = readBoolean(job.enabled) ?? true\n if (!enabled) {\n return false\n }\n const state = readString(job, 'state')?.toLowerCase()\n return !['paused', 'disabled', 'completed', 'deleted'].includes(state ?? '')\n}\n\nfunction filterLogsWithinHours(\n logs: LogEntry[],\n hours: number,\n now = Date.now(),\n): LogEntry[] {\n const cutoff = now - Math.max(1, hours) * 60 * 60 * 1000\n return logs.filter((entry) => {\n if (entry.timestampSource === 'file_mtime') {\n return false\n }\n const timestamp = entry.ts\n if (!timestamp) {\n return false\n }\n const time = Date.parse(timestamp)\n return Number.isFinite(time) && time >= cutoff\n })\n}\n\nfunction readAppInstanceIdHeader(ctx: { get(name: string): string }): string | null {\n const value = ctx.get('x-hermes-app-instance-id').trim()\n return /^appi_[A-Za-z0-9_-]{16,96}$/u.test(value) ? value : null\n}\n\nfunction readDeviceModelHeader(ctx: { get(name: string): string }): string | null {\n const value = ctx.get('x-hermes-device-model').trim()\n return value ? value.slice(0, 128) : null\n}\n","import type { ServerResponse } from 'node:http'\nimport type Router from '@koa/router'\nimport {\n readHermesUpdateCheck,\n readHermesUpdateStatus,\n startHermesUpdate,\n subscribeHermesUpdateStatus,\n type HermesUpdateJobStatus,\n} from '../../hermes/updates.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\n\nexport function registerHermesUpdateRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n },\n): void {\n const { paths, logger } = options\n\n router.get('/api/v1/hermes/update-check', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await readHermesUpdateCheck({\n paths,\n logger,\n refreshRemote: true,\n })\n })\n\n router.get('/api/v1/hermes/update/status', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await readHermesUpdateStatus(paths)\n })\n\n router.post('/api/v1/hermes/update', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.status = 202\n ctx.body = await startHermesUpdate({ paths, logger })\n })\n\n router.get('/api/v1/hermes/update/events', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.respond = false\n const response = ctx.res\n response.statusCode = 200\n response.setHeader('content-type', 'text/event-stream; charset=utf-8')\n response.setHeader('cache-control', 'no-store')\n response.setHeader('connection', 'keep-alive')\n\n writeUpdateSseEvent(response, await readHermesUpdateStatus(paths))\n const unsubscribe = subscribeHermesUpdateStatus((status) => {\n writeUpdateSseEvent(response, status)\n })\n const cleanup = () => {\n unsubscribe()\n response.end()\n }\n ctx.req.on('close', cleanup)\n })\n}\n\nfunction writeUpdateSseEvent(\n response: ServerResponse,\n status: HermesUpdateJobStatus,\n): void {\n response.write('event: hermes.update.status\\n')\n response.write(`data: ${JSON.stringify(status)}\\n\\n`)\n}\n","import type { ServerResponse } from 'node:http'\nimport type Router from '@koa/router'\nimport {\n readLinkUpdateCheck,\n readLinkUpdateStatus,\n startLinkUpdate,\n subscribeLinkUpdateStatus,\n type LinkUpdateJobStatus,\n} from '../../link/updates.js'\nimport type { FileLogger } from '../../runtime/logger.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { authenticateRequest } from '../auth.js'\nimport { readJsonBody, readString } from '../request.js'\n\nexport function registerLinkUpdateRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n logger: FileLogger\n },\n): void {\n const { paths, logger } = options\n\n router.get('/api/v1/link/update-check', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await readLinkUpdateCheck({ paths, logger })\n })\n\n router.get('/api/v1/link/update/status', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.set('cache-control', 'no-store')\n ctx.body = await readLinkUpdateStatus(paths)\n })\n\n router.post('/api/v1/link/update', async (ctx) => {\n await authenticateRequest(ctx, paths)\n const body = await readJsonBody(ctx.req)\n ctx.status = 202\n ctx.body = await startLinkUpdate({\n paths,\n logger,\n targetVersion:\n readString(body, 'target_version') ?? readString(body, 'targetVersion'),\n })\n })\n\n router.get('/api/v1/link/update/events', async (ctx) => {\n await authenticateRequest(ctx, paths)\n ctx.respond = false\n const response = ctx.res\n response.statusCode = 200\n response.setHeader('content-type', 'text/event-stream; charset=utf-8')\n response.setHeader('cache-control', 'no-store')\n response.setHeader('connection', 'keep-alive')\n\n writeUpdateSseEvent(response, await readLinkUpdateStatus(paths))\n const unsubscribe = subscribeLinkUpdateStatus((status) => {\n writeUpdateSseEvent(response, status)\n })\n const cleanup = () => {\n unsubscribe()\n response.end()\n }\n ctx.req.on('close', cleanup)\n })\n}\n\nfunction writeUpdateSseEvent(\n response: ServerResponse,\n status: LinkUpdateJobStatus,\n): void {\n response.write('event: link.update.status\\n')\n response.write(`data: ${JSON.stringify(status)}\\n\\n`)\n}\n","import type Router from '@koa/router'\nimport QRCode from 'qrcode'\nimport { LINK_VERSION } from '../../constants.js'\nimport { loadConfig } from '../../config/config.js'\nimport { loadIdentity } from '../../identity/identity.js'\nimport {\n readPairingClaim,\n readPairingSession,\n type PairingSessionRecord,\n} from '../../pairing/pairing.js'\nimport type { RuntimePaths } from '../../runtime/paths.js'\nimport { LinkHttpError } from '../errors.js'\nimport { readString } from '../request.js'\n\nexport function registerPairingRoutes(\n router: Router,\n options: {\n paths: RuntimePaths\n },\n): void {\n const { paths } = options\n\n router.get('/pair', async (ctx) => {\n const sessionId = readString(ctx.query as Record<string, unknown>, 'session_id')\n if (!sessionId) {\n throw new LinkHttpError(400, 'pairing_session_required', 'session_id is required')\n }\n const [session, config, identity] = await Promise.all([\n readPairingSession(sessionId, paths),\n loadConfig(paths),\n loadIdentity(paths),\n ])\n if (!session) {\n throw new LinkHttpError(404, 'pairing_session_not_found', 'Pairing session was not found')\n }\n const state = await readPairingState(sessionId, paths)\n const page = await renderPairingPage({\n session,\n state,\n version: LINK_VERSION,\n port: config.port,\n linkId: identity?.link_id ?? session.link_id,\n })\n ctx.set('content-type', 'text/html; charset=utf-8')\n ctx.set('cache-control', 'no-store')\n ctx.body = page\n })\n\n router.get('/api/v1/pairing/session', async (ctx) => {\n const sessionId = readString(ctx.query as Record<string, unknown>, 'session_id')\n if (!sessionId) {\n throw new LinkHttpError(400, 'pairing_session_required', 'session_id is required')\n }\n const session = await readPairingSession(sessionId, paths)\n if (!session) {\n throw new LinkHttpError(404, 'pairing_session_not_found', 'Pairing session was not found')\n }\n ctx.set('cache-control', 'no-store')\n ctx.body = {\n ok: true,\n session: {\n ...session,\n claimed: Boolean(await readPairingState(sessionId, paths).then((state) => state.claimed)),\n },\n }\n })\n}\n\nasync function readPairingState(sessionId: string, paths: RuntimePaths) {\n const claim = await readPairingClaim(sessionId, paths)\n const session = await readPairingSession(sessionId, paths)\n return {\n claimed: Boolean(claim),\n claim,\n expiresAt: session?.expires_at ?? null,\n }\n}\n\nasync function renderPairingPage(input: {\n session: PairingSessionRecord\n state: { claimed: boolean; claim: Awaited<ReturnType<typeof readPairingClaim>>; expiresAt: string | null }\n version: string\n port: number\n linkId: string | null\n}): Promise<string> {\n const session = input.session\n const qrPayload = JSON.stringify({\n kind: 'hermes_link_pairing',\n version: 1,\n link_id: session.link_id,\n display_name: session.display_name,\n session_id: session.session_id,\n code: session.code,\n preferred_urls: session.preferred_urls,\n })\n const qrSvg = await QRCode.toString(qrPayload, {\n type: 'svg',\n margin: 1,\n width: 320,\n errorCorrectionLevel: 'M',\n })\n const qrDataUri = `data:image/svg+xml;base64,${Buffer.from(qrSvg).toString('base64')}`\n const currentUrl = session.local_api_url.replace(/\\/+$/u, '')\n const linkIdLabel = escapeHtml(input.linkId ?? session.link_id)\n const expiresLabel = escapeHtml(formatDate(session.expires_at))\n const statusLabel = input.state.claimed ? '已完成配对' : '等待 App 扫码'\n const statusHint = input.state.claimed\n ? 'App 已完成配对,这个页面可以关闭。'\n : '打开 App 扫码,或者复制配对码手动输入。'\n\n return `<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta name=\"color-scheme\" content=\"light dark\" />\n <title>Hermes Link Pairing</title>\n <style>\n :root {\n color-scheme: light dark;\n --bg: #f4f5f7;\n --panel: rgba(255, 255, 255, 0.78);\n --panel-strong: rgba(255, 255, 255, 0.94);\n --text: #151922;\n --muted: #5f6673;\n --line: rgba(21, 25, 34, 0.12);\n --accent: #2d5cff;\n --accent-soft: rgba(45, 92, 255, 0.12);\n --good: #0b8457;\n --shadow: 0 24px 90px rgba(18, 24, 38, 0.12);\n }\n @media (prefers-color-scheme: dark) {\n :root {\n --bg: #0c1017;\n --panel: rgba(16, 20, 28, 0.78);\n --panel-strong: rgba(16, 20, 28, 0.94);\n --text: #eef2f8;\n --muted: #9ba4b3;\n --line: rgba(255, 255, 255, 0.12);\n --accent: #8ab4ff;\n --accent-soft: rgba(138, 180, 255, 0.12);\n --good: #67d7a7;\n --shadow: 0 24px 90px rgba(0, 0, 0, 0.45);\n }\n }\n * { box-sizing: border-box; }\n body {\n margin: 0;\n min-height: 100vh;\n font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n color: var(--text);\n background: linear-gradient(180deg, var(--bg) 0%, color-mix(in srgb, var(--bg) 88%, var(--accent) 12%) 100%);\n }\n .shell {\n min-height: 100vh;\n display: grid;\n place-items: center;\n padding: 28px 18px;\n }\n .panel {\n width: min(1040px, 100%);\n border: 1px solid var(--line);\n border-radius: 28px;\n background: var(--panel);\n box-shadow: var(--shadow);\n backdrop-filter: blur(18px);\n overflow: hidden;\n }\n .hero {\n display: grid;\n grid-template-columns: minmax(0, 1.1fr) minmax(320px, 390px);\n gap: 0;\n }\n .copy {\n padding: 34px 34px 30px;\n border-right: 1px solid var(--line);\n }\n .eyebrow {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n padding: 8px 12px;\n border-radius: 999px;\n background: var(--accent-soft);\n color: var(--accent);\n font-size: 13px;\n font-weight: 600;\n letter-spacing: 0;\n }\n h1 {\n margin: 18px 0 12px;\n font-size: clamp(34px, 4vw, 52px);\n line-height: 1.02;\n letter-spacing: 0;\n }\n .subtitle {\n max-width: 42ch;\n margin: 0;\n color: var(--muted);\n font-size: 16px;\n line-height: 1.7;\n }\n .meta-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 14px;\n margin-top: 26px;\n }\n .meta {\n padding: 16px 16px 15px;\n border-radius: 18px;\n background: var(--panel-strong);\n border: 1px solid var(--line);\n }\n .meta-label {\n display: block;\n color: var(--muted);\n font-size: 12px;\n line-height: 1.4;\n margin-bottom: 8px;\n }\n .meta-value {\n font-size: 15px;\n line-height: 1.5;\n word-break: break-word;\n }\n .stack {\n margin-top: 24px;\n display: grid;\n gap: 12px;\n }\n .steps {\n display: grid;\n gap: 10px;\n margin-top: 18px;\n }\n .step {\n display: flex;\n gap: 12px;\n align-items: flex-start;\n padding: 14px 16px;\n border: 1px solid var(--line);\n border-radius: 18px;\n background: var(--panel-strong);\n }\n .step-badge {\n flex: none;\n width: 26px;\n height: 26px;\n border-radius: 999px;\n display: grid;\n place-items: center;\n background: var(--accent-soft);\n color: var(--accent);\n font-size: 13px;\n font-weight: 600;\n }\n .step-title {\n font-size: 14px;\n line-height: 1.45;\n margin: 0;\n font-weight: 600;\n }\n .step-copy {\n margin: 3px 0 0;\n color: var(--muted);\n font-size: 13px;\n line-height: 1.55;\n }\n .qr {\n padding: 26px 26px 30px;\n background: linear-gradient(180deg, rgba(255,255,255,0.16), rgba(255,255,255,0));\n }\n .card {\n border: 1px solid var(--line);\n border-radius: 24px;\n background: var(--panel-strong);\n padding: 20px;\n }\n .status {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n margin-bottom: 18px;\n }\n .status-title {\n margin: 0;\n font-size: 18px;\n line-height: 1.3;\n }\n .pill {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 7px 11px;\n border-radius: 999px;\n background: rgba(11, 132, 87, 0.12);\n color: var(--good);\n font-size: 12px;\n font-weight: 600;\n white-space: nowrap;\n }\n .qr-frame {\n display: grid;\n place-items: center;\n padding: 18px;\n border-radius: 24px;\n background: linear-gradient(180deg, rgba(45, 92, 255, 0.06), rgba(45, 92, 255, 0));\n border: 1px solid var(--line);\n }\n .qr-frame img {\n width: min(100%, 300px);\n aspect-ratio: 1;\n display: block;\n border-radius: 18px;\n background: #fff;\n padding: 14px;\n }\n .code {\n margin-top: 16px;\n padding: 14px 16px;\n border-radius: 18px;\n border: 1px solid var(--line);\n background: rgba(0, 0, 0, 0.03);\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 22px;\n letter-spacing: 0.18em;\n text-align: center;\n user-select: all;\n }\n .footer {\n display: flex;\n justify-content: space-between;\n gap: 18px;\n flex-wrap: wrap;\n padding-top: 16px;\n color: var(--muted);\n font-size: 13px;\n line-height: 1.55;\n }\n .hint {\n margin: 10px 0 0;\n color: var(--muted);\n font-size: 13px;\n line-height: 1.55;\n }\n @media (max-width: 920px) {\n .hero { grid-template-columns: 1fr; }\n .copy { border-right: none; border-bottom: 1px solid var(--line); }\n }\n @media (max-width: 640px) {\n .copy, .qr { padding: 22px 18px; }\n .meta-grid { grid-template-columns: 1fr; }\n .status { align-items: flex-start; flex-direction: column; }\n .code { font-size: 18px; letter-spacing: 0.14em; }\n }\n </style>\n</head>\n<body>\n <main class=\"shell\">\n <section class=\"panel\">\n <div class=\"hero\">\n <div class=\"copy\">\n <span class=\"eyebrow\">Hermes Link · ${escapeHtml(input.version)}</span>\n <h1>在 App 里完成这次配对</h1>\n <p class=\"subtitle\">这不是一张孤零零的二维码。它同时给你配对状态、手动码、有效期和当前本地地址,方便 Windows 传统控制台、远程终端和浏览器打开时都能顺利完成。</p>\n <div class=\"meta-grid\">\n <div class=\"meta\">\n <span class=\"meta-label\">本地地址</span>\n <div class=\"meta-value\">${escapeHtml(currentUrl)}</div>\n </div>\n <div class=\"meta\">\n <span class=\"meta-label\">Link ID</span>\n <div class=\"meta-value\">${linkIdLabel}</div>\n </div>\n <div class=\"meta\">\n <span class=\"meta-label\">配对码</span>\n <div class=\"meta-value\">${escapeHtml(session.code)}</div>\n </div>\n <div class=\"meta\">\n <span class=\"meta-label\">过期时间</span>\n <div class=\"meta-value\">${expiresLabel}</div>\n </div>\n </div>\n <div class=\"stack\">\n <div class=\"step\">\n <div class=\"step-badge\">1</div>\n <div>\n <p class=\"step-title\">在 App 里打开“连接 Hermes Link”</p>\n <p class=\"step-copy\">先登录 HermesPilot 账号,再走扫码或手动码。配对成功后,App 会自动切到这台 Link。</p>\n </div>\n </div>\n <div class=\"step\">\n <div class=\"step-badge\">2</div>\n <div>\n <p class=\"step-title\">扫二维码,或直接输入配对码</p>\n <p class=\"step-copy\">如果扫码不方便,App 里也可以直接输入这个页面显示的配对码。</p>\n </div>\n </div>\n <div class=\"step\">\n <div class=\"step-badge\">3</div>\n <div>\n <p class=\"step-title\">配对成功后,这个页面会自动变成已完成状态</p>\n <p class=\"step-copy\" id=\"statusHint\">${escapeHtml(statusHint)}</p>\n </div>\n </div>\n </div>\n <p class=\"hint\">可在终端继续保留这个页面,方便稍后核对状态;如果配对已经成功,页面不会再要求重新扫码。</p>\n </div>\n <div class=\"qr\">\n <div class=\"card\">\n <div class=\"status\">\n <h2 class=\"status-title\" id=\"statusTitle\">${escapeHtml(statusLabel)}</h2>\n <span class=\"pill\" id=\"statusPill\">${input.state.claimed ? '已扫码' : '等待中'}</span>\n </div>\n <div class=\"qr-frame\">\n <img src=\"${qrDataUri}\" alt=\"Hermes Link pairing QR code\" />\n </div>\n <div class=\"code\">${escapeHtml(session.code)}</div>\n <div class=\"footer\">\n <span>Local API: ${escapeHtml(currentUrl)}</span>\n <span>Relay / Server 会同时准备可用路线</span>\n </div>\n </div>\n </div>\n </div>\n </section>\n </main>\n <script>\n const sessionId = ${JSON.stringify(session.session_id)};\n const refresh = async () => {\n try {\n const response = await fetch('/api/v1/pairing/session?session_id=' + encodeURIComponent(sessionId), {\n headers: { accept: 'application/json' },\n });\n if (!response.ok) return;\n const payload = await response.json();\n if (payload?.session?.claimed) {\n document.querySelector('#statusPill').textContent = '已扫码';\n document.querySelector('#statusTitle').textContent = '已完成配对';\n document.querySelector('#statusHint').textContent = 'App 已完成配对,这个页面可以关闭。';\n }\n } catch (_) {}\n };\n setInterval(refresh, 1500);\n refresh();\n </script>\n</body>\n</html>`\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;')\n}\n\nfunction formatDate(value: string): string {\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? value : date.toLocaleString('zh-CN', { hour12: false })\n}\n"],"mappings":"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","names":["randomUUID","mkdir","readdir","readFile","path","mkdir","randomUUID","path","mkdir","readFile","rename","path","isNodeError","readString","entry","readString","path","readdir","isNodeError","readFile","mkdir","toRecord","randomUUID","mkdir","readFile","readdir","rm","stat","writeFile","path","path","unique","path","toRecord","readString","path","randomUUID","mkdir","writeFile","readFile","isNodeError","rm","stat","readdir","stat","stat","isNodeError","emptySnapshot","execFile","readFile","stat","path","promisify","mkdir","open","readFile","rename","rm","stat","os","path","os","path","path","os","mkdir","path","mkdir","path","os","stat","rm","readFile","open","rename","execFileAsync","promisify","execFile","PROFILE_NAME_PATTERN","normalizeProfileName","path","stat","isNodeError","toRecord","readString","readFile","randomUUID","emptySnapshot","stat","createRequire","path","nodeRequire","createRequire","path","stat","isNodeError","delay","hermesSynced","event","next","randomUUID","randomUUID","run","createHash","readString","toRecord","emptySnapshot","appendFile","mkdir","readdir","readFile","rm","writeFile","path","mkdir","readdir","isNodeError","createEmptySnapshot","appendFile","readFile","writeFile","rm","path","readFile","readdir","stat","path","readString","path","readString","stat","createRequire","path","nodeRequire","createRequire","isValidProfileName","path","stat","isNodeError","execFile","access","readFile","stat","path","promisify","execFileAsync","promisify","execFile","path","stat","access","readFile","toRecord","readString","readErrorMessage","readString","toRecord","readText","readInteger","readErrorMessage","readString","toRecord","stat","isNodeError","readFile","path","readdir","emptySnapshot","randomUUID","message","runtime","randomUUID","mkdir","mkdir","randomUUID","randomBytes","randomUUID","createHash","randomUUID","randomBytes","createHash","decodeJson","normalizeAppInstanceId","readString","readPositiveInteger","readInteger","readAttachmentWaveform","readString","readInteger","mkdir","readdir","readFile","rename","rm","stat","os","path","YAML","PROFILE_NAME_PATTERN","path","os","readdir","isNodeError","stat","rename","stat","isNodeError","rm","path","PROFILE_NAME_PATTERN","isNodeError","readdir","path","readFile","toRecord","YAML","readString","readPositiveInteger","readString","readPositiveInteger","spawn","EventEmitter","copyFile","mkdir","readFile","rm","stat","writeFile","rename","path","YAML","PROFILE_NAME_PATTERN","EventEmitter","mkdir","spawn","normalizeOptionalText","toRecord","ensureRecord","path","readFile","isNodeError","escapeRegExp","formatEnvValue","copyFile","writeFile","rename","rm","YAML","stat","readString","readPositiveInteger","access","copyFile","mkdir","readdir","readFile","rename","stat","writeFile","path","YAML","path","toRecord","mkdir","writeFile","readFile","isNodeError","YAML","copyFile","rename","stat","config","readString","id","registryPath","readdir","access","escapeRegExp","formatEnvValue","readBoolean","readString","readPositiveInteger","copyFile","mkdir","readFile","readdir","rename","writeFile","path","YAML","path","skill","readHermesConfigDocument","ensureRecord","readStringList","writeHermesConfigDocument","readdir","isNodeError","readFile","readString","toRecord","YAML","mkdir","copyFile","writeFile","rename","readString","readInteger","EventEmitter","spawn","mkdir","readFile","rm","path","MAX_OUTPUT_LINE_LENGTH","EventEmitter","compareSemver","mkdir","spawn","isRecentRunningState","isProcessAlive","toRecord","readString","readFile","path","rm","spawn","EventEmitter","mkdir","readFile","rm","path","spawn","mkdir","readFile","rm","path","mkdir","rm","writeFile","delay","rm","mkdir","writeFile","mkdir","spawn","path","isProcessAlive","rm","readFile","UPDATE_LOG_FILE","UPDATE_LOG_MAX_FILES","MAX_UPDATE_LOG_LINES","MAX_OUTPUT_LINE_LENGTH","updateEvents","EventEmitter","runningUpdate","clearUpdateLogFiles","mkdir","writeUpdateState","spawn","emitUpdateStatus","updateStatePath","compareSemver","isRecentRunningState","isProcessAlive","updateLogPath","readUpdateLogLines","toRecord","toNullableRecord","readString","readFile","path","rm","path","rm","readErrorMessage","os","rm","loadRequiredIdentity","path","readJsonResponse","readErrorMessage","readString","readString","writeUpdateSseEvent","readString"]}