negotium 0.2.12 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-helpers.js +31 -6
- package/dist/agent-helpers.js.map +5 -5
- package/dist/background-bash.js +30 -4
- package/dist/background-bash.js.map +4 -4
- package/dist/browser-runtime.js +14 -1
- package/dist/browser-runtime.js.map +3 -3
- package/dist/{chunk-8asy22vc.js → chunk-rnsnhcye.js} +30 -4
- package/dist/{chunk-8asy22vc.js.map → chunk-rnsnhcye.js.map} +4 -4
- package/dist/hosted-agent.js +31 -5
- package/dist/hosted-agent.js.map +5 -5
- package/dist/main.js +31 -6
- package/dist/main.js.map +5 -5
- package/dist/mcp-factories.js +31 -6
- package/dist/mcp-factories.js.map +5 -5
- package/dist/prompts.js +14 -1
- package/dist/prompts.js.map +3 -3
- package/dist/query-runtime.js +14 -1
- package/dist/query-runtime.js.map +3 -3
- package/dist/registry.js +3 -3
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +1 -1
- package/dist/runtime/src/platform/background-bash/manager.ts +35 -3
- package/dist/runtime/src/platform/config.ts +32 -0
- package/dist/runtime/src/runtime/bashrs-completions.ts +268 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js +14 -1
- package/dist/runtime-helpers.js.map +3 -3
- package/dist/types/packages/core/src/platform/config.d.ts +18 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js +14 -1
- package/dist/vault.js.map +3 -3
- package/install-bash-rs.mjs +77 -0
- package/package.json +3 -2
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
"import type { ForkHandle } from \"#agents/fork\";\nimport type { AskReplySource } from \"#storage/session-asks\";\nimport type { AgentKind, EffortLevel } from \"#types\";\n\n/**\n * What `handleAgentQuery` did with the request. Callers that own resources\n * tied to the params (e.g. an ask-fork rollout) use this to decide cleanup:\n * \"ran\"/\"queued\" transfer ownership to the query layer, \"dropped\" returns it.\n */\nexport type HandleAgentQueryOutcome = \"ran\" | \"queued\" | \"dropped\";\n\n// --- Parameter interfaces ---\n\ninterface BaseQueryParams {\n chatId: number;\n userId: number;\n topicName: string;\n sessionId: string | null;\n prompt: string;\n}\n\ninterface OutputParams {\n messageThreadId?: number;\n systemPrompt: string;\n cwd?: string;\n sessionType?: \"dm\" | \"forum\" | \"ephemeral\" | \"manager\" | \"cron\";\n model?: string;\n silent?: boolean;\n effort?: EffortLevel;\n /** Override the topic-resolved agent backend. Used by callers like the\n * archiver that run on ephemeral topics and need an explicit provider. */\n agent?: AgentKind;\n}\n\ninterface InterSessionParams {\n from?: string; // \"user\" or sender session name\n depth?: number; // 0 = from user, 1+ = via tell_session\n // For silent ask-reply forks: caller's depth at ask time. When the fork's\n // reply is injected back to the caller, the caller resumes at this depth\n // so tell chain caps remain accurate across ask hops.\n fromDepth?: number;\n requestId?: string; // unique ID for dedup in interSessionQueue\n contextId?: string; // context ID for multi-turn inter-session conversations\n /**\n * Ask-fork rollout backing this inject's `sessionId`. Ownership travels\n * WITH the params: while the inject sits in `interSessionQueue` the rollout\n * must stay on disk (deleting it breaks the dequeued query's resume), and\n * `handleAgentQuery`'s finally removes it once the consuming query actually\n * finished (and no retry/requeue still references it).\n */\n forkHandle?: ForkHandle;\n /** Original ask_session replies represented by this inject, preserved across dequeueAll merges. */\n askReplySources?: AskReplySource[];\n agents?: Record<\n string,\n {\n description: string;\n prompt: string;\n model?: string;\n tools?: string[];\n maxTurns?: number;\n effort?: EffortLevel | number;\n }\n >;\n}\n\ninterface RetryGuardParams {\n _sessionRetried?: boolean; // guard against infinite retry on session expiry\n}\n\nexport interface HandleAgentQueryParams\n extends BaseQueryParams,\n OutputParams,\n InterSessionParams,\n RetryGuardParams {}\n\n// --- Abort reason ---\n\nexport enum AbortReason {\n None = \"none\",\n Internal = \"internal\", // replaced by a newer query on the same topic\n External = \"external\", // /abort command or abort_session via session-inbox\n Infrastructure = \"infrastructure\", // required runtime dependency exited unexpectedly\n}\n",
|
|
13
13
|
"/**\n * Room-keyed in-flight query registry + abort-on-new-message priority +\n * inter-session inject queue (requestId dedup + mergeable-prefix merging).\n *\n * ActiveQueries + SessionInjectQueue semantics, adapted to Otium's REST/WS\n * model where the \"room\" is a `topicId` and the live runner is\n * `api/routes/ai.ts`.\n *\n * Invariant: AT MOST ONE in-flight AI turn per room (topicId). A new turn\n * arriving on a busy room is resolved by origin priority:\n * - incoming user, running user → abort running (superseded), replace\n * - incoming user, running inject → re-queue running inject, abort, replace\n * - incoming inject (any running) → defer incoming (the user keeps priority)\n */\n\nimport type { ForkHandle } from \"#agents/fork\";\nimport { logger } from \"#platform/logger\";\nimport type { UserTurnEnvelope } from \"#runtime/user-turn-envelope\";\nimport {\n claimRuntimeTurnLease,\n getRuntimeTurnLease,\n heartbeatRuntimeTurnLease,\n listRuntimeTurnLeases,\n RUNTIME_INSTANCE_ID,\n type RuntimeTurnLease,\n releaseRuntimeTurnLease,\n requestRuntimeTurnAbort,\n} from \"#storage/runtime-leases\";\nimport type { AskReplySource } from \"#storage/session-asks\";\nimport type { AgentKind, PeerRuntimeBridgeContext } from \"#types\";\nimport { createRoomQueryRegistry, type RoomQueryDecision } from \"./room-query-registry\";\nimport { AbortReason } from \"./types\";\n\nexport { isolatedTurnRoomId, isUserOrigin } from \"./room-query-registry\";\n\n/** Lazily create an isolated provider session immediately before execution. */\nexport type PrepareInjectSession = () => Promise<ForkHandle>;\n\n/** A turn started by a session-inject, replayed when its room frees up. */\nexport interface DeferredInject {\n topicId: string;\n /** Topic execution epoch captured when this work was accepted. */\n runtimeEpoch?: number;\n userId: string;\n /** Credential namespace when the executor and Vault owner differ. */\n vaultUserId?: string;\n prompt: string;\n /** Inject source — the topic name/id this inject came from (never \"user\"). */\n origin: string;\n sourceNode?: string;\n /** Inter-session request id for dedup. */\n requestId?: string;\n /** Nesting depth (starts at 1 for the first cross-topic hop). */\n depth?: number;\n /** Whether this inject is silent (injected but hidden from the user). */\n silent?: boolean;\n /** Context chain id for continuing an inter-session conversation. */\n contextId?: string;\n /** Agent override for injected turns that must resume a provider-specific session. */\n agentOverride?: AgentKind;\n /** Model override for specialized internal turns such as cron. */\n modelOverride?: string;\n /** Effort override for specialized internal turns such as cron. */\n effortOverride?: import(\"#types\").EffortLevel;\n /** SDK-native session/thread id to resume for a forked injected turn. */\n sessionId?: string | null;\n /** Explicit provider-session ownership boundary. */\n sessionScope?: \"topic\" | \"isolated\";\n /** Scheduling boundary. Isolated turns do not occupy or wait for the topic room. */\n turnConcurrency?: \"topic\" | \"isolated\";\n /** Rollout file backing a synthetic/native fork; cleaned when the turn finishes. */\n forkHandle?: ForkHandle;\n /** Build a fresh isolated session at dispatch time (used by ask_session). */\n prepareSession?: PrepareInjectSession;\n /** Working directory override for provider-native resumed sessions. */\n cwd?: string;\n /** Conversation/session namespace override (cron jobs keep isolated rollouts). */\n sessionName?: string;\n /** MCP/tool scope override for a specialized internal turn. */\n sessionType?: \"dm\" | \"forum\" | \"ephemeral\" | \"manager\" | \"cron\";\n /** Adapter-granted access to Otium's visual panel tools. */\n visualTools?: boolean;\n /** Adapter-granted access to chat file-delivery tools. */\n fileDeliveryTools?: boolean;\n /** Optional session owner; when present the topic's main session is not replaced. */\n onSessionId?: (sessionId: string) => void;\n /** Clear an externally-owned session after an unrecoverable expiry. */\n onSessionReset?: () => void;\n /** Rebuild a provider-native rollout from the shared conversation log when needed. */\n bridgeSessionFromHistory?: boolean;\n /** Final result hook for optional modules that own an internal turn. */\n onSettled?: (result: {\n queryId: string;\n kind: \"completed\" | \"aborted\" | \"error\";\n abortReason?: AbortReason;\n error?: string;\n }) => void;\n /** Canonical hub identity for a placed-room runtime turn. */\n peerBridge?: PeerRuntimeBridgeContext;\n /** True after a session-expired recovery retry has already been attempted. */\n _sessionRetried?: boolean;\n /** Original ask_session replies represented by this inject, preserved across dequeueAll merges. */\n askReplySources?: AskReplySource[];\n /** Source marker forwarded to startAiTurn (e.g. FROM_AUTO_CONTINUE). */\n from?: string;\n /** Fired with the AI turn's queryId once the deferred turn is dispatched. */\n onDispatched?: (queryId: string) => void;\n}\n\nexport interface RoomQueryControl {\n topicId: string;\n /** Runtime scheduling/lease key. Defaults to topicId for normal turns. */\n roomId?: string;\n queryId: string;\n /** \"user\" for a human message; otherwise the inject source topic name. */\n origin: string;\n /** Prompt currently being processed. User-turn preemption merges this with the new prompt. */\n prompt: string;\n /** Original user submissions represented by prompt, in arrival order. */\n userMessages?: UserTurnEnvelope[];\n /** Durable request rows whose messages are already represented by userMessages. */\n durableRequestIds?: string[];\n /** Attachment ids currently being processed. User-turn preemption carries them forward. */\n attachments?: string[];\n /** Latest provider session id observed for this turn. */\n sessionId?: string | null;\n /** True once the provider has published the native session backing this turn. */\n providerSessionObserved?: boolean;\n /** True once provider output proves that this turn's prompt reached the native session. */\n providerTurnContentObserved?: boolean;\n abortController: AbortController;\n abortReason: AbortReason;\n /** Specific failure surfaced when infrastructure aborts the turn. */\n abortError?: string;\n /** Epoch ms when this turn claimed the room (stale-abort guard). */\n startedAt?: number;\n /**\n * Set when this turn was started by a session-inject — the params needed to\n * re-enqueue it if a user message preempts it mid-flight. undefined for user\n * turns (a preempted user turn is simply discarded).\n */\n injectParams?: DeferredInject;\n /** True only after this process successfully queued a local replay. */\n injectRequeued?: boolean;\n}\n\n// ── Room-keyed in-flight registry ──────────────────────────────────────\n\nconst roomQueryRegistry = createRoomQueryRegistry<RoomQueryControl, RuntimeTurnLease, AbortReason>({\n instanceId: RUNTIME_INSTANCE_ID,\n internalAbortReason: AbortReason.Internal,\n externalAbortReason: AbortReason.External,\n listLeases: listRuntimeTurnLeases,\n getLease: getRuntimeTurnLease,\n claimLease: claimRuntimeTurnLease,\n heartbeatLease: heartbeatRuntimeTurnLease,\n releaseLease: releaseRuntimeTurnLease,\n requestAbort: requestRuntimeTurnAbort,\n});\n\nexport function getRoomQuery(roomId: string): RoomQueryControl | undefined {\n return roomQueryRegistry.get(roomId);\n}\n\n/** Topic ids and query ids with an in-flight turn in this or another runtime process. */\nexport function listRunningTopicQueries(): Map<string, string> {\n return roomQueryRegistry.listRunningTopicQueries();\n}\n\nexport function listRunningTopicIds(): Set<string> {\n return roomQueryRegistry.listRunningTopicIds();\n}\n\n/** Single-topic status check for callers that do not need a list snapshot. */\nexport function isTopicRunning(topicId: string): boolean {\n return roomQueryRegistry.isTopicRunning(topicId);\n}\n\nexport function getRoomQueryStatus(topicId: string, queryId: string): \"running\" | \"not_found\" {\n return roomQueryRegistry.status(topicId, queryId);\n}\n\nexport function setRoomQuery(control: RoomQueryControl): boolean {\n return roomQueryRegistry.set(control);\n}\n\n/**\n * Delete the room's in-flight entry, but ONLY if it is still this query — a\n * newer turn may have already replaced it (abort-and-replace), and the dying\n * turn's cleanup must not clobber its successor. Mirrors Otium's\n * \"Only delete our own entry\" guard.\n */\nexport function clearRoomQuery(roomId: string, queryId: string): void {\n roomQueryRegistry.clear(roomId, queryId);\n}\n\n/** Abort the currently-running turn in a room, if any. Cleanup is still owned by\n * the streaming turn's finally block so deferred injects drain in order. */\nexport function abortRoom(roomId: string, reason: AbortReason = AbortReason.External): boolean {\n return roomQueryRegistry.abort(roomId, reason);\n}\n\n/** Abort every in-flight provider turn before the node tears down its resources. */\nexport function abortAllRooms(reason: AbortReason = AbortReason.External): number {\n return roomQueryRegistry.abortAll(reason);\n}\n\n// ── Priority decision ──────────────────────────────────────────────────\n\nexport type NewQueryDecision = RoomQueryDecision<RoomQueryControl, RuntimeTurnLease>;\n\n/**\n * Decide what to do when a new turn (with `incomingOrigin`) arrives on a room.\n * Mirrors the abort-on-new-message priority used by live topic turns.\n */\nexport function decideNewQuery(topicId: string, incomingOrigin: string): NewQueryDecision {\n return roomQueryRegistry.decide(topicId, incomingOrigin);\n}\n\n// ── Session-inject queue (inter-session) ───────────────────────────────\n//\n// Session-inject queue for cross-topic ask/tell messages.\n// Key differences: Otium doesn't have per-user concurrency caps, so the key\n// is just the `topicId` (room).\n// `markPendingAskSources` is handled by the MCP layer; the queue here only\n// manages in-memory defer/replay.\n\nexport class InterSessionQueue {\n private queue = new Map<\n string,\n { items: DeferredInject[]; head: number; requestIds: Set<string> }\n >();\n\n private compactOrDelete(\n topicId: string,\n bucket: { items: DeferredInject[]; head: number; requestIds: Set<string> },\n ): void {\n if (bucket.head >= bucket.items.length) {\n this.queue.delete(topicId);\n return;\n }\n // Keep dequeue O(1) on the hot path; compact only when the reclaimed\n // prefix is large enough to justify copying the remaining references.\n if (bucket.head >= 64 && bucket.head * 2 >= bucket.items.length) {\n bucket.items = bucket.items.slice(bucket.head);\n bucket.head = 0;\n }\n }\n\n /** Enqueue inject if requestId is set and not a duplicate. Returns true if enqueued. */\n enqueue(topicId: string, inject: DeferredInject): boolean {\n if (!inject.requestId) {\n logger.error(\n { topicId, origin: inject.origin },\n \"BUG: session inject reached enqueue without requestId — DROPPING inject\",\n );\n return false;\n }\n let bucket = this.queue.get(topicId);\n if (!bucket) {\n bucket = { items: [], head: 0, requestIds: new Set<string>() };\n this.queue.set(topicId, bucket);\n }\n if (bucket.requestIds.has(inject.requestId)) {\n logger.info(\n { topicId, requestId: inject.requestId, origin: inject.origin },\n \"session inject deduped (existing entry with same requestId)\",\n );\n return false;\n }\n bucket.items.push(inject);\n bucket.requestIds.add(inject.requestId);\n logger.info(\n { topicId, origin: inject.origin, requestId: inject.requestId, depth: inject.depth },\n \"session inject enqueued\",\n );\n return true;\n }\n\n /** True when an entry with this requestId is still queued for this topic. */\n hasRequest(topicId: string, requestId: string): boolean {\n return this.queue.get(topicId)?.requestIds.has(requestId) ?? false;\n }\n\n /** Remove and return the next queued inject for this topic, or undefined if empty. */\n dequeueNext(topicId: string): DeferredInject | undefined {\n const bucket = this.queue.get(topicId);\n if (!bucket || bucket.head >= bucket.items.length) return undefined;\n const next = bucket.items[bucket.head++];\n if (next.requestId) bucket.requestIds.delete(next.requestId);\n this.compactOrDelete(topicId, bucket);\n return next;\n }\n\n /**\n * Remove and return the longest mergeable PREFIX of the queue as a single\n * entry, or undefined if empty. Multiple prompts are joined so they land in\n * one turn instead of chaining N turns for N queued injects.\n *\n * Merge rule (mirrors Otium): caller-bound ask_session replies can merge\n * even when they came from different target topics; ordinary inter-session\n * injects remain conservative and require the same origin/silent/session\n * shape. `onDispatched` callbacks from each merged entry are composed.\n */\n dequeueAll(topicId: string): DeferredInject | undefined {\n const bucket = this.queue.get(topicId);\n if (!bucket || bucket.head >= bucket.items.length) return undefined;\n const base = bucket.items[bucket.head];\n const isAskReplyInject = (e: DeferredInject) => !e.silent && Boolean(e.askReplySources?.length);\n const baseIsAskReplyInject = isAskReplyInject(base);\n const mergeable = (e: DeferredInject) =>\n (baseIsAskReplyInject\n ? isAskReplyInject(e)\n : !isAskReplyInject(e) &&\n e.origin === base.origin &&\n (e.silent ?? false) === (base.silent ?? false)) &&\n (e.onDispatched !== undefined) === (base.onDispatched !== undefined) &&\n (e.agentOverride ?? null) === (base.agentOverride ?? null) &&\n (e.modelOverride ?? null) === (base.modelOverride ?? null) &&\n (e.effortOverride ?? null) === (base.effortOverride ?? null) &&\n (e.runtimeEpoch ?? 0) === (base.runtimeEpoch ?? 0) &&\n (e.sessionId ?? null) === (base.sessionId ?? null) &&\n (e.forkHandle?.forkId ?? null) === (base.forkHandle?.forkId ?? null) &&\n (e.prepareSession ?? null) === (base.prepareSession ?? null) &&\n (e.cwd ?? null) === (base.cwd ?? null) &&\n (e.sessionName ?? null) === (base.sessionName ?? null) &&\n (e.sessionType ?? null) === (base.sessionType ?? null) &&\n (e.onSessionId ?? null) === (base.onSessionId ?? null) &&\n (e.onSessionReset ?? null) === (base.onSessionReset ?? null) &&\n (e.bridgeSessionFromHistory ?? false) === (base.bridgeSessionFromHistory ?? false) &&\n (e.onSettled ?? null) === (base.onSettled ?? null);\n let end = bucket.head + 1;\n while (end < bucket.items.length && mergeable(bucket.items[end])) end++;\n const batch = bucket.items.slice(bucket.head, end);\n bucket.head = end;\n for (const entry of batch) {\n if (entry.requestId) bucket.requestIds.delete(entry.requestId);\n }\n this.compactOrDelete(topicId, bucket);\n if (batch.length === 1) return batch[0];\n\n const callbacks = batch\n .map((e) => e.onDispatched)\n .filter((cb): cb is NonNullable<typeof cb> => !!cb);\n const askReplySources = batch.flatMap((e): AskReplySource[] => {\n if (e.askReplySources?.length) return e.askReplySources;\n if (!e.requestId || !e.origin) return [];\n return [{ from: e.origin, requestId: e.requestId, contextId: e.contextId }];\n });\n const depths = batch\n .map((e) => e.depth)\n .filter((depth): depth is number => typeof depth === \"number\");\n return {\n ...base,\n prompt: batch.map((e) => e.prompt).join(\"\\n\\n\"),\n origin: baseIsAskReplyInject\n ? [...new Set(batch.map((e) => e.origin).filter(Boolean))].join(\", \")\n : base.origin,\n depth: depths.length ? Math.min(...depths) : base.depth,\n requestId: `merged-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n // Same-origin batches share one context; only drop it when the batch\n // disagrees (a merged turn must not append to the wrong context).\n contextId: batch.every((e) => e.contextId === base.contextId) ? base.contextId : undefined,\n askReplySources,\n onDispatched: callbacks.length\n ? (queryId: string) => {\n callbacks.forEach((cb) => {\n cb(queryId);\n });\n }\n : undefined,\n };\n }\n\n /** All non-empty queue keys for this topic room. */\n keysForRoom(): string[] {\n return Array.from(this.queue.keys());\n }\n\n /** Drop all queued injects for a topic (e.g. after room abort). */\n drop(topicId: string): void {\n this.queue.delete(topicId);\n }\n\n /** Number of queued injects for a topic. */\n size(topicId: string): number {\n const bucket = this.queue.get(topicId);\n return bucket ? bucket.items.length - bucket.head : 0;\n }\n\n /** Remove one queued inject by request id. Used by bounded background queues. */\n remove(topicId: string, requestId: string): DeferredInject | undefined {\n const bucket = this.queue.get(topicId);\n if (!bucket?.requestIds.has(requestId)) return undefined;\n const index = bucket.items.findIndex(\n (entry, entryIndex) => entryIndex >= bucket.head && entry.requestId === requestId,\n );\n if (index < 0) return undefined;\n const [removed] = bucket.items.splice(index, 1);\n bucket.requestIds.delete(requestId);\n this.compactOrDelete(topicId, bucket);\n return removed;\n }\n}\n\nexport interface DeferredInjectBatcherOptions {\n queue: InterSessionQueue;\n delayMs: number;\n isBusy: (topicId: string) => boolean;\n dispatch: (inject: DeferredInject) => void;\n schedule?: (callback: () => void, delayMs: number) => unknown;\n}\n\n/**\n * Gives caller-bound ask replies a short window to collect before dispatch.\n * `dequeueAll()` only merges entries that are already queued, so the first\n * reply must pass through this gate too when its caller room is idle.\n */\nexport class DeferredInjectBatcher {\n private readonly timers = new Map<string, unknown>();\n private readonly scheduleTimer: (callback: () => void, delayMs: number) => unknown;\n\n constructor(private readonly options: DeferredInjectBatcherOptions) {\n this.scheduleTimer = options.schedule ?? ((callback, delayMs) => setTimeout(callback, delayMs));\n }\n\n enqueue(inject: DeferredInject): boolean {\n const queued = this.options.queue.enqueue(inject.topicId, inject);\n if (!queued) return false;\n if (this.timers.has(inject.topicId)) return true;\n\n const timer = this.scheduleTimer(() => {\n this.timers.delete(inject.topicId);\n // A busy room owns the drain in its turn-finally path. Leaving the\n // entries queued avoids a second dispatcher racing that owner.\n if (this.options.isBusy(inject.topicId)) return;\n const batch = this.options.queue.dequeueAll(inject.topicId);\n if (batch) this.options.dispatch(batch);\n }, this.options.delayMs);\n this.timers.set(inject.topicId, timer);\n return true;\n }\n\n isScheduled(topicId: string): boolean {\n return this.timers.has(topicId);\n }\n}\n\nexport const interSessionQueue = new InterSessionQueue();\n\n// ── Defer / drain helpers (thin wrappers around InterSessionQueue) ────\n\n/**\n * Enqueue a deferred inject. With the full queue, this also deduplicates by\n * requestId.\n */\nexport function deferInject(inject: DeferredInject): boolean {\n return interSessionQueue.enqueue(inject.topicId, inject);\n}\n\n/**\n * Remove and return the longest mergeable batch of deferred injects for a room,\n * or undefined if empty.\n */\nexport function takeDeferredInject(topicId: string): DeferredInject | undefined {\n return interSessionQueue.dequeueAll(topicId);\n}\n\n/** Cancel one deferred inject before it claims the room. */\nexport function cancelDeferredInject(topicId: string, requestId: string): boolean {\n return interSessionQueue.remove(topicId, requestId) !== undefined;\n}\n\n// ── WS discriminator ───────────────────────────────────────────────────\n\n/** Map the internal AbortReason → the WS `ai_aborted` discriminator. */\nexport function wsAbortReason(reason: AbortReason): \"superseded\" | \"stopped\" {\n return reason === AbortReason.Internal ? \"superseded\" : \"stopped\";\n}\n",
|
|
14
14
|
"import { mkdirSync, renameSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport { USERS_LOG_DIR } from \"#platform/config\";\nimport { logger } from \"#platform/logger\";\nimport { sanitizeId } from \"#security/sanitize\";\nimport type { QueryState } from \"#types\";\n\ntype QueryStateUserId = number | string;\n\nexport interface QueryStateStoreLogger {\n warn(context: Record<string, unknown>, message: string): void;\n}\n\nexport interface QueryStateStoreOptions {\n usersLogDir: string;\n logger?: QueryStateStoreLogger;\n sanitizeTopicId?: (topicId: string) => string;\n}\n\nexport interface QueryStateStore {\n write(userId: QueryStateUserId, topicId: string, topicName: string, task?: string): void;\n clear(userId: QueryStateUserId, topicId: string, legacyTopicName?: string): void;\n}\n\nexport function createQueryStateStore(options: QueryStateStoreOptions): QueryStateStore {\n const sanitize = options.sanitizeTopicId ?? sanitizeId;\n const queryStateDirPath = (userId: QueryStateUserId): string =>\n join(options.usersLogDir, String(userId), \"active-queries\");\n const queryStateFile = (userId: QueryStateUserId, topicId: string): string =>\n join(queryStateDirPath(userId), `${sanitize(topicId)}.json`);\n const legacyQueryStateFile = (\n userId: QueryStateUserId,\n topicName: string | undefined,\n ): string | null => {\n if (\n !topicName ||\n topicName === \".\" ||\n topicName === \"..\" ||\n basename(topicName) !== topicName\n ) {\n return null;\n }\n return join(queryStateDirPath(userId), `${topicName}.json`);\n };\n\n return {\n write(userId, topicId, topicName, task) {\n const dir = queryStateDirPath(userId);\n mkdirSync(dir, { recursive: true });\n const state: QueryState = { topicId, topicName, since: new Date().toISOString() };\n if (task) state.task = [...task.replace(/\\n+/g, \" \").trim()].slice(0, 100).join(\"\");\n const target = queryStateFile(userId, topicId);\n const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;\n writeFileSync(tmp, JSON.stringify(state));\n renameSync(tmp, target);\n },\n clear(userId, topicId, legacyTopicName) {\n const paths = [\n queryStateFile(userId, topicId),\n legacyQueryStateFile(userId, legacyTopicName),\n ].filter((path): path is string => Boolean(path));\n for (const path of new Set(paths)) {\n try {\n unlinkSync(path);\n } catch (error) {\n if ((error as NodeJS.ErrnoException)?.code !== \"ENOENT\") {\n options.logger?.warn(\n { err: error, userId, topicId, path },\n \"Failed to clear query state file\",\n );\n }\n }\n }\n },\n };\n}\n\nconst defaultQueryStateStore = createQueryStateStore({\n usersLogDir: USERS_LOG_DIR,\n logger,\n});\n\nexport function writeQueryState(\n userId: QueryStateUserId,\n topicId: string,\n topicName: string,\n task?: string,\n) {\n defaultQueryStateStore.write(userId, topicId, topicName, task);\n}\n\nexport function clearQueryState(\n userId: QueryStateUserId,\n topicId: string,\n legacyTopicName?: string,\n) {\n defaultQueryStateStore.clear(userId, topicId, legacyTopicName);\n}\n",
|
|
15
|
-
"import { execFileSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n accessSync,\n chmodSync,\n constants,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseRuntimePort, readEnvText, safeRuntimePathSegment } from \"#platform/config-helpers\";\nimport { logger } from \"#platform/logger\";\nimport { type AgentKind, isAgentKind } from \"#types\";\n\nexport function envText(envKey: string): string | undefined {\n return readEnvText(process.env, envKey);\n}\n\nfunction resolveAgentEnv(envKey: string, fallback: AgentKind, legacyEnvKey?: string): AgentKind {\n const value = envText(envKey) ?? (legacyEnvKey ? envText(legacyEnvKey) : undefined);\n return isAgentKind(value) ? value : fallback;\n}\n\nconst HOME = homedir();\n\n// new URL(\"../..\", import.meta.url) causes webpack to treat \"../..\" as a module import.\n// Split into fileURLToPath → dirname → resolve to avoid that.\nfunction resolveProjectRoot(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const packagedRuntime = resolve(moduleDir, \"runtime\");\n if (existsSync(resolve(packagedRuntime, \"src\"))) return packagedRuntime;\n return resolve(moduleDir, \"../..\");\n}\n\nexport const PROJECT_ROOT = resolveProjectRoot();\n\n/** Resolve a dependency executable from either a package-local or hoisted install. */\nfunction resolveDependencyBin(name: string): string {\n let dir = PROJECT_ROOT;\n while (true) {\n const candidate = resolve(dir, \"node_modules\", \".bin\", name);\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) return candidate;\n dir = parent;\n }\n}\n\n// Each machine is one negotium node; all node state lives in one dotdir.\n// NEGOTIUM_STATE_DIR overrides (useful for tests and multi-node-on-one-box).\nconst STATE_DIR_ENV = envText(\"NEGOTIUM_STATE_DIR\");\nexport const STATE_DIR = STATE_DIR_ENV ? resolve(STATE_DIR_ENV) : resolve(HOME, \".negotium\");\n\nfunction resolveLocalStateDir(envKey: string, stateName: string): string {\n const envValue = envText(envKey);\n if (envValue) return resolve(envValue);\n return resolve(STATE_DIR, stateName);\n}\n\nfunction parsePortEnv(envValue: string | undefined, fallback: number): number {\n return parseRuntimePort(envValue, fallback);\n}\n\nexport const WORKSPACE_DIR = resolveLocalStateDir(\"NEGOTIUM_WORKSPACE_DIR\", \"workspace\");\nexport const TOPIC_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"topics\");\nexport const SHARED_WIKI_DIR = resolve(WORKSPACE_DIR, \"wiki\");\nexport const CRON_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"cron\");\nexport const BROWSER_DIR = resolveLocalStateDir(\"NEGOTIUM_BROWSER_DIR\", \"browser\");\nexport const BROWSER_PROFILES_DIR = resolve(BROWSER_DIR, \"profiles\");\nexport const BINARIES_DIR = resolve(STATE_DIR, \"binaries\");\nexport const SECRETS_DIR = resolve(STATE_DIR, \"secrets\");\n// Legacy names remain public, but their durable contents now live under data.\nexport const DM_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"dm\");\nexport const SESSION_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"sessions\");\n// The Claude Agent SDK ships a platform-matched Claude Code binary. Keep that\n// SDK/CLI pair together by default; only use an external executable when an\n// operator explicitly opts in. This avoids silently pairing an older SDK with\n// a newer globally installed Claude Code release.\nconst CLAUDE_EXECUTABLE_ENV = envText(\"NEGOTIUM_CLAUDE_EXECUTABLE\");\nexport const CLAUDE_EXECUTABLE = CLAUDE_EXECUTABLE_ENV ? resolve(CLAUDE_EXECUTABLE_ENV) : undefined;\n\n// Fallback output language for model-generated prose (topic/channel/manager\n// replies and the archiver's summaries, briefs, articles, completion reply).\n// Defaults to English; set `NEGOTIUM_LANG` to the user's mother tongue (e.g.\n// `Korean`, `ko`). The assistant still mirrors whatever language the user\n// writes in; `NEGOTIUM_MEMORY_LANG` can narrow just the archiver. Fixed system\n// chrome / degraded-path strings emitted by code stay English (can't translate\n// an arbitrary value at runtime).\nexport const DEFAULT_OUTPUT_LANGUAGE = \"English\";\n\nexport function resolveOutputLanguage(): string {\n const raw = envText(\"NEGOTIUM_LANG\")?.trim();\n return raw && raw.length > 0 ? raw : DEFAULT_OUTPUT_LANGUAGE;\n}\n\n/** Browser.rs release tested with this Negotium version. */\nexport const BROWSER_RS_VERSION = \"v0.1.19\";\n/** Require the authenticated listener and the current Browser.rs tool contract. */\nexport const BROWSER_RS_MIN_SECURE_VERSION = \"0.1.15\";\n\nfunction versionAtLeast(actualVersion: string, minimumVersion: string): boolean {\n const actual = actualVersion.split(\".\").map(Number);\n const minimum = minimumVersion.split(\".\").map(Number);\n if (actual.some(Number.isNaN) || minimum.some(Number.isNaN)) return false;\n for (let index = 0; index < minimum.length; index += 1) {\n if ((actual[index] ?? 0) > (minimum[index] ?? 0)) return true;\n if ((actual[index] ?? 0) < (minimum[index] ?? 0)) return false;\n }\n return true;\n}\n\nfunction browserRsMeetsMinimumVersion(candidate: string): boolean {\n try {\n const output = execFileSync(candidate, [\"--version\"], {\n encoding: \"utf8\",\n timeout: 2_000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n const match = output.match(/^browser-rs (\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) return false;\n return versionAtLeast(match.slice(1).join(\".\"), BROWSER_RS_MIN_SECURE_VERSION);\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the preferred Browser.rs engine without consulting PATH. The\n * versioned private location keeps different Negotium releases reproducible\n * and avoids changing a user's global browser-rs installation.\n */\nexport function resolveBrowserRsBin(envValue?: string): string | undefined {\n const override = envValue?.trim();\n if (\n !override &&\n !versionAtLeast(BROWSER_RS_VERSION.replace(/^v/, \"\"), BROWSER_RS_MIN_SECURE_VERSION)\n ) {\n return undefined;\n }\n const candidate = override\n ? resolve(override)\n : resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n try {\n accessSync(candidate, constants.X_OK);\n return browserRsMeetsMinimumVersion(candidate) ? candidate : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Backend that stores documents published by `publish_html` and serves them\n * at `<base>/snippets/<id>`. Unset means the deployment has nowhere to\n * publish, and the publish tools are omitted from the catalog rather than\n * offering a link that cannot be minted.\n */\nexport const SNIPPETS_API_URL = (\n envText(\"NEGOTIUM_SNIPPETS_API_URL\") ??\n envText(\"SNIPPETS_API_URL\") ??\n \"\"\n).replace(/\\/+$/, \"\");\n\nexport const BROWSER_RS_BIN = resolveBrowserRsBin(envText(\"NEGOTIUM_BROWSER_RS_BIN\"));\n\n// Managed Browser.rs terminates MCP transports and security policy itself.\nexport function resolveBrowserMcpBin(envValue?: string): string {\n const override = envValue?.trim();\n if (override) return resolve(override);\n return BROWSER_RS_BIN ?? resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n}\n\nexport const PLAYWRIGHT_MCP_BIN = resolveBrowserMcpBin(envText(\"NEGOTIUM_BROWSER_MCP_BIN\"));\n\n// --- Browser egress proxy ---\n//\n// On a datacenter host (AWS) the browser's egress IP is a known cloud range,\n// so anti-bot services (Cloudflare, DataDome, reCAPTCHA) challenge or block it\n// far more than a residential IP would. Routing the automation browser through\n// a residential/ISP proxy moves the egress IP out of the datacenter range.\n//\n// Operators set BROWSER_PROXY_URL, e.g. http://user:pass@proxy.host:8080 or\n// socks5://proxy.host:1080. Credentials in the URL are split out because\n// Playwright takes them as separate fields. BROWSER_PROXY_BYPASS is an optional\n// comma-separated no-proxy list (e.g. \"localhost,127.0.0.1,*.internal\").\n//\n// NOTE: Chromium does not support authentication for SOCKS proxies — put\n// credentials only on http/https proxy URLs.\nexport type BrowserProxyConfig = {\n server: string;\n username?: string;\n password?: string;\n bypass?: string;\n};\n\nexport function resolveBrowserProxy(): BrowserProxyConfig | null {\n const raw = envText(\"BROWSER_PROXY_URL\");\n if (!raw) return null;\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n logger.warn({ raw }, \"Ignoring malformed BROWSER_PROXY_URL\");\n return null;\n }\n // Playwright wants the server without embedded credentials.\n const server = `${url.protocol}//${url.host}`;\n const proxy: BrowserProxyConfig = { server };\n if (url.username) proxy.username = decodeURIComponent(url.username);\n if (url.password) proxy.password = decodeURIComponent(url.password);\n const bypass = envText(\"BROWSER_PROXY_BYPASS\");\n if (bypass) proxy.bypass = bypass;\n return proxy;\n}\n\n// --- Node/tsx runtime for the `codex` agent's MCP servers ---\n//\n// codex 0.135's rmcp stdio MCP client cannot reliably complete the initialize\n// handshake with servers spawned via `bun` (the JSON-RPC initialize is\n// dropped/raced and no tools ever reach the model). Pure-node servers connect\n// reliably, so codex turns launch the SAME .ts servers via node + tsx instead\n// of `bun run`. claude/maestro keep using `bun run` (fast, native, unaffected).\n//\n// tsx transpiles .ts on the fly and resolves the `@/*` tsconfig path aliases,\n// but only when it can find the tsconfig — and MCP servers run with cwd set to\n// the user's workspace dir, not PROJECT_ROOT — so we pass TSX_TSCONFIG_PATH\n// explicitly via env. Requires package.json `\"type\": \"module\"` so the servers'\n// top-level `await` loads as ESM under node.\nexport const TSX_BIN = resolveDependencyBin(\"tsx\");\n/** In-process tsx loader used by Node MCP entrypoints (avoids the tsx CLI child process). */\nexport const TSX_LOADER = createRequire(import.meta.url).resolve(\"tsx\");\nexport const TSCONFIG_PATH = resolve(PROJECT_ROOT, \"tsconfig.json\");\n\nexport const SESSION_COMM_SERVER = resolve(PROJECT_ROOT, \"src/mcp/session-comm/server.ts\");\n\nexport const TASK_SERVER = resolve(PROJECT_ROOT, \"src/mcp/task-server.ts\");\nexport const BROWSER_MCP_SSE_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/browser-sse-proxy-server.ts\",\n);\nexport const CANONICAL_MCP_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/canonical-proxy-server.ts\",\n);\n\nexport const WIKI_SERVER = resolve(PROJECT_ROOT, \"src/mcp/wiki-server.ts\");\n\nexport const TOKEN_STATS_SERVER = resolve(PROJECT_ROOT, \"src/mcp/token-stats-server.ts\");\n\nexport const COMPACTION_LOG_SERVER = resolve(PROJECT_ROOT, \"src/mcp/compaction-log-server.ts\");\n\nexport const SYSTEM_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/system-health-server.ts\");\n\nexport const AGENT_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/agent-health-server.ts\");\n\nexport const BACKGROUND_BASH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/background-bash-server.ts\");\n\nexport const VAULT_SERVER = resolve(PROJECT_ROOT, \"src/mcp/vault-server.ts\");\n\nexport const BG_BASH_BASE_PORT = parsePortEnv(process.env.BG_BASH_BASE_PORT, 9700);\nexport const BG_BASH_MAX_PORT = parsePortEnv(process.env.BG_BASH_MAX_PORT, 9799);\n\nfunction safeWorkspaceSegment(value: string, fallback: string): string {\n return safeRuntimePathSegment(value, fallback);\n}\n\n/** Resolve the shared filesystem workspace for an API topic. */\nexport function resolveTopicWorkspaceDir(topicId: string): string {\n return join(TOPIC_WORKSPACE_DIR, safeWorkspaceSegment(topicId, \"topic\"));\n}\n\nexport function isProductionEnv(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\n\nfunction loadOrCreateLocalSecret(\n envKey: string,\n filename: string,\n options: { persistEnvValue?: boolean } = {},\n): string {\n const envValue = envText(envKey);\n const secretFile = resolve(SECRETS_DIR, filename);\n mkdirSync(dirname(secretFile), { recursive: true });\n if (envValue) {\n if (options.persistEnvValue) {\n writeFileSync(secretFile, `${envValue}\\n`, { mode: 0o600 });\n chmodSync(secretFile, 0o600);\n }\n return envValue;\n }\n\n if (existsSync(secretFile)) {\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (stored) {\n chmodSync(secretFile, 0o600);\n return stored;\n }\n }\n\n const secret = randomBytes(32).toString(\"base64url\");\n try {\n writeFileSync(secretFile, `${secret}\\n`, { mode: 0o600, flag: \"wx\" });\n return secret;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (!stored) throw new Error(`Secret file exists but is empty: ${secretFile}`);\n chmodSync(secretFile, 0o600);\n return stored;\n }\n}\n\nexport const RUNTIME_MCP_SECRET = loadOrCreateLocalSecret(\n \"RUNTIME_MCP_SECRET\",\n \"runtime-mcp-secret\",\n);\n/** Local bearer token for the loopback node-control API. */\nexport const NODE_CONTROL_TOKEN = loadOrCreateLocalSecret(\n \"NEGOTIUM_CONTROL_TOKEN\",\n \"node-control-token\",\n);\nexport const VAULT_MASTER_KEY = loadOrCreateLocalSecret(\n \"NEGOTIUM_VAULT_MASTER_KEY\",\n \"vault-master-key\",\n { persistEnvValue: true },\n);\n// Agent/tool subprocesses inherit process.env. Keep the loaded key in this\n// process only so `env`/`ps` inside an agent workspace cannot reveal it.\ndelete process.env.NEGOTIUM_VAULT_MASTER_KEY;\n\n/** The node's single open port: runtime MCP endpoint + node API. */\nexport const NEGOTIUM_PORT = parseInt(process.env.NEGOTIUM_PORT || \"7777\", 10);\nexport const hostname = process.env.HOSTNAME || \"127.0.0.1\";\n\n// Persistent state (survives restarts, long-lived)\nexport const DATA_DIR = resolveLocalStateDir(\"NEGOTIUM_DATA_DIR\", \"data\");\nexport const LOG_DIR = resolveLocalStateDir(\"NEGOTIUM_LOG_DIR\", \"logs\");\nexport const UPLOADS_DIR = resolve(DATA_DIR, \"uploads\");\nexport const VAULT_DIR = resolve(DATA_DIR, \"vault\");\n// SESSIONS_DB_PATH env override lets tests point the DB singleton at a temp file.\nexport const SESSIONS_DB = process.env.SESSIONS_DB_PATH\n ? resolve(process.env.SESSIONS_DB_PATH)\n : resolve(DATA_DIR, \"sessions.db\");\nexport const DEBUG_FILE = resolve(DATA_DIR, \"debug-users.json\");\nexport const USERS_LOG_DIR = resolve(DATA_DIR, \"users\");\n\n// Runtime IPC queues (transient, safe to clear on restart)\n/** @deprecated Use the runtime layout name; NEGOTIUM_RUN_DIR remains a compatibility override. */\nexport const RUN_DIR = resolveLocalStateDir(\"NEGOTIUM_RUN_DIR\", \"runtime\");\nexport const RUNTIME_DIR = RUN_DIR;\nexport const PROGRESS_DIR = resolve(RUN_DIR, \"progress\");\nexport const DM_CMD_DIR = resolve(RUN_DIR, \"dm-commands\");\nexport const DM_RESP_DIR = resolve(RUN_DIR, \"dm-responses\");\nexport const SESSION_INBOX_DIR = resolve(RUN_DIR, \"session-inbox\");\nexport const SESSION_ASKS_DIR = resolve(RUN_DIR, \"session-asks\");\nexport const PLAYWRIGHT_BASE_PORT = parsePortEnv(process.env.PLAYWRIGHT_BASE_PORT, 9100);\nexport const PLAYWRIGHT_MAX_PORT = parsePortEnv(process.env.PLAYWRIGHT_MAX_PORT, 9499);\nexport const PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, \"playwright-ports\");\nmkdirSync(STATE_DIR, { recursive: true });\nmkdirSync(DATA_DIR, { recursive: true });\nmkdirSync(UPLOADS_DIR, { recursive: true });\nmkdirSync(VAULT_DIR, { recursive: true, mode: 0o700 });\nmkdirSync(LOG_DIR, { recursive: true });\nmkdirSync(PROGRESS_DIR, { recursive: true });\nmkdirSync(DM_CMD_DIR, { recursive: true });\nmkdirSync(DM_RESP_DIR, { recursive: true });\nmkdirSync(SESSION_INBOX_DIR, { recursive: true });\nmkdirSync(SESSION_ASKS_DIR, { recursive: true });\nmkdirSync(PLAYWRIGHT_PORTS_DIR, { recursive: true });\nmkdirSync(WORKSPACE_DIR, { recursive: true });\nmkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SHARED_WIKI_DIR, { recursive: true });\nmkdirSync(CRON_WORKSPACE_DIR, { recursive: true });\nmkdirSync(DM_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });\nmkdirSync(BROWSER_DIR, { recursive: true });\nmkdirSync(BROWSER_PROFILES_DIR, { recursive: true });\nmkdirSync(BINARIES_DIR, { recursive: true });\nmkdirSync(SECRETS_DIR, { recursive: true, mode: 0o700 });\n\n/** Stale threshold for active-query state files (crash recovery) */\nexport const ACTIVE_QUERY_STALE_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const AGENTS_PROMPTS_DIR = resolve(PROJECT_ROOT, \"src/prompts/agents\");\nexport const RESOURCES_DIR = resolve(PROJECT_ROOT, \"src/resources\");\n\n/** Returns process.env without CLAUDECODE, to prevent nested claude-code detection in subprocesses. */\nexport function getCleanEnv(): NodeJS.ProcessEnv {\n const env = { ...process.env };\n delete env.CLAUDECODE;\n return env;\n}\n\nexport const FILE_EXTENSIONS_REGEX =\n /(?:\\/[^\\s\"'<>|*?[\\]]+\\.(?:png|jpg|jpeg|gif|webp|svg|pdf|csv|xlsx|xls|json|txt|md|html|zip|py|js|ts|tsx|jsx|css|xml|yaml|yml|docx|pptx))/gi;\n\nexport const FILE_TAG_REGEX = /\\[FILE:(\\/[^\\]]+)\\]/gi;\n\n// Canonical Claude model IDs — update here when Anthropic releases new versions\nexport const MODEL_SONNET = \"claude-sonnet-5\";\nexport const MODEL_OPUS = \"claude-opus-5\";\nexport const MODEL_HAIKU = \"claude-haiku-4-5-20251001\";\nexport const MODEL_FABLE = \"claude-fable-5\"; // Mythos-class, announced 2026-06-09\n\n// DeepSeek V4 (released 2026-04-24). API is OpenAI-compatible at\n// https://api.deepseek.com/v1/chat/completions; thinking mode is enabled via\n// `extra_body.thinking.type` + `reasoning_effort`. Legacy `deepseek-chat` /\n// `deepseek-reasoner` are deprecated 2026-07-24.\nexport const MODEL_DEEPSEEK_V4_PRO = \"deepseek-v4-pro\";\nexport const MODEL_DEEPSEEK_V4_FLASH = \"deepseek-v4-flash\";\n\n// Agent + model defaults split by session role. FALLBACK_* is the shared base;\n// SESSION_* overrides topic + ephemeral; GATEWAY_* overrides dm + manager.\n// DEFAULT_* is accepted as a legacy alias during the env migration window.\nexport const FALLBACK_AGENT: AgentKind = resolveAgentEnv(\n \"FALLBACK_AGENT\",\n \"maestro\",\n \"DEFAULT_AGENT\",\n);\nexport const SESSION_AGENT: AgentKind = resolveAgentEnv(\"SESSION_AGENT\", FALLBACK_AGENT);\nexport const GATEWAY_AGENT: AgentKind = resolveAgentEnv(\"GATEWAY_AGENT\", FALLBACK_AGENT);\n\nexport const FALLBACK_MODEL = envText(\"FALLBACK_MODEL\") ?? envText(\"DEFAULT_MODEL\");\n\nfunction resolveModelEnv(envKey: string, agentConst: AgentKind): string | undefined {\n return envText(envKey) ?? (agentConst === FALLBACK_AGENT ? FALLBACK_MODEL : undefined);\n}\n\nexport const SESSION_MODEL = resolveModelEnv(\"SESSION_MODEL\", SESSION_AGENT);\nexport const GATEWAY_MODEL = resolveModelEnv(\"GATEWAY_MODEL\", GATEWAY_AGENT);\n\n/** Resolve the effective display/default model for a topic (session context).\n * Applies the session model override only when that role owns the agent;\n * otherwise each registry's native default stays authoritative. */\nexport function resolveDefaultModel(agent: string, registryDefaultModel: string): string {\n return agent === SESSION_AGENT && SESSION_MODEL ? SESSION_MODEL : registryDefaultModel;\n}\n\n// ── External tool binaries + media pipeline env ───────────────────\n// (src/media/* 에서 사용. 미설정 시 fallback 의미는 기존 그대로:\n// FFMPEG_BIN은 text-extractor에서 필수(undefined면 spawn 시점 실패),\n// video.ts에서는 PATH의 ffmpeg/ffprobe로 fallback.)\nexport const FFMPEG_BIN = envText(\"FFMPEG_BIN\");\nexport const FFPROBE_BIN = envText(\"FFPROBE_BIN\");\nexport const PYTHON_BIN = envText(\"PYTHON_BIN\") ?? \"python3\";\nexport const FASTER_WHISPER_WRAPPER =\n envText(\"FASTER_WHISPER_WRAPPER\") ?? resolve(PROJECT_ROOT, \"scripts/faster-whisper-wrapper.py\");\nexport const WHISPER_MODEL = envText(\"WHISPER_MODEL_FILE\") ?? \"turbo\";\nexport const TESSERACT_BIN = envText(\"TESSERACT_BIN\") ?? \"tesseract\";\nexport const PDFTOTEXT_BIN = envText(\"PDFTOTEXT_BIN\") ?? \"pdftotext\";\n\n// Max tell_session relay depth from origin user. ask_session forks reset to\n// depth=0, so this only caps tell_session chains. Override via MAX_TELL_DEPTH\n// (positive int); defaults to 20 when unset or invalid.\nconst _envMaxTellDepth = Number.parseInt(process.env.MAX_TELL_DEPTH ?? \"\", 10);\nexport const MAX_TELL_DEPTH =\n Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 20;\n\n/** Codex CLI auth file. 호출 시점에 env를 읽는다 — 테스트가 런타임에\n * NEGOTIUM_CODEX_AUTH_FILE을 바꾸므로 모듈 로드 상수로 만들면 안 된다. */\nexport function codexAuthFilePath(): string {\n return (\n process.env.NEGOTIUM_CODEX_AUTH_FILE ||\n join(process.env.CODEX_HOME || join(homedir(), \".codex\"), \"auth.json\")\n );\n}\n\n// System defaults moved to per-agent registries\n// (`src/agents/{claude,codex}-registry.ts`). Read via\n// `getRegistry(agent).defaultModel` / `.defaultEffort`.\n\n// MCP server builders -> src/platform/mcp-config.ts\n",
|
|
15
|
+
"import { execFileSync } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n accessSync,\n chmodSync,\n constants,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { parseRuntimePort, readEnvText, safeRuntimePathSegment } from \"#platform/config-helpers\";\nimport { logger } from \"#platform/logger\";\nimport { type AgentKind, isAgentKind } from \"#types\";\n\nexport function envText(envKey: string): string | undefined {\n return readEnvText(process.env, envKey);\n}\n\nfunction resolveAgentEnv(envKey: string, fallback: AgentKind, legacyEnvKey?: string): AgentKind {\n const value = envText(envKey) ?? (legacyEnvKey ? envText(legacyEnvKey) : undefined);\n return isAgentKind(value) ? value : fallback;\n}\n\nconst HOME = homedir();\n\n// new URL(\"../..\", import.meta.url) causes webpack to treat \"../..\" as a module import.\n// Split into fileURLToPath → dirname → resolve to avoid that.\nfunction resolveProjectRoot(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const packagedRuntime = resolve(moduleDir, \"runtime\");\n if (existsSync(resolve(packagedRuntime, \"src\"))) return packagedRuntime;\n return resolve(moduleDir, \"../..\");\n}\n\nexport const PROJECT_ROOT = resolveProjectRoot();\n\n/** Resolve a dependency executable from either a package-local or hoisted install. */\nfunction resolveDependencyBin(name: string): string {\n let dir = PROJECT_ROOT;\n while (true) {\n const candidate = resolve(dir, \"node_modules\", \".bin\", name);\n if (existsSync(candidate)) return candidate;\n const parent = dirname(dir);\n if (parent === dir) return candidate;\n dir = parent;\n }\n}\n\n// Each machine is one negotium node; all node state lives in one dotdir.\n// NEGOTIUM_STATE_DIR overrides (useful for tests and multi-node-on-one-box).\nconst STATE_DIR_ENV = envText(\"NEGOTIUM_STATE_DIR\");\nexport const STATE_DIR = STATE_DIR_ENV ? resolve(STATE_DIR_ENV) : resolve(HOME, \".negotium\");\n\nfunction resolveLocalStateDir(envKey: string, stateName: string): string {\n const envValue = envText(envKey);\n if (envValue) return resolve(envValue);\n return resolve(STATE_DIR, stateName);\n}\n\nfunction parsePortEnv(envValue: string | undefined, fallback: number): number {\n return parseRuntimePort(envValue, fallback);\n}\n\nexport const WORKSPACE_DIR = resolveLocalStateDir(\"NEGOTIUM_WORKSPACE_DIR\", \"workspace\");\nexport const TOPIC_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"topics\");\nexport const SHARED_WIKI_DIR = resolve(WORKSPACE_DIR, \"wiki\");\nexport const CRON_WORKSPACE_DIR = resolve(WORKSPACE_DIR, \"cron\");\nexport const BROWSER_DIR = resolveLocalStateDir(\"NEGOTIUM_BROWSER_DIR\", \"browser\");\nexport const BROWSER_PROFILES_DIR = resolve(BROWSER_DIR, \"profiles\");\nexport const BINARIES_DIR = resolve(STATE_DIR, \"binaries\");\nexport const SECRETS_DIR = resolve(STATE_DIR, \"secrets\");\n// Legacy names remain public, but their durable contents now live under data.\nexport const DM_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"dm\");\nexport const SESSION_WORKSPACE_DIR = resolve(STATE_DIR, \"data\", \"sessions\");\n// The Claude Agent SDK ships a platform-matched Claude Code binary. Keep that\n// SDK/CLI pair together by default; only use an external executable when an\n// operator explicitly opts in. This avoids silently pairing an older SDK with\n// a newer globally installed Claude Code release.\nconst CLAUDE_EXECUTABLE_ENV = envText(\"NEGOTIUM_CLAUDE_EXECUTABLE\");\nexport const CLAUDE_EXECUTABLE = CLAUDE_EXECUTABLE_ENV ? resolve(CLAUDE_EXECUTABLE_ENV) : undefined;\n\n// Fallback output language for model-generated prose (topic/channel/manager\n// replies and the archiver's summaries, briefs, articles, completion reply).\n// Defaults to English; set `NEGOTIUM_LANG` to the user's mother tongue (e.g.\n// `Korean`, `ko`). The assistant still mirrors whatever language the user\n// writes in; `NEGOTIUM_MEMORY_LANG` can narrow just the archiver. Fixed system\n// chrome / degraded-path strings emitted by code stay English (can't translate\n// an arbitrary value at runtime).\nexport const DEFAULT_OUTPUT_LANGUAGE = \"English\";\n\nexport function resolveOutputLanguage(): string {\n const raw = envText(\"NEGOTIUM_LANG\")?.trim();\n return raw && raw.length > 0 ? raw : DEFAULT_OUTPUT_LANGUAGE;\n}\n\n/** Browser.rs release tested with this Negotium version. */\nexport const BROWSER_RS_VERSION = \"v0.1.19\";\n/** Require the authenticated listener and the current Browser.rs tool contract. */\nexport const BROWSER_RS_MIN_SECURE_VERSION = \"0.1.15\";\n\nfunction versionAtLeast(actualVersion: string, minimumVersion: string): boolean {\n const actual = actualVersion.split(\".\").map(Number);\n const minimum = minimumVersion.split(\".\").map(Number);\n if (actual.some(Number.isNaN) || minimum.some(Number.isNaN)) return false;\n for (let index = 0; index < minimum.length; index += 1) {\n if ((actual[index] ?? 0) > (minimum[index] ?? 0)) return true;\n if ((actual[index] ?? 0) < (minimum[index] ?? 0)) return false;\n }\n return true;\n}\n\nfunction browserRsMeetsMinimumVersion(candidate: string): boolean {\n try {\n const output = execFileSync(candidate, [\"--version\"], {\n encoding: \"utf8\",\n timeout: 2_000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n const match = output.match(/^browser-rs (\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) return false;\n return versionAtLeast(match.slice(1).join(\".\"), BROWSER_RS_MIN_SECURE_VERSION);\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve the preferred Browser.rs engine without consulting PATH. The\n * versioned private location keeps different Negotium releases reproducible\n * and avoids changing a user's global browser-rs installation.\n */\nexport function resolveBrowserRsBin(envValue?: string): string | undefined {\n const override = envValue?.trim();\n if (\n !override &&\n !versionAtLeast(BROWSER_RS_VERSION.replace(/^v/, \"\"), BROWSER_RS_MIN_SECURE_VERSION)\n ) {\n return undefined;\n }\n const candidate = override\n ? resolve(override)\n : resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n try {\n accessSync(candidate, constants.X_OK);\n return browserRsMeetsMinimumVersion(candidate) ? candidate : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Backend that stores documents published by `publish_html` and serves them\n * at `<base>/snippets/<id>`. Unset means the deployment has nowhere to\n * publish, and the publish tools are omitted from the catalog rather than\n * offering a link that cannot be minted.\n */\nexport const SNIPPETS_API_URL = (\n envText(\"NEGOTIUM_SNIPPETS_API_URL\") ??\n envText(\"SNIPPETS_API_URL\") ??\n \"\"\n).replace(/\\/+$/, \"\");\n\nexport const BROWSER_RS_BIN = resolveBrowserRsBin(envText(\"NEGOTIUM_BROWSER_RS_BIN\"));\n\n/** bash-rs release tested with this Negotium version — see apps/negotium/install-bash-rs.mjs. */\nexport const BASH_RS_VERSION = \"v0.1.2\";\n\n/**\n * Resolve the bash-rs binary the same way `resolveBrowserRsBin` resolves\n * Browser.rs: a versioned private location, no PATH lookup, `undefined`\n * (rather than throwing) when it's missing — callers fall back to the TS\n * `background-bash-server.ts` in that case (see `background-bash/manager.ts`).\n */\nexport function resolveBashRsBin(envValue?: string): string | undefined {\n const override = envValue?.trim();\n const candidate = override\n ? resolve(override)\n : resolve(BINARIES_DIR, \"bash-rs\", BASH_RS_VERSION, \"bash-rs\");\n try {\n accessSync(candidate, constants.X_OK);\n return candidate;\n } catch {\n return undefined;\n }\n}\n\nexport const BASH_RS_BIN = resolveBashRsBin(envText(\"NEGOTIUM_BASH_RS_BIN\"));\n\n// Managed Browser.rs terminates MCP transports and security policy itself.\nexport function resolveBrowserMcpBin(envValue?: string): string {\n const override = envValue?.trim();\n if (override) return resolve(override);\n return BROWSER_RS_BIN ?? resolve(BINARIES_DIR, \"browser-rs\", BROWSER_RS_VERSION, \"browser-rs\");\n}\n\nexport const PLAYWRIGHT_MCP_BIN = resolveBrowserMcpBin(envText(\"NEGOTIUM_BROWSER_MCP_BIN\"));\n\n// --- Browser egress proxy ---\n//\n// On a datacenter host (AWS) the browser's egress IP is a known cloud range,\n// so anti-bot services (Cloudflare, DataDome, reCAPTCHA) challenge or block it\n// far more than a residential IP would. Routing the automation browser through\n// a residential/ISP proxy moves the egress IP out of the datacenter range.\n//\n// Operators set BROWSER_PROXY_URL, e.g. http://user:pass@proxy.host:8080 or\n// socks5://proxy.host:1080. Credentials in the URL are split out because\n// Playwright takes them as separate fields. BROWSER_PROXY_BYPASS is an optional\n// comma-separated no-proxy list (e.g. \"localhost,127.0.0.1,*.internal\").\n//\n// NOTE: Chromium does not support authentication for SOCKS proxies — put\n// credentials only on http/https proxy URLs.\nexport type BrowserProxyConfig = {\n server: string;\n username?: string;\n password?: string;\n bypass?: string;\n};\n\nexport function resolveBrowserProxy(): BrowserProxyConfig | null {\n const raw = envText(\"BROWSER_PROXY_URL\");\n if (!raw) return null;\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n logger.warn({ raw }, \"Ignoring malformed BROWSER_PROXY_URL\");\n return null;\n }\n // Playwright wants the server without embedded credentials.\n const server = `${url.protocol}//${url.host}`;\n const proxy: BrowserProxyConfig = { server };\n if (url.username) proxy.username = decodeURIComponent(url.username);\n if (url.password) proxy.password = decodeURIComponent(url.password);\n const bypass = envText(\"BROWSER_PROXY_BYPASS\");\n if (bypass) proxy.bypass = bypass;\n return proxy;\n}\n\n// --- Node/tsx runtime for the `codex` agent's MCP servers ---\n//\n// codex 0.135's rmcp stdio MCP client cannot reliably complete the initialize\n// handshake with servers spawned via `bun` (the JSON-RPC initialize is\n// dropped/raced and no tools ever reach the model). Pure-node servers connect\n// reliably, so codex turns launch the SAME .ts servers via node + tsx instead\n// of `bun run`. claude/maestro keep using `bun run` (fast, native, unaffected).\n//\n// tsx transpiles .ts on the fly and resolves the `@/*` tsconfig path aliases,\n// but only when it can find the tsconfig — and MCP servers run with cwd set to\n// the user's workspace dir, not PROJECT_ROOT — so we pass TSX_TSCONFIG_PATH\n// explicitly via env. Requires package.json `\"type\": \"module\"` so the servers'\n// top-level `await` loads as ESM under node.\nexport const TSX_BIN = resolveDependencyBin(\"tsx\");\n/** In-process tsx loader used by Node MCP entrypoints (avoids the tsx CLI child process). */\nexport const TSX_LOADER = createRequire(import.meta.url).resolve(\"tsx\");\nexport const TSCONFIG_PATH = resolve(PROJECT_ROOT, \"tsconfig.json\");\n\nexport const SESSION_COMM_SERVER = resolve(PROJECT_ROOT, \"src/mcp/session-comm/server.ts\");\n\nexport const TASK_SERVER = resolve(PROJECT_ROOT, \"src/mcp/task-server.ts\");\nexport const BROWSER_MCP_SSE_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/browser-sse-proxy-server.ts\",\n);\nexport const CANONICAL_MCP_PROXY_SERVER = resolve(\n PROJECT_ROOT,\n \"src/mcp/canonical-proxy-server.ts\",\n);\n\nexport const WIKI_SERVER = resolve(PROJECT_ROOT, \"src/mcp/wiki-server.ts\");\n\nexport const TOKEN_STATS_SERVER = resolve(PROJECT_ROOT, \"src/mcp/token-stats-server.ts\");\n\nexport const COMPACTION_LOG_SERVER = resolve(PROJECT_ROOT, \"src/mcp/compaction-log-server.ts\");\n\nexport const SYSTEM_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/system-health-server.ts\");\n\nexport const AGENT_HEALTH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/agent-health-server.ts\");\n\nexport const BACKGROUND_BASH_SERVER = resolve(PROJECT_ROOT, \"src/mcp/background-bash-server.ts\");\n\nexport const VAULT_SERVER = resolve(PROJECT_ROOT, \"src/mcp/vault-server.ts\");\n\nexport const BG_BASH_BASE_PORT = parsePortEnv(process.env.BG_BASH_BASE_PORT, 9700);\nexport const BG_BASH_MAX_PORT = parsePortEnv(process.env.BG_BASH_MAX_PORT, 9799);\n\nfunction safeWorkspaceSegment(value: string, fallback: string): string {\n return safeRuntimePathSegment(value, fallback);\n}\n\n/** Resolve the shared filesystem workspace for an API topic. */\nexport function resolveTopicWorkspaceDir(topicId: string): string {\n return join(TOPIC_WORKSPACE_DIR, safeWorkspaceSegment(topicId, \"topic\"));\n}\n\nexport function isProductionEnv(): boolean {\n return process.env.NODE_ENV === \"production\";\n}\n\nfunction loadOrCreateLocalSecret(\n envKey: string,\n filename: string,\n options: { persistEnvValue?: boolean } = {},\n): string {\n const envValue = envText(envKey);\n const secretFile = resolve(SECRETS_DIR, filename);\n mkdirSync(dirname(secretFile), { recursive: true });\n if (envValue) {\n if (options.persistEnvValue) {\n writeFileSync(secretFile, `${envValue}\\n`, { mode: 0o600 });\n chmodSync(secretFile, 0o600);\n }\n return envValue;\n }\n\n if (existsSync(secretFile)) {\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (stored) {\n chmodSync(secretFile, 0o600);\n return stored;\n }\n }\n\n const secret = randomBytes(32).toString(\"base64url\");\n try {\n writeFileSync(secretFile, `${secret}\\n`, { mode: 0o600, flag: \"wx\" });\n return secret;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n const stored = readFileSync(secretFile, \"utf-8\").trim();\n if (!stored) throw new Error(`Secret file exists but is empty: ${secretFile}`);\n chmodSync(secretFile, 0o600);\n return stored;\n }\n}\n\nexport const RUNTIME_MCP_SECRET = loadOrCreateLocalSecret(\n \"RUNTIME_MCP_SECRET\",\n \"runtime-mcp-secret\",\n);\n/** Local bearer token for the loopback node-control API. */\nexport const NODE_CONTROL_TOKEN = loadOrCreateLocalSecret(\n \"NEGOTIUM_CONTROL_TOKEN\",\n \"node-control-token\",\n);\nexport const VAULT_MASTER_KEY = loadOrCreateLocalSecret(\n \"NEGOTIUM_VAULT_MASTER_KEY\",\n \"vault-master-key\",\n { persistEnvValue: true },\n);\n// Agent/tool subprocesses inherit process.env. Keep the loaded key in this\n// process only so `env`/`ps` inside an agent workspace cannot reveal it.\ndelete process.env.NEGOTIUM_VAULT_MASTER_KEY;\n\n/** The node's single open port: runtime MCP endpoint + node API. */\nexport const NEGOTIUM_PORT = parseInt(process.env.NEGOTIUM_PORT || \"7777\", 10);\nexport const hostname = process.env.HOSTNAME || \"127.0.0.1\";\n\n// Persistent state (survives restarts, long-lived)\nexport const DATA_DIR = resolveLocalStateDir(\"NEGOTIUM_DATA_DIR\", \"data\");\nexport const LOG_DIR = resolveLocalStateDir(\"NEGOTIUM_LOG_DIR\", \"logs\");\nexport const UPLOADS_DIR = resolve(DATA_DIR, \"uploads\");\nexport const VAULT_DIR = resolve(DATA_DIR, \"vault\");\n// SESSIONS_DB_PATH env override lets tests point the DB singleton at a temp file.\nexport const SESSIONS_DB = process.env.SESSIONS_DB_PATH\n ? resolve(process.env.SESSIONS_DB_PATH)\n : resolve(DATA_DIR, \"sessions.db\");\nexport const DEBUG_FILE = resolve(DATA_DIR, \"debug-users.json\");\nexport const USERS_LOG_DIR = resolve(DATA_DIR, \"users\");\n\n// Runtime IPC queues (transient, safe to clear on restart)\n/** @deprecated Use the runtime layout name; NEGOTIUM_RUN_DIR remains a compatibility override. */\nexport const RUN_DIR = resolveLocalStateDir(\"NEGOTIUM_RUN_DIR\", \"runtime\");\nexport const RUNTIME_DIR = RUN_DIR;\nexport const PROGRESS_DIR = resolve(RUN_DIR, \"progress\");\nexport const DM_CMD_DIR = resolve(RUN_DIR, \"dm-commands\");\nexport const DM_RESP_DIR = resolve(RUN_DIR, \"dm-responses\");\nexport const SESSION_INBOX_DIR = resolve(RUN_DIR, \"session-inbox\");\nexport const SESSION_ASKS_DIR = resolve(RUN_DIR, \"session-asks\");\n/**\n * Passed to `bash-rs` as `BASHRS_SPILL_ROOT`. Each job gets a subdirectory\n * here (`{bash_id}/meta.json`, `result.json`, `stdout.log`, `stderr.log`) —\n * see bash-rs-mcp's `journal.rs`. `runtime/bashrs-completions.ts` watches\n * this directory and turns `result.json` into a session-inbox `tell`, the\n * same way `background-bash-server.ts` used to write one directly.\n */\nexport const BASHRS_SPILL_ROOT = resolve(RUN_DIR, \"bashrs\");\nexport const PLAYWRIGHT_BASE_PORT = parsePortEnv(process.env.PLAYWRIGHT_BASE_PORT, 9100);\nexport const PLAYWRIGHT_MAX_PORT = parsePortEnv(process.env.PLAYWRIGHT_MAX_PORT, 9499);\nexport const PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, \"playwright-ports\");\nmkdirSync(STATE_DIR, { recursive: true });\nmkdirSync(DATA_DIR, { recursive: true });\nmkdirSync(UPLOADS_DIR, { recursive: true });\nmkdirSync(VAULT_DIR, { recursive: true, mode: 0o700 });\nmkdirSync(LOG_DIR, { recursive: true });\nmkdirSync(PROGRESS_DIR, { recursive: true });\nmkdirSync(DM_CMD_DIR, { recursive: true });\nmkdirSync(DM_RESP_DIR, { recursive: true });\nmkdirSync(SESSION_INBOX_DIR, { recursive: true });\nmkdirSync(SESSION_ASKS_DIR, { recursive: true });\nmkdirSync(PLAYWRIGHT_PORTS_DIR, { recursive: true });\nmkdirSync(WORKSPACE_DIR, { recursive: true });\nmkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SHARED_WIKI_DIR, { recursive: true });\nmkdirSync(CRON_WORKSPACE_DIR, { recursive: true });\nmkdirSync(DM_WORKSPACE_DIR, { recursive: true });\nmkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });\nmkdirSync(BROWSER_DIR, { recursive: true });\nmkdirSync(BROWSER_PROFILES_DIR, { recursive: true });\nmkdirSync(BINARIES_DIR, { recursive: true });\nmkdirSync(SECRETS_DIR, { recursive: true, mode: 0o700 });\n\n/** Stale threshold for active-query state files (crash recovery) */\nexport const ACTIVE_QUERY_STALE_MS = 10 * 60 * 1000; // 10 minutes\n\nexport const AGENTS_PROMPTS_DIR = resolve(PROJECT_ROOT, \"src/prompts/agents\");\nexport const RESOURCES_DIR = resolve(PROJECT_ROOT, \"src/resources\");\n\n/** Returns process.env without CLAUDECODE, to prevent nested claude-code detection in subprocesses. */\nexport function getCleanEnv(): NodeJS.ProcessEnv {\n const env = { ...process.env };\n delete env.CLAUDECODE;\n return env;\n}\n\nexport const FILE_EXTENSIONS_REGEX =\n /(?:\\/[^\\s\"'<>|*?[\\]]+\\.(?:png|jpg|jpeg|gif|webp|svg|pdf|csv|xlsx|xls|json|txt|md|html|zip|py|js|ts|tsx|jsx|css|xml|yaml|yml|docx|pptx))/gi;\n\nexport const FILE_TAG_REGEX = /\\[FILE:(\\/[^\\]]+)\\]/gi;\n\n// Canonical Claude model IDs — update here when Anthropic releases new versions\nexport const MODEL_SONNET = \"claude-sonnet-5\";\nexport const MODEL_OPUS = \"claude-opus-5\";\nexport const MODEL_HAIKU = \"claude-haiku-4-5-20251001\";\nexport const MODEL_FABLE = \"claude-fable-5\"; // Mythos-class, announced 2026-06-09\n\n// DeepSeek V4 (released 2026-04-24). API is OpenAI-compatible at\n// https://api.deepseek.com/v1/chat/completions; thinking mode is enabled via\n// `extra_body.thinking.type` + `reasoning_effort`. Legacy `deepseek-chat` /\n// `deepseek-reasoner` are deprecated 2026-07-24.\nexport const MODEL_DEEPSEEK_V4_PRO = \"deepseek-v4-pro\";\nexport const MODEL_DEEPSEEK_V4_FLASH = \"deepseek-v4-flash\";\n\n// Agent + model defaults split by session role. FALLBACK_* is the shared base;\n// SESSION_* overrides topic + ephemeral; GATEWAY_* overrides dm + manager.\n// DEFAULT_* is accepted as a legacy alias during the env migration window.\nexport const FALLBACK_AGENT: AgentKind = resolveAgentEnv(\n \"FALLBACK_AGENT\",\n \"maestro\",\n \"DEFAULT_AGENT\",\n);\nexport const SESSION_AGENT: AgentKind = resolveAgentEnv(\"SESSION_AGENT\", FALLBACK_AGENT);\nexport const GATEWAY_AGENT: AgentKind = resolveAgentEnv(\"GATEWAY_AGENT\", FALLBACK_AGENT);\n\nexport const FALLBACK_MODEL = envText(\"FALLBACK_MODEL\") ?? envText(\"DEFAULT_MODEL\");\n\nfunction resolveModelEnv(envKey: string, agentConst: AgentKind): string | undefined {\n return envText(envKey) ?? (agentConst === FALLBACK_AGENT ? FALLBACK_MODEL : undefined);\n}\n\nexport const SESSION_MODEL = resolveModelEnv(\"SESSION_MODEL\", SESSION_AGENT);\nexport const GATEWAY_MODEL = resolveModelEnv(\"GATEWAY_MODEL\", GATEWAY_AGENT);\n\n/** Resolve the effective display/default model for a topic (session context).\n * Applies the session model override only when that role owns the agent;\n * otherwise each registry's native default stays authoritative. */\nexport function resolveDefaultModel(agent: string, registryDefaultModel: string): string {\n return agent === SESSION_AGENT && SESSION_MODEL ? SESSION_MODEL : registryDefaultModel;\n}\n\n// ── External tool binaries + media pipeline env ───────────────────\n// (src/media/* 에서 사용. 미설정 시 fallback 의미는 기존 그대로:\n// FFMPEG_BIN은 text-extractor에서 필수(undefined면 spawn 시점 실패),\n// video.ts에서는 PATH의 ffmpeg/ffprobe로 fallback.)\nexport const FFMPEG_BIN = envText(\"FFMPEG_BIN\");\nexport const FFPROBE_BIN = envText(\"FFPROBE_BIN\");\nexport const PYTHON_BIN = envText(\"PYTHON_BIN\") ?? \"python3\";\nexport const FASTER_WHISPER_WRAPPER =\n envText(\"FASTER_WHISPER_WRAPPER\") ?? resolve(PROJECT_ROOT, \"scripts/faster-whisper-wrapper.py\");\nexport const WHISPER_MODEL = envText(\"WHISPER_MODEL_FILE\") ?? \"turbo\";\nexport const TESSERACT_BIN = envText(\"TESSERACT_BIN\") ?? \"tesseract\";\nexport const PDFTOTEXT_BIN = envText(\"PDFTOTEXT_BIN\") ?? \"pdftotext\";\n\n// Max tell_session relay depth from origin user. ask_session forks reset to\n// depth=0, so this only caps tell_session chains. Override via MAX_TELL_DEPTH\n// (positive int); defaults to 20 when unset or invalid.\nconst _envMaxTellDepth = Number.parseInt(process.env.MAX_TELL_DEPTH ?? \"\", 10);\nexport const MAX_TELL_DEPTH =\n Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 20;\n\n/** Codex CLI auth file. 호출 시점에 env를 읽는다 — 테스트가 런타임에\n * NEGOTIUM_CODEX_AUTH_FILE을 바꾸므로 모듈 로드 상수로 만들면 안 된다. */\nexport function codexAuthFilePath(): string {\n return (\n process.env.NEGOTIUM_CODEX_AUTH_FILE ||\n join(process.env.CODEX_HOME || join(homedir(), \".codex\"), \"auth.json\")\n );\n}\n\n// System defaults moved to per-agent registries\n// (`src/agents/{claude,codex}-registry.ts`). Read via\n// `getRegistry(agent).defaultModel` / `.defaultEffort`.\n\n// MCP server builders -> src/platform/mcp-config.ts\n",
|
|
16
16
|
"import { resolve } from \"node:path\";\n\nexport type RuntimeEnvironment = Readonly<Record<string, string | undefined>>;\n\nexport function readEnvText(env: RuntimeEnvironment, key: string): string | undefined {\n const value = env[key]?.trim();\n return value || undefined;\n}\n\nexport function parseRuntimePort(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const port = Number.parseInt(value, 10);\n return Number.isInteger(port) && port > 0 && port <= 65_535 ? port : fallback;\n}\n\nexport function resolveRuntimeStateDir(options: {\n env: RuntimeEnvironment;\n envKey: string;\n fallbackRoot: string;\n fallbackName: string;\n}): string {\n const configured = readEnvText(options.env, options.envKey);\n return configured ? resolve(configured) : resolve(options.fallbackRoot, options.fallbackName);\n}\n\nexport function safeRuntimePathSegment(value: string, fallback: string, maxLength = 160): string {\n const cleaned = value\n .trim()\n .replace(/[^A-Za-z0-9._-]/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, maxLength);\n return cleaned || fallback;\n}\n",
|
|
17
17
|
"/**\n * Common context carried through the attachment/prompt-build pipeline.\n * Used by buildPromptFromMessage and related helpers.\n */\nexport interface SessionContext {\n userId: number;\n topicName?: string;\n userDir?: string;\n sessionType?: \"dm\" | \"forum\" | \"ephemeral\" | \"manager\" | \"cron\";\n}\n\nexport interface TokenUsage {\n /** Aggregate billable input across every model call made during this turn. */\n inputTokens: number;\n outputTokens: number;\n cacheCreationInputTokens?: number;\n cacheReadInputTokens?: number;\n /** Provider-reported query cost when available. */\n costUsd?: number;\n /** Tokens occupied by the latest model call, not aggregate turn spend. */\n contextTokens?: number;\n /** Provider-reported context window for the latest model call. */\n contextWindow?: number;\n}\n\n/** Agent identifier — one of the supported AI provider backends. */\nexport type AgentKind = \"maestro\" | \"claude\" | \"codex\";\n\nexport const SUPPORTED_AGENTS: readonly AgentKind[] = [\"maestro\", \"claude\", \"codex\"] as const;\n\nexport function isAgentKind(value: unknown): value is AgentKind {\n return typeof value === \"string\" && (SUPPORTED_AGENTS as readonly string[]).includes(value);\n}\n\n/**\n * Per-agent supported reasoning efforts. Single source of truth for both the\n * `EffortLevel` type and each registry's `validEfforts` runtime list — the\n * registries import these directly so adding a value in one place\n * propagates to validation, footer rendering, and zod enums.\n *\n * Claude SDK rejects 'minimal'; Codex SDK rejects 'max'. The two sets\n * intersect on low/medium/high/xhigh. Maestro (TS port) currently piggybacks\n * on the Anthropic provider, so its efforts mirror the Claude set; this can\n * narrow per-provider once Phase 5 lands.\n *\n * 'minimal' removed from codex: Codex API rejects it when default tools\n * (image_gen, web_search) are active, making agent sessions unusable.\n */\nexport const CLAUDE_EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\nexport const CODEX_EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\nexport const MAESTRO_EFFORT_VALUES = [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\n\nexport type EffortLevel =\n | (typeof CLAUDE_EFFORT_VALUES)[number]\n | (typeof CODEX_EFFORT_VALUES)[number]\n | (typeof MAESTRO_EFFORT_VALUES)[number];\n\n/**\n * Runtime iteration list (used by zod enums and any callers that need to\n * loop over every accepted value). Manually ordered for readability; the\n * `satisfies` check fails the build if an entry here isn't covered by the\n * per-agent unions above.\n */\nexport const EFFORT_VALUES = [\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n] as const satisfies readonly EffortLevel[];\n\n/**\n * Normalized events yielded by any agent provider (claudeProvider, codexProvider).\n * The handler/event-processor consumes these without caring which backend produced them.\n *\n * `user_message` is the lone \"into-the-log\" variant — no provider yields it.\n * The query handler writes it directly to the conversation log right before\n * `runAgent()` starts, so cross-agent rollout reconstruction can pair every\n * assistant turn with the user prompt that triggered it. Consumers that only\n * react to provider output (e.g. processAgentEvent) can safely ignore it.\n */\n/**\n * Wire-safe projection of one task, carried by the `tasks` UnifiedEvent.\n *\n * This is also the on-disk shape of Otium's shared task store, so claude,\n * codex, and maestro render the same live panel from the same source of truth.\n */\nexport interface TaskSnapshot {\n id: string;\n subject: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n /** Task ids this one is blocked by; omitted when empty. */\n blockedBy?: string[];\n /** Present-continuous label for spinners, when set. */\n activeForm?: string;\n /** Owner / agent name for multi-agent runs, when set. */\n owner?: string;\n}\n\nexport type UnifiedEvent =\n | {\n type: \"user_message\";\n content: string;\n synthetic?: \"compaction\";\n /** Total ordered user submissions represented by one preempting provider turn. */\n consecutiveBatchSize?: number;\n /** Zero-based position within the ordered preemption batch. */\n consecutiveBatchIndex?: number;\n }\n | { type: \"session\"; sessionId: string }\n | {\n type: \"tool_use\";\n name: string;\n input: Record<string, unknown>;\n /** Provider-assigned id so the client can match tool_use→tool_result pairs. */\n toolUseId?: string;\n }\n | { type: \"tool_progress\"; toolName: string; elapsed: number }\n | { type: \"tool_use_summary\"; summary: string }\n // Provider reasoning/thinking summary text (Codex `reasoning` items; Claude\n // extended-thinking). Surfaced so background runs (cron/archiver) show the\n // agent's thought process, not just tool calls.\n | { type: \"reasoning\"; content: string }\n // Full task-list snapshot (replace, not delta) from Otium's shared task\n // store. Provider-native task/todo stores are not authoritative.\n | { type: \"tasks\"; tasks: TaskSnapshot[] }\n | {\n type: \"tool_result\";\n toolUseId: string;\n content: string;\n /** True when the tool call failed; absent/false means success. */\n isError?: boolean;\n metadata?: {\n truncatedForModel: boolean;\n originalBytes: number;\n returnedBytes: number;\n omittedBytes?: number;\n outputPath?: string;\n };\n }\n | { type: \"text_delta\"; content: string }\n | { type: \"text\"; content: string }\n | { type: \"result\"; content: string; stopReason: string; usage?: TokenUsage }\n | { type: \"file\"; path: string; source: string; origin: \"tag\" | \"extension\" }\n | {\n type: \"error\";\n content: string;\n usage?: TokenUsage;\n code?: \"budget_exceeded\";\n }\n | { type: \"status\"; content: string };\n\nexport interface AgentInputAttachment {\n id: string;\n type: \"image\" | \"file\" | \"audio\";\n filename: string;\n mimeType: string;\n sizeBytes: number;\n path: string;\n}\n\n/** Worker-side runtime tools proxy user-facing state back to the canonical\n * hub topic identified here. */\nexport interface PeerRuntimeBridgeContext {\n hubCellId: string;\n hostTopicId: string;\n hostQueryId: string;\n canSpawnSubagents: boolean;\n}\n\nexport interface AgentQueryOptions {\n agent: AgentKind;\n prompt: string;\n attachments?: AgentInputAttachment[];\n sessionId?: string | null;\n cwd: string;\n systemPrompt: string;\n userId?: string;\n /** Credential namespace when it differs from the execution principal. */\n vaultUserId?: string;\n session?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n bgBashPort?: number;\n sessionType?: \"dm\" | \"forum\" | \"ephemeral\" | \"manager\" | \"cron\";\n /** API topic id (REST/WS world). Carries per-query topic context for MCP servers. */\n topicId?: string;\n /** Direct parent topic id when this query runs inside a subagent room. */\n subagentParentTopicId?: string;\n /** API query id for the currently running turn. Used by runtime MCP tools. */\n queryId?: string;\n /** Optional wiki-memory topic id. Derived topics use their root origin here\n * while other per-topic MCP servers keep `topicId` bound to the live room. */\n wikiTopicId?: string;\n /** Whether self-config MCP may enqueue an automatic continue turn after set_* changes. */\n autoContinue?: boolean;\n /** Expose Otium-only visual panel tools for this turn. Default-deny. */\n visualTools?: boolean;\n /** Expose adapter-backed file-delivery tools for this turn. Default-deny. */\n fileDeliveryTools?: boolean;\n abortController?: AbortController;\n model?: string;\n /** Provider-side hard budget when the selected SDK supports one. */\n maxBudgetUsd?: number;\n depth?: number;\n agents?: Record<\n string,\n {\n description: string;\n prompt: string;\n model?: string;\n tools?: string[];\n maxTurns?: number;\n effort?: EffortLevel | number;\n }\n >;\n effort?: EffortLevel;\n /**\n * Per-API-call `max_tokens` ceiling on the assistant's output. Wired\n * through to the underlying provider request body for every agent\n * (claude/codex/maestro). Omit to inherit each provider SDK's per-model\n * default — for maestro that's the v0.1.21+ `getNativeMaxOutputTokens`\n * catalog (deepseek-pro=64K, kimi-k3=64K, kimi-k2.7-code=32K).\n *\n * Pass an explicit number when a specific topic / surface needs a tighter\n * latency cap or a higher ceiling for long-form generation (legal\n * report writing, multi-K Write/Edit file bodies). Pre-0.1.21 maestro\n * builds silently clamped at 4096 and truncated outputs mid-string;\n * setting this field is now the supported way to lift that ceiling.\n */\n maxTokens?: number;\n /**\n * v0.1.22+: Claude-Code-style deferred tool catalog + `ToolSearch` built-in.\n *\n * Wired straight through to `maestro-agent-sdk`'s\n * `AgentQueryOptions.enableToolSearch`. When `true`, the maestro provider\n * registers every MCP tool as deferred — schemas stay off the wire until\n * the model promotes them via `ToolSearch(\"select:Name1,Name2\")` or\n * `ToolSearch(\"keyword\")`. Active set persists across resume.\n *\n * Otium's maestro provider supplies `true` when the caller leaves this\n * option unset, because most forum turns carry enough MCP surface for the\n * reminder-token savings to outweigh the first-use `ToolSearch` round-trip.\n * Callers can still pass `false` per call when a narrow surface or\n * latency-sensitive workflow is better served by eager MCP schemas.\n *\n * No-op for claude / codex agents — they have their own deferred-tool\n * machinery owned by their respective SDKs.\n */\n enableToolSearch?: boolean;\n /**\n * Bounded tool results with the full output kept on disk.\n *\n * Wired to `maestro-agent-sdk`'s `AgentQueryOptions.toolResultTruncation`.\n * The SDK caps a string tool result, writes the untruncated bytes to a file,\n * and splices an opaque `maestro://tool-output/<id>` reference into the text\n * that the `ReadToolOutput` tool can page back through.\n *\n * The maestro provider enables it by default. Left unset, every tool result\n * — a whole-file `Read`, a wide `Grep`, a `WebFetch` of a large page —\n * entered the context at full size, and the `\"ReadToolOutput\"` entry in the\n * provider's builtin list was dead, because the SDK only registers that tool\n * when truncation is on with `saveFullOutput`.\n *\n * Pass an explicit object to tune the budget, or `{ enabled: false }` for a\n * call whose tool results must arrive whole.\n *\n * No-op for claude / codex agents — their SDKs do their own truncation.\n */\n toolResultTruncation?: {\n enabled?: boolean;\n maxBytes?: number;\n headBytes?: number;\n tailBytes?: number;\n saveFullOutput?: boolean;\n outputDir?: string;\n retentionDays?: number;\n ignoreTools?: string[];\n };\n /**\n * Claude-Code-compatible exact tool denylist. Maestro v0.1.42+ hides these\n * tools from provider schemas / ToolSearch and blocks dispatch if a stale\n * call still arrives. Claude maps this to its SDK option. Codex does not\n * support this name-based list; its provider-native multi-agent tool family\n * is disabled separately through the Codex feature config.\n */\n disallowedTools?: readonly string[];\n /**\n * Hard provider tool policy for auxiliary model calls.\n *\n * `\"none\"` removes MCP and provider-native tools before the request is\n * dispatched. `\"compaction-log\"` keeps provider-native tools disabled and\n * exposes only the host-scoped immutable log reader. Use these for untrusted\n * transcript transforms; reacting to tool events after dispatch is not a\n * security boundary.\n */\n toolPolicy?: \"none\" | \"compaction-log\";\n mcpEnabled?: string[] | null;\n peerBridge?: PeerRuntimeBridgeContext;\n mcpExtra?: Record<string, unknown>;\n /**\n * true for silent fork runs generating ask_session replies — restricts session-comm\n * outbound tools (ask/tell/abort) so the forked session can only produce text\n */\n silent?: boolean;\n}\n\n/** State file written to data/users/{userId}/active-queries/{topicId}.json while a query is running. */\nexport interface QueryState {\n topicId?: string;\n topicName?: string;\n task?: string; // first 100 chars of prompt, newlines normalized\n since: string; // ISO timestamp\n}\n",
|
|
18
18
|
"/** Sanitize a topic/session name for use in file paths.\n * Replaces non-alphanumeric characters (excluding Korean) with underscores.\n * Empty input (or input consisting only of disallowed chars) returns \"_\" so\n * callers always get a non-empty single path component.\n * @param name The raw topic or session name.\n * @param lowercase Whether to lowercase the result (default: false).\n * Use true for wiki paths; leave false for log file paths.\n */\nexport function sanitizeTopicName(name: string, lowercase = false): string {\n const safe = name.replace(/[^a-zA-Z0-9가-힣_-]/g, \"_\") || \"_\";\n return lowercase ? safe.toLowerCase() : safe;\n}\n\n/** Sanitize a file name for use in file paths. Allows dots.\n * Pure-dot results (\".\", \"..\") are replaced with \"_\" to block path-traversal\n * when the sanitized value is used as a standalone path component.\n */\nexport function sanitizeFileName(name: string): string {\n const safe = name.replace(/[^a-zA-Z0-9._-]/g, \"_\") || \"_\";\n if (safe === \".\" || safe === \"..\") return \"_\";\n return safe;\n}\n\n/** Sanitize an arbitrary ID (no Korean, no dots) for use in file paths. */\nexport function sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9_-]/g, \"_\") || \"_\";\n}\n"
|
|
19
19
|
],
|
|
20
|
-
"mappings": "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",
|
|
21
|
-
"debugId": "
|
|
20
|
+
"mappings": "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",
|
|
21
|
+
"debugId": "074D4E0D14553FB964756E2164756E21",
|
|
22
22
|
"names": []
|
|
23
23
|
}
|
package/dist/registry.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
logger,
|
|
17
17
|
writeClaudeRollout,
|
|
18
18
|
writeCodexRollout
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-rnsnhcye.js";
|
|
20
20
|
|
|
21
21
|
// ../../packages/core/src/agents/claude-registry.ts
|
|
22
22
|
import { existsSync, mkdirSync, readdirSync, renameSync, unlinkSync } from "fs";
|
|
@@ -121,7 +121,7 @@ import { createRequire } from "module";
|
|
|
121
121
|
import { dirname, join as join2 } from "path";
|
|
122
122
|
|
|
123
123
|
// ../../packages/core/src/version.ts
|
|
124
|
-
var NEGOTIUM_VERSION = "0.2.
|
|
124
|
+
var NEGOTIUM_VERSION = "0.2.13";
|
|
125
125
|
|
|
126
126
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
127
127
|
var moduleRequire = createRequire(import.meta.url);
|
|
@@ -479,4 +479,4 @@ export {
|
|
|
479
479
|
getRegistry2 as getRegistry
|
|
480
480
|
};
|
|
481
481
|
|
|
482
|
-
//# debugId=
|
|
482
|
+
//# debugId=FADD20203AF8426B64756E2164756E21
|
package/dist/registry.js.map
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"import { existsSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { forkCodexSession } from \"#agents/codex-app-server\";\nimport type { AgentRegistry, AgentRegistryOperations } from \"#agents/contracts\";\nimport { hostedCodexHomePath } from \"#agents/execution-host\";\nimport { writeCodexRollout } from \"#agents/rollout/codex\";\nimport { logger } from \"#platform/logger\";\nimport { CODEX_EFFORT_VALUES, type EffortLevel } from \"#types\";\n\nconst VALID_EFFORTS = new Set<EffortLevel>(CODEX_EFFORT_VALUES);\n\n// Codex CLI's own empirical default is gpt-5.6-sol (`codex exec` 2026-07-10 →\n// \"model: gpt-5.6-sol\"), but we deliberately default to gpt-5.6-luna — the\n// cheapest/fastest GPT-5.6 tier — for a general always-on assistant where most\n// queries are light. Heavier work escalates to terra/sol via set_model. This\n// value is passed explicitly to the SDK (see event-processor resolveDefaultModel),\n// so the footer and the actual model stay in sync.\nexport const codexRegistry: AgentRegistry = {\n kind: \"codex\",\n defaultModel: \"gpt-5.6-luna\",\n // defaultEffort intentionally omitted — Codex SDK treats absence as\n // \"reasoning off\". Setting \"high\"/etc. would silently flip on reasoning.\n\n expandModelAlias(s) {\n return s;\n },\n\n validateModel(s) {\n // Codex doesn't publish a closed model list and OpenAI ships new IDs\n // (gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, o3, ...) frequently. Best-effort: accept any\n // non-empty string. Bad IDs surface at SDK call time with a clear error.\n return typeof s === \"string\" && s.length > 0;\n },\n\n validEfforts: CODEX_EFFORT_VALUES,\n validateEffort(s) {\n // GPT-5.6 accepts low/medium/high/xhigh/max; 'minimal'\n // was removed because the Codex API rejects it when default tools\n // (image_gen, web_search) are active.\n return VALID_EFFORTS.has(s);\n },\n\n footerLabel(model, effort) {\n // Codex omits effort to mean \"reasoning off\". Show `(off)` explicitly so\n // the user can distinguish from claude (which always has a default).\n return `${model} · ${effort ?? \"(off)\"}`;\n },\n};\n\nexport const codexRegistryOperations: AgentRegistryOperations = {\n writeRollout(opts) {\n // Codex SDK exposes the resume key as `threadId`; AgentRegistry unifies\n // the name to `sessionId` so callers don't branch on agent.\n // `reuseSessionId` (if any) is forwarded as `threadId` so claude→codex→claude\n // round-trips also keep one continuous codex thread instead of orphaning a\n // fresh uuidv7 on every switch.\n const { threadId, rolloutPath } = writeCodexRollout({\n cwd: opts.cwd,\n entries: opts.entries,\n model: opts.model ?? codexRegistry.defaultModel,\n ...(opts.effort ? { effort: opts.effort } : {}),\n ...(opts.reuseSessionId ? { threadId: opts.reuseSessionId } : {}),\n });\n return { sessionId: threadId, rolloutPath };\n },\n\n // The TypeScript SDK does not expose forking yet, but the bundled Codex App\n // Server does. Native thread/fork preserves the provider's stored prefix,\n // including tool structure, which gives prompt caching the best chance to\n // reuse the parent context. Callers retain unified-log synthesis as fallback.\n async forkSession({ parentSessionId }) {\n return await forkCodexSession(parentSessionId);\n },\n\n // Codex stores rollouts at `~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-<ts>-<threadId>.jsonl`.\n // The date prefix is unknown at cleanup time (it's the *original* write\n // timestamp, not \"now\"), so we glob across the whole sessions tree by\n // threadId suffix. With at most a few thousand files in active use this\n // is well under a millisecond on a warm filesystem.\n async cleanupRollouts({ sessionIds }) {\n if (sessionIds.length === 0) return;\n const sessionsDir = join(hostedCodexHomePath(), \"sessions\");\n // No sessions directory means there are no provider rollouts left to remove.\n if (!existsSync(sessionsDir)) return;\n const failures: unknown[] = [];\n // One Glob per threadId so a single corrupt entry can't poison the rest.\n // Bun.Glob's `scan` yields paths relative to its base dir.\n for (const tid of sessionIds) {\n try {\n const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);\n for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {\n const path = join(sessionsDir, rel);\n try {\n unlinkSync(path);\n } catch (e) {\n if ((e as NodeJS.ErrnoException)?.code !== \"ENOENT\") {\n logger.warn({ err: e, path }, \"codex cleanupRollouts: unlink failed\");\n failures.push(e);\n }\n }\n }\n } catch (e) {\n logger.warn({ err: e, threadId: tid }, \"codex cleanupRollouts: scan failed\");\n failures.push(e);\n }\n }\n if (failures.length > 0) {\n throw new AggregateError(failures, \"codex cleanupRollouts failed\");\n }\n },\n};\n",
|
|
7
7
|
"import { type ChildProcessWithoutNullStreams, spawn } from \"node:child_process\";\nimport { codexCliScriptPath } from \"#agents/codex-native-multi-agent\";\nimport { hostedCodexHomePath } from \"#agents/execution-host\";\nimport { latestCodexRolloutPath } from \"#agents/rollout/codex\";\nimport { NEGOTIUM_VERSION } from \"#version\";\n\ninterface CodexAppServerForkResult {\n forkId: string;\n rolloutPath: string;\n}\n\ninterface CodexAppServerForkHost {\n spawnServer(): ChildProcessWithoutNullStreams;\n findRolloutPath(threadId: string): string | undefined;\n timeoutMs: number;\n}\n\ntype JsonRpcResponse = {\n id?: number;\n result?: { thread?: { id?: unknown } };\n error?: { message?: unknown };\n};\n\nexport function createCodexAppServerForker(host: CodexAppServerForkHost) {\n return async (parentThreadId: string): Promise<CodexAppServerForkResult> => {\n const child = host.spawnServer();\n\n return await new Promise<CodexAppServerForkResult>((resolve, reject) => {\n let settled = false;\n let stdoutBuffer = \"\";\n let stderr = \"\";\n const timer = setTimeout(\n () => finish(new Error(\"Codex thread fork timed out\")),\n host.timeoutMs,\n );\n\n const finish = (error?: Error, result?: CodexAppServerForkResult) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n child.stdin.end();\n child.kill();\n } catch {\n // The app server may already have exited after stdin closed.\n }\n if (error) reject(error);\n else if (result) resolve(result);\n else reject(new Error(\"Codex thread fork returned no result\"));\n };\n\n const send = (message: Record<string, unknown>) => {\n child.stdin.write(`${JSON.stringify(message)}\\n`);\n };\n\n child.stderr.on(\"data\", (chunk) => {\n if (stderr.length < 8_192) stderr += String(chunk);\n });\n child.on(\"error\", (error) => finish(error));\n child.on(\"exit\", (code, signal) => {\n if (settled) return;\n const detail = signal ? `signal ${signal}` : `code ${code ?? 1}`;\n finish(\n new Error(\n `Codex app server exited with ${detail}${stderr.trim() ? `: ${stderr.trim()}` : \"\"}`,\n ),\n );\n });\n child.stdout.on(\"data\", (chunk) => {\n stdoutBuffer += String(chunk);\n for (;;) {\n const newline = stdoutBuffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = stdoutBuffer.slice(0, newline);\n stdoutBuffer = stdoutBuffer.slice(newline + 1);\n let message: JsonRpcResponse;\n try {\n message = JSON.parse(line) as JsonRpcResponse;\n } catch {\n continue;\n }\n\n if (message.id === 1) {\n if (message.error) {\n finish(new Error(String(message.error.message || \"Codex initialization failed\")));\n return;\n }\n send({ method: \"initialized\" });\n send({ id: 2, method: \"thread/fork\", params: { threadId: parentThreadId } });\n continue;\n }\n if (message.id !== 2) continue;\n if (message.error) {\n finish(new Error(String(message.error.message || \"Codex thread fork failed\")));\n return;\n }\n const forkId = message.result?.thread?.id;\n if (typeof forkId !== \"string\" || !forkId) {\n finish(new Error(\"Codex thread fork returned no thread id\"));\n return;\n }\n const rolloutPath = host.findRolloutPath(forkId);\n if (!rolloutPath) {\n finish(new Error(`Codex thread fork rollout was not found for ${forkId}`));\n return;\n }\n finish(undefined, { forkId, rolloutPath });\n return;\n }\n });\n\n send({\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"negotium\", version: NEGOTIUM_VERSION },\n },\n });\n });\n };\n}\n\nconst forkCodexThread = createCodexAppServerForker({\n spawnServer() {\n return spawn(process.execPath, [codexCliScriptPath(), \"app-server\", \"--stdio\"], {\n env: { ...process.env, CODEX_HOME: hostedCodexHomePath() },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n },\n findRolloutPath: latestCodexRolloutPath,\n timeoutMs: 15_000,\n});\n\nexport async function forkCodexSession(parentThreadId: string): Promise<CodexAppServerForkResult> {\n return await forkCodexThread(parentThreadId);\n}\n",
|
|
8
8
|
"import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdtempSync,\n readFileSync,\n renameSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { NEGOTIUM_VERSION } from \"#version\";\n\ntype CodexModel = Record<string, unknown>;\ntype CodexModelCache = {\n client_version?: unknown;\n models?: unknown;\n};\n\nconst moduleRequire = createRequire(import.meta.url);\nconst codexSdkPackagePath = moduleRequire.resolve(\"@openai/codex-sdk/package.json\");\nconst codexSdkRequire = createRequire(codexSdkPackagePath);\nconst bundledCodexPackagePath = codexSdkRequire.resolve(\"@openai/codex/package.json\");\n\nfunction readPackageVersion(packageJsonPath: string): string {\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n if (typeof parsed.version !== \"string\" || !parsed.version.trim()) {\n throw new Error(`Codex package has no valid version: ${packageJsonPath}`);\n }\n return parsed.version;\n}\n\nexport const BUNDLED_CODEX_VERSION = readPackageVersion(bundledCodexPackagePath);\nconst SAFE_BUNDLED_CODEX_VERSION = BUNDLED_CODEX_VERSION.replace(/[^a-zA-Z0-9._-]/g, \"_\");\nconst NEGOTIUM_MODEL_CACHE = `negotium-models-cache-${SAFE_BUNDLED_CODEX_VERSION}.json`;\nconst NEGOTIUM_MODEL_CATALOG = `negotium-model-catalog-${SAFE_BUNDLED_CODEX_VERSION}.json`;\n\nexport function codexCliScriptPath(): string {\n return join(dirname(bundledCodexPackagePath), \"bin\", \"codex.js\");\n}\n\nfunction parseCodexModelCache(contents: string, sourcePath: string): CodexModelCache {\n let parsed: CodexModelCache;\n try {\n parsed = JSON.parse(contents) as CodexModelCache;\n } catch (error) {\n throw new Error(`Codex model cache is invalid JSON: ${sourcePath}`, { cause: error });\n }\n if (!Array.isArray(parsed.models) || parsed.models.length === 0) {\n throw new Error(`Codex model cache has no models: ${sourcePath}`);\n }\n return parsed;\n}\n\nfunction readCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const contents = readFileSync(cachePath, \"utf8\");\n return { contents, parsed: parseCodexModelCache(contents, cachePath) };\n}\n\nfunction readCompatibleCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const cache = readCodexModelCache(cachePath);\n if (cache.parsed.client_version !== BUNDLED_CODEX_VERSION) {\n const found =\n typeof cache.parsed.client_version === \"string\"\n ? cache.parsed.client_version\n : \"missing or invalid\";\n throw new Error(\n `Codex model cache version ${found} does not match Negotium's bundled Codex ${BUNDLED_CODEX_VERSION}: ${cachePath}`,\n );\n }\n return cache;\n}\n\nfunction writePrivateFileAtomic(path: string, contents: string): void {\n if (existsSync(path) && readFileSync(path, \"utf8\") === contents) return;\n\n const tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n try {\n writeFileSync(tempPath, contents, { encoding: \"utf8\", mode: 0o600 });\n renameSync(tempPath, path);\n chmodSync(path, 0o600);\n } finally {\n try {\n unlinkSync(tempPath);\n } catch {\n // renameSync normally consumed the temporary file.\n }\n }\n}\n\nexport function bundledCodexModelCachePath(authFilePath: string): string {\n return join(dirname(authFilePath), NEGOTIUM_MODEL_CACHE);\n}\n\nasync function bootstrapCodexModelCache(codexHome: string, cachePath: string): Promise<void> {\n const child = spawn(process.execPath, [codexCliScriptPath(), \"app-server\", \"--stdio\"], {\n env: { ...process.env, CODEX_HOME: codexHome },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n let stdoutBuffer = \"\";\n let stderr = \"\";\n const timer = setTimeout(\n () => finish(new Error(\"timed out while refreshing the Codex model catalog\")),\n 15_000,\n );\n\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n child.stdin.end();\n child.kill();\n } catch {\n // The app server may already have exited after stdin closed.\n }\n if (error) reject(error);\n else if (!existsSync(cachePath)) reject(new Error(\"Codex did not create its model cache\"));\n else resolve();\n };\n\n const send = (message: Record<string, unknown>) => {\n child.stdin.write(`${JSON.stringify(message)}\\n`);\n };\n\n child.stderr.on(\"data\", (chunk) => {\n if (stderr.length < 4_096) stderr += String(chunk);\n });\n child.on(\"error\", (error) => finish(error));\n child.on(\"exit\", (code, signal) => {\n if (!settled) {\n finish(\n new Error(\n `Codex model catalog refresh exited with ${signal ? `signal ${signal}` : `code ${code ?? 1}`}${stderr.trim() ? `: ${stderr.trim()}` : \"\"}`,\n ),\n );\n }\n });\n child.stdout.on(\"data\", (chunk) => {\n stdoutBuffer += String(chunk);\n for (;;) {\n const newline = stdoutBuffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = stdoutBuffer.slice(0, newline);\n stdoutBuffer = stdoutBuffer.slice(newline + 1);\n let message: { id?: number; error?: { message?: string } };\n try {\n message = JSON.parse(line) as typeof message;\n } catch {\n continue;\n }\n if (message.id === 1) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex initialization failed\"));\n return;\n }\n send({ method: \"initialized\" });\n send({ id: 2, method: \"model/list\", params: { includeHidden: true } });\n } else if (message.id === 2) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex model listing failed\"));\n } else {\n finish();\n }\n return;\n }\n }\n });\n\n send({\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"negotium\", version: NEGOTIUM_VERSION },\n capabilities: { experimentalApi: true },\n },\n });\n });\n}\n\nasync function bootstrapIsolatedCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void>,\n): Promise<string> {\n const sourceHome = dirname(authFilePath);\n const isolatedHome = mkdtempSync(join(tmpdir(), \"negotium-codex-models-\"));\n const isolatedCachePath = join(isolatedHome, \"models_cache.json\");\n\n try {\n const isolatedAuthPath = join(isolatedHome, \"auth.json\");\n copyFileSync(authFilePath, isolatedAuthPath);\n chmodSync(isolatedAuthPath, 0o600);\n\n // Preserve custom provider configuration while keeping the bundled CLI's\n // cache write completely outside the user's shared CODEX_HOME.\n const sourceConfigPath = join(sourceHome, \"config.toml\");\n if (existsSync(sourceConfigPath)) {\n const isolatedConfigPath = join(isolatedHome, \"config.toml\");\n copyFileSync(sourceConfigPath, isolatedConfigPath);\n chmodSync(isolatedConfigPath, 0o600);\n }\n\n await bootstrap(isolatedHome, isolatedCachePath);\n return readCompatibleCodexModelCache(isolatedCachePath).contents;\n } finally {\n rmSync(isolatedHome, { recursive: true, force: true });\n }\n}\n\nexport async function ensureCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void> = bootstrapCodexModelCache,\n): Promise<string> {\n const codexHome = dirname(authFilePath);\n const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;\n if (configuredCachePath) {\n if (!existsSync(configuredCachePath)) {\n throw new Error(`Configured Codex model cache does not exist: ${configuredCachePath}`);\n }\n readCompatibleCodexModelCache(configuredCachePath);\n return configuredCachePath;\n }\n\n // The global Codex CLI owns models_cache.json and may update it to a schema\n // newer than the SDK bundled by Negotium. Snapshot a cache generated for our\n // exact bundled version so later global CLI updates cannot break turns.\n const bundledCachePath = bundledCodexModelCachePath(authFilePath);\n const sharedCachePath = join(codexHome, \"models_cache.json\");\n if (existsSync(sharedCachePath)) {\n try {\n const shared = readCompatibleCodexModelCache(sharedCachePath);\n // Keep model metadata fresh while the global CLI remains compatible.\n writePrivateFileAtomic(bundledCachePath, shared.contents);\n return bundledCachePath;\n } catch {\n // A compatible private snapshot is safer than failing because another\n // process briefly exposed an incomplete shared-cache write.\n }\n }\n\n if (existsSync(bundledCachePath)) {\n try {\n readCompatibleCodexModelCache(bundledCachePath);\n return bundledCachePath;\n } catch {\n // Re-bootstrap below instead of passing a corrupt or version-mismatched\n // private snapshot into this SDK version.\n }\n }\n\n const refreshedContents = await bootstrapIsolatedCodexModelCache(authFilePath, bootstrap);\n writePrivateFileAtomic(bundledCachePath, refreshedContents);\n return bundledCachePath;\n}\n\n/**\n * Codex can resolve model metadata before `features.multi_agent=false`, so a\n * model-advertised v1/v2 value may still register native collaboration tools.\n * Feed Codex an authoritative copy of its own catalog with only that field\n * disabled. Runtime MCP delegation remains available independently.\n */\nexport function writeCodexCatalogWithNativeMultiAgentDisabled(\n authFilePath: string,\n sourcePath: string,\n): string {\n const codexHome = dirname(authFilePath);\n const outputPath = join(codexHome, NEGOTIUM_MODEL_CATALOG);\n\n const parsed = readCodexModelCache(sourcePath).parsed;\n\n const models = (parsed.models as unknown[]).map((model, index): CodexModel => {\n if (!model || typeof model !== \"object\" || Array.isArray(model)) {\n throw new Error(`Codex model cache entry ${index} is invalid: ${sourcePath}`);\n }\n return { ...(model as CodexModel), multi_agent_version: \"disabled\" };\n });\n const contents = `${JSON.stringify({ models }, null, 2)}\\n`;\n writePrivateFileAtomic(outputPath, contents);\n return outputPath;\n}\n",
|
|
9
|
-
"export const NEGOTIUM_VERSION = \"0.2.
|
|
9
|
+
"export const NEGOTIUM_VERSION = \"0.2.13\";\n",
|
|
10
10
|
"import { randomUUID } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { AgentRegistry, AgentRegistryOperations } from \"#agents/contracts\";\nimport { assertUuidLike, ensureCwdExists, extractChatPairs } from \"#agents/rollout/shared\";\nimport { logger } from \"#platform/logger\";\nimport { MAESTRO_EFFORT_VALUES } from \"#types\";\n\nconst ALIAS_MAP: Record<string, string> = {\n \"deepseek-pro\": \"deepseek-v4-pro\",\n // \"deepseek-flash\" was disabled in 0.1.25 because DeepSeek had retired its\n // old flash model. \"DeepSeek-V4-Flash-0731\" (released 2026-07-31) is an\n // unrelated, currently-live model reusing a similar name — verified with a\n // live API call before re-enabling this alias.\n \"deepseek-flash\": \"deepseek-v4-flash\",\n kimi: \"kimi-k3\",\n \"kimi-pro\": \"kimi-k3\",\n \"kimi-code\": \"kimi-k2.7-code\",\n};\nconst VALID_MODELS = new Set([...Object.keys(ALIAS_MAP), ...Object.values(ALIAS_MAP)]);\nconst VALID_EFFORTS = new Set(MAESTRO_EFFORT_VALUES);\n\nexport const maestroRegistry: AgentRegistry = {\n kind: \"maestro\",\n defaultModel: \"deepseek-pro\",\n defaultEffort: \"medium\",\n expandModelAlias(model) {\n return ALIAS_MAP[model] ?? model;\n },\n validateModel(model) {\n return VALID_MODELS.has(model);\n },\n validEfforts: MAESTRO_EFFORT_VALUES,\n validateEffort(effort) {\n return VALID_EFFORTS.has(effort);\n },\n footerLabel(model, effort) {\n return effort ? `${model} · ${effort}` : model;\n },\n};\n\nfunction maestroSessionsDir(): string {\n return join(\n process.env.MAESTRO_DATA_DIR\n ? resolve(process.env.MAESTRO_DATA_DIR)\n : join(homedir(), \".maestro\"),\n \"sessions\",\n );\n}\n\nfunction maestroSessionPath(sessionId: string): string {\n return join(maestroSessionsDir(), `${sessionId}.jsonl`);\n}\n\nfunction maestroActiveSessionPath(sessionId: string): string {\n return join(maestroSessionsDir(), `${sessionId}.active.jsonl`);\n}\n\nfunction existingCreatedAt(path: string): string | undefined {\n if (!existsSync(path)) return undefined;\n try {\n const firstLine = readFileSync(path, \"utf8\").split(\"\\n\", 1)[0];\n const parsed = JSON.parse(firstLine) as { _meta?: { createdAt?: unknown } };\n return typeof parsed._meta?.createdAt === \"string\" ? parsed._meta.createdAt : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Placeholder for a synthesized turn whose text is blank.\n *\n * Moonshot (Kimi) hard-rejects the *whole* request when any history message has\n * empty content — `Kimi API 400: the message at position N with role 'user'\n * must not be empty` (verified against the live API, kimi-k3). DeepSeek's\n * validator is laxer today but the same shape is not worth relying on.\n *\n * maestro-agent-sdk 0.2.1 drops empty assistant slots, but only in the\n * *content-block* form (`content: []`); the pair encoder below writes plain\n * strings, and `content: \"\"` still reaches the wire and 400s. Blank sides are\n * reachable here from real conversations — an attachment-only user submission\n * records a `user_message` with `content: \"\"`, and `renderUserPromptBatch`\n * passes it through verbatim — so the synthesized session must not contain one.\n *\n * We substitute rather than drop: dropping a pair would silently delete a turn\n * from the historical narrative the next agent reads, while a one-line marker\n * keeps the turn boundary and tells the model why the slot is thin.\n */\nconst BLANK_TURN_PLACEHOLDER = \"(no text content in this turn)\";\n\nfunction nonEmptyTurnText(text: string): string {\n return text.trim().length > 0 ? text : BLANK_TURN_PLACEHOLDER;\n}\n\nfunction writeRollout(options: Parameters<AgentRegistryOperations[\"writeRollout\"]>[0]) {\n const sessionId = options.reuseSessionId ?? randomUUID();\n assertUuidLike(\"sessionId\", sessionId);\n ensureCwdExists(options.cwd);\n const path = maestroSessionPath(sessionId);\n mkdirSync(maestroSessionsDir(), { recursive: true });\n const messages = extractChatPairs(options.entries).flatMap((pair) => [\n { role: \"user\", content: nonEmptyTurnText(pair.userText) },\n { role: \"assistant\", content: nonEmptyTurnText(pair.assistantText) },\n ]);\n const lines = [\n {\n _meta: {\n version: 1,\n cwd: options.cwd,\n createdAt: existingCreatedAt(path) ?? new Date().toISOString(),\n // Deliberately a literal, not the SDK's `MAESTRO_SDK_VERSION`: this\n // module must not statically import maestro-agent-sdk (asserted by\n // tests/core/daemon-import-boundaries.test.ts — the SDK stays off the\n // daemon startup path). The value names the session *format* version\n // this encoder targets, which is what a reader of the header needs.\n sdkVersion: \"0.2.0\",\n },\n },\n ...messages,\n ];\n writeFileSync(path, `${lines.map((line) => JSON.stringify(line)).join(\"\\n\")}\\n`, {\n mode: 0o600,\n });\n return { sessionId, rolloutPath: path };\n}\n\nexport const maestroRegistryOperations: AgentRegistryOperations = {\n writeRollout(options) {\n return writeRollout(options);\n },\n async forkSession(options) {\n // Fork the full raw history while preserving the compacted working view.\n // A compacted parent that cannot copy its active projection is not a usable\n // cache-preserving fork, so let the caller fall back to bounded synthesis.\n const { deleteMaestroSession, forkSessionAt, loadRawMaestroSession } = await import(\n \"maestro-agent-sdk\"\n );\n const parentMessages = loadRawMaestroSession(options.parentSessionId);\n if (!parentMessages) {\n throw new Error(`Maestro parent session not found: ${options.parentSessionId}`);\n }\n const parentHasActiveProjection = existsSync(maestroActiveSessionPath(options.parentSessionId));\n const fork = forkSessionAt({\n parentSessionId: options.parentSessionId,\n messageIndex: parentMessages.length,\n cwd: options.cwd,\n userId: String(options.userId),\n });\n if (parentHasActiveProjection && !fork.activeProjectionForked) {\n deleteMaestroSession(fork.sessionId);\n throw new Error(`Maestro active projection could not be forked: ${options.parentSessionId}`);\n }\n const activePath = maestroActiveSessionPath(fork.sessionId);\n return {\n forkId: fork.sessionId,\n rolloutPath: fork.rolloutPath,\n ...(existsSync(activePath) ? { cleanupPaths: [activePath] } : {}),\n };\n },\n async cleanupRollouts(options) {\n // Keep the SDK off the daemon startup path, but use its canonical cleanup\n // once a Maestro session is actually being removed. It also clears memory,\n // task, todo, and in-process file-state sidecars.\n const { deleteMaestroSession } = await import(\"maestro-agent-sdk\");\n const failures: unknown[] = [];\n for (const sessionId of options.sessionIds) {\n try {\n deleteMaestroSession(sessionId);\n const remaining = [\n maestroSessionPath(sessionId),\n maestroActiveSessionPath(sessionId),\n ].filter(existsSync);\n if (remaining.length > 0) {\n throw new Error(`Maestro session files remain after cleanup: ${remaining.join(\", \")}`);\n }\n } catch (error) {\n logger.warn({ err: error, sessionId }, \"maestro cleanupRollouts: cleanup failed\");\n failures.push(error);\n }\n }\n if (failures.length > 0) {\n throw new AggregateError(failures, \"Maestro rollout cleanup failed\");\n }\n },\n};\n",
|
|
11
11
|
"import { claudeRegistry, claudeRegistryOperations } from \"#agents/claude-registry\";\nimport { codexRegistry, codexRegistryOperations } from \"#agents/codex-registry\";\nimport type { AgentRegistry, AgentRegistryOperations } from \"#agents/contracts\";\nimport { maestroRegistry, maestroRegistryOperations } from \"#agents/maestro-registry\";\nimport type { AgentKind } from \"#types\";\n\nexport type {\n AgentRegistry,\n AgentRegistryOperations,\n CleanupRolloutsOptions,\n ForkRegistryOptions,\n ForkRegistryResult,\n WriteRolloutOptions,\n WriteRolloutResult,\n} from \"#agents/contracts\";\n\nconst REGISTRIES: Record<AgentKind, AgentRegistry> = {\n claude: claudeRegistry,\n codex: codexRegistry,\n maestro: maestroRegistry,\n};\n\nexport function getRegistry(agent: AgentKind): AgentRegistry {\n return REGISTRIES[agent];\n}\n\nconst OPERATIONS: Record<AgentKind, AgentRegistryOperations> = {\n claude: claudeRegistryOperations,\n codex: codexRegistryOperations,\n maestro: maestroRegistryOperations,\n};\n\nexport function getRegistryOperations(agent: AgentKind): AgentRegistryOperations {\n return OPERATIONS[agent];\n}\n",
|
|
12
12
|
"import {\n type AgentRegistry,\n type AgentRegistryOperations,\n type CleanupRolloutsOptions,\n type ForkRegistryOptions,\n type ForkRegistryResult,\n getRegistry as resolveCoreRegistry,\n getRegistryOperations as resolveCoreRegistryOperations,\n type WriteRolloutOptions,\n type WriteRolloutResult,\n} from \"@negotium/core/registry\";\n\nexport type {\n AgentRegistry,\n AgentRegistryOperations,\n CleanupRolloutsOptions,\n ForkRegistryOptions,\n ForkRegistryResult,\n WriteRolloutOptions,\n WriteRolloutResult,\n};\n\nexport const getRegistry: typeof resolveCoreRegistry = (agent) => resolveCoreRegistry(agent);\n\nexport const getRegistryOperations: typeof resolveCoreRegistryOperations = (agent) =>\n resolveCoreRegistryOperations(agent);\n"
|
|
13
13
|
],
|
|
14
14
|
"mappings": "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",
|
|
15
|
-
"debugId": "
|
|
15
|
+
"debugId": "FADD20203AF8426B64756E2164756E21",
|
|
16
16
|
"names": []
|
|
17
17
|
}
|
package/dist/rollout.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { type ChildProcess, execFileSync, spawn } from "node:child_process";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
BACKGROUND_BASH_SERVER,
|
|
5
|
+
BASH_RS_BIN,
|
|
6
|
+
BASHRS_SPILL_ROOT,
|
|
7
|
+
BG_BASH_BASE_PORT,
|
|
8
|
+
BG_BASH_MAX_PORT,
|
|
9
|
+
} from "#platform/config";
|
|
4
10
|
import { delay } from "#platform/delay";
|
|
5
11
|
import { logger } from "#platform/logger";
|
|
6
12
|
import { deriveBgBashContextCapability } from "./context";
|
|
@@ -103,7 +109,21 @@ export function createBackgroundBashManager(
|
|
|
103
109
|
const response = await fetchImpl(`http://127.0.0.1:${port}/health`, {
|
|
104
110
|
signal: AbortSignal.timeout(2000),
|
|
105
111
|
});
|
|
106
|
-
|
|
112
|
+
if (!response.ok) return false;
|
|
113
|
+
const body = await response.text();
|
|
114
|
+
// bash-rs (Rust binary) answers with JSON + `instance_id`; the legacy
|
|
115
|
+
// TS server answers with the bare id as `text/plain`. Both exist to
|
|
116
|
+
// confirm this port is answering *our* spawned process, not a stale
|
|
117
|
+
// one left over from a previous manager instance.
|
|
118
|
+
try {
|
|
119
|
+
const parsed = JSON.parse(body);
|
|
120
|
+
if (parsed && typeof parsed === "object" && "instance_id" in parsed) {
|
|
121
|
+
return parsed.instance_id === runtimeServerId;
|
|
122
|
+
}
|
|
123
|
+
} catch {
|
|
124
|
+
// Not JSON — fall through to the plain-text comparison below.
|
|
125
|
+
}
|
|
126
|
+
return body === runtimeServerId;
|
|
107
127
|
} catch {
|
|
108
128
|
return false;
|
|
109
129
|
}
|
|
@@ -127,13 +147,25 @@ export function createBackgroundBashManager(
|
|
|
127
147
|
excludedPorts: ReadonlySet<number> = new Set(),
|
|
128
148
|
): Promise<number> {
|
|
129
149
|
const port = reservedPort ?? (await allocatePort(excludedPorts));
|
|
130
|
-
|
|
150
|
+
// Prefer the Rust binary when the installer (install-bash-rs.mjs) put
|
|
151
|
+
// one in place; otherwise fall back to the TS server unconditionally —
|
|
152
|
+
// e.g. no prebuilt binary for this platform/arch yet. Both speak the
|
|
153
|
+
// same wire protocol (X-Background-Bash-* headers, HMAC capability
|
|
154
|
+
// derived from the same `runtimeCapability` root secret), so either one
|
|
155
|
+
// is a transparent swap from the caller's point of view.
|
|
156
|
+
const [command, args] = BASH_RS_BIN
|
|
157
|
+
? [BASH_RS_BIN, [String(port)]]
|
|
158
|
+
: ["bun", ["run", serverFile, `--port=${port}`]];
|
|
159
|
+
const process = spawnImpl(command, args, {
|
|
131
160
|
stdio: "ignore",
|
|
132
161
|
detached: false,
|
|
133
162
|
env: {
|
|
134
163
|
...(options.env ?? globalThis.process.env),
|
|
135
164
|
NEGOTIUM_BG_BASH_CAPABILITY: runtimeCapability,
|
|
136
165
|
NEGOTIUM_BG_BASH_SERVER_ID: runtimeServerId,
|
|
166
|
+
BASHRS_HTTP_CAPABILITY: runtimeCapability,
|
|
167
|
+
BASHRS_INSTANCE_ID: runtimeServerId,
|
|
168
|
+
BASHRS_SPILL_ROOT,
|
|
137
169
|
},
|
|
138
170
|
});
|
|
139
171
|
|
|
@@ -167,6 +167,30 @@ export const SNIPPETS_API_URL = (
|
|
|
167
167
|
|
|
168
168
|
export const BROWSER_RS_BIN = resolveBrowserRsBin(envText("NEGOTIUM_BROWSER_RS_BIN"));
|
|
169
169
|
|
|
170
|
+
/** bash-rs release tested with this Negotium version — see apps/negotium/install-bash-rs.mjs. */
|
|
171
|
+
export const BASH_RS_VERSION = "v0.1.2";
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Resolve the bash-rs binary the same way `resolveBrowserRsBin` resolves
|
|
175
|
+
* Browser.rs: a versioned private location, no PATH lookup, `undefined`
|
|
176
|
+
* (rather than throwing) when it's missing — callers fall back to the TS
|
|
177
|
+
* `background-bash-server.ts` in that case (see `background-bash/manager.ts`).
|
|
178
|
+
*/
|
|
179
|
+
export function resolveBashRsBin(envValue?: string): string | undefined {
|
|
180
|
+
const override = envValue?.trim();
|
|
181
|
+
const candidate = override
|
|
182
|
+
? resolve(override)
|
|
183
|
+
: resolve(BINARIES_DIR, "bash-rs", BASH_RS_VERSION, "bash-rs");
|
|
184
|
+
try {
|
|
185
|
+
accessSync(candidate, constants.X_OK);
|
|
186
|
+
return candidate;
|
|
187
|
+
} catch {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export const BASH_RS_BIN = resolveBashRsBin(envText("NEGOTIUM_BASH_RS_BIN"));
|
|
193
|
+
|
|
170
194
|
// Managed Browser.rs terminates MCP transports and security policy itself.
|
|
171
195
|
export function resolveBrowserMcpBin(envValue?: string): string {
|
|
172
196
|
const override = envValue?.trim();
|
|
@@ -357,6 +381,14 @@ export const DM_CMD_DIR = resolve(RUN_DIR, "dm-commands");
|
|
|
357
381
|
export const DM_RESP_DIR = resolve(RUN_DIR, "dm-responses");
|
|
358
382
|
export const SESSION_INBOX_DIR = resolve(RUN_DIR, "session-inbox");
|
|
359
383
|
export const SESSION_ASKS_DIR = resolve(RUN_DIR, "session-asks");
|
|
384
|
+
/**
|
|
385
|
+
* Passed to `bash-rs` as `BASHRS_SPILL_ROOT`. Each job gets a subdirectory
|
|
386
|
+
* here (`{bash_id}/meta.json`, `result.json`, `stdout.log`, `stderr.log`) —
|
|
387
|
+
* see bash-rs-mcp's `journal.rs`. `runtime/bashrs-completions.ts` watches
|
|
388
|
+
* this directory and turns `result.json` into a session-inbox `tell`, the
|
|
389
|
+
* same way `background-bash-server.ts` used to write one directly.
|
|
390
|
+
*/
|
|
391
|
+
export const BASHRS_SPILL_ROOT = resolve(RUN_DIR, "bashrs");
|
|
360
392
|
export const PLAYWRIGHT_BASE_PORT = parsePortEnv(process.env.PLAYWRIGHT_BASE_PORT, 9100);
|
|
361
393
|
export const PLAYWRIGHT_MAX_PORT = parsePortEnv(process.env.PLAYWRIGHT_MAX_PORT, 9499);
|
|
362
394
|
export const PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, "playwright-ports");
|