reasonix 0.0.1
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/LICENSE +21 -0
- package/README.md +114 -0
- package/dist/chunk-XILYSYPT.js +261 -0
- package/dist/chunk-XILYSYPT.js.map +1 -0
- package/dist/cli/chunk-OSNTDDD6.js +262 -0
- package/dist/cli/chunk-OSNTDDD6.js.map +1 -0
- package/dist/cli/client-OWZXRMOE.js +10 -0
- package/dist/cli/client-OWZXRMOE.js.map +1 -0
- package/dist/cli/index.js +1089 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/client-4JTJKRDV.js +9 -0
- package/dist/client-4JTJKRDV.js.map +1 -0
- package/dist/index.d.ts +396 -0
- package/dist/index.js +716 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts","../../src/harvest.ts","../../src/memory.ts","../../src/repair/scavenge.ts","../../src/repair/storm.ts","../../src/repair/truncation.ts","../../src/repair/index.ts","../../src/telemetry.ts","../../src/tools.ts","../../src/loop.ts","../../src/env.ts","../../src/index.ts","../../src/cli/commands/chat.tsx","../../src/cli/ui/App.tsx","../../src/cli/ui/EventLog.tsx","../../src/cli/ui/markdown.tsx","../../src/cli/ui/PromptInput.tsx","../../src/cli/ui/StatsPanel.tsx","../../src/cli/commands/run.ts","../../src/cli/commands/stats.ts","../../src/cli/commands/version.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { VERSION } from \"../index.js\";\nimport { chatCommand } from \"./commands/chat.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { statsCommand } from \"./commands/stats.js\";\nimport { versionCommand } from \"./commands/version.js\";\n\nconst DEFAULT_SYSTEM =\n \"You are Reasonix, a helpful DeepSeek-powered assistant. Be concise and accurate. Use tools when available.\";\n\nconst program = new Command();\nprogram\n .name(\"reasonix\")\n .description(\"DeepSeek-native agent framework — built for cache hits and cheap tokens.\")\n .version(VERSION);\n\nprogram\n .command(\"chat\")\n .description(\"Interactive Ink TUI with live cache/cost panel.\")\n .option(\"-m, --model <id>\", \"DeepSeek model id\", \"deepseek-chat\")\n .option(\"-s, --system <prompt>\", \"System prompt (pinned in the immutable prefix)\", DEFAULT_SYSTEM)\n .option(\"--transcript <path>\", \"Write a JSONL transcript to this path\")\n .action(async (opts) => {\n await chatCommand({\n model: opts.model,\n system: opts.system,\n transcript: opts.transcript,\n });\n });\n\nprogram\n .command(\"run <task>\")\n .description(\"Run a single task non-interactively, streaming output.\")\n .option(\"-m, --model <id>\", \"DeepSeek model id\", \"deepseek-chat\")\n .option(\"-s, --system <prompt>\", \"System prompt\", DEFAULT_SYSTEM)\n .action(async (task: string, opts) => {\n await runCommand({ task, model: opts.model, system: opts.system });\n });\n\nprogram\n .command(\"stats <transcript>\")\n .description(\"Summarize a JSONL transcript produced by `reasonix chat --transcript`.\")\n .action((transcript: string) => {\n statsCommand({ transcript });\n });\n\nprogram.command(\"version\").description(\"Print Reasonix version.\").action(versionCommand);\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err);\n process.exit(1);\n});\n","/**\n * Pillar 2 — R1 Thought Harvesting.\n *\n * v0.0.1 stub. Real implementation lands in v0.2 as a constrained V3 call\n * against a strict JSON schema. The shape below is the public contract that\n * downstream code may already depend on.\n */\n\nexport interface TypedPlanState {\n subgoals: string[];\n hypotheses: string[];\n uncertainties: string[];\n rejectedPaths: string[];\n}\n\nexport function emptyPlanState(): TypedPlanState {\n return { subgoals: [], hypotheses: [], uncertainties: [], rejectedPaths: [] };\n}\n\nexport function isPlanStateEmpty(s: TypedPlanState): boolean {\n return (\n s.subgoals.length === 0 &&\n s.hypotheses.length === 0 &&\n s.uncertainties.length === 0 &&\n s.rejectedPaths.length === 0\n );\n}\n\n/** v0.0.1 stub — returns empty state. */\nexport async function harvest(_reasoningContent: string | null): Promise<TypedPlanState> {\n return emptyPlanState();\n}\n","import { createHash } from \"node:crypto\";\nimport type { ChatMessage, ToolSpec } from \"./types.js\";\n\nexport interface ImmutablePrefixOptions {\n system: string;\n toolSpecs?: readonly ToolSpec[];\n fewShots?: readonly ChatMessage[];\n}\n\nexport class ImmutablePrefix {\n readonly system: string;\n readonly toolSpecs: readonly ToolSpec[];\n readonly fewShots: readonly ChatMessage[];\n\n constructor(opts: ImmutablePrefixOptions) {\n this.system = opts.system;\n this.toolSpecs = Object.freeze([...(opts.toolSpecs ?? [])]);\n this.fewShots = Object.freeze([...(opts.fewShots ?? [])]);\n }\n\n toMessages(): ChatMessage[] {\n return [{ role: \"system\", content: this.system }, ...this.fewShots.map((m) => ({ ...m }))];\n }\n\n tools(): ToolSpec[] {\n return this.toolSpecs.map((t) => structuredClone(t) as ToolSpec);\n }\n\n get fingerprint(): string {\n const blob = JSON.stringify({\n system: this.system,\n tools: this.toolSpecs,\n shots: this.fewShots,\n });\n return createHash(\"sha256\").update(blob).digest(\"hex\").slice(0, 16);\n }\n}\n\nexport class AppendOnlyLog {\n private _entries: ChatMessage[] = [];\n\n append(message: ChatMessage): void {\n if (!message || typeof message !== \"object\" || !(\"role\" in message)) {\n throw new Error(`invalid log entry: ${JSON.stringify(message)}`);\n }\n this._entries.push(message);\n }\n\n extend(messages: ChatMessage[]): void {\n for (const m of messages) this.append(m);\n }\n\n get entries(): readonly ChatMessage[] {\n return this._entries;\n }\n\n toMessages(): ChatMessage[] {\n return this._entries.map((e) => ({ ...e }));\n }\n\n get length(): number {\n return this._entries.length;\n }\n}\n\nexport class VolatileScratch {\n reasoning: string | null = null;\n planState: Record<string, unknown> | null = null;\n notes: string[] = [];\n\n reset(): void {\n this.reasoning = null;\n this.planState = null;\n this.notes = [];\n }\n}\n","/**\n * Scavenge tool calls leaked into reasoning_content.\n *\n * R1 sometimes emits tool-call JSON inside <think>…</think> and then forgets\n * to surface it in `tool_calls`. This pass extracts plausible calls and\n * proposes them to the loop, which decides whether to merge them with the\n * declared calls.\n */\n\nimport type { ToolCall } from \"../types.js\";\n\nexport interface ScavengeOptions {\n /** Names of tools the model may legitimately call. Other names are ignored. */\n allowedNames: ReadonlySet<string>;\n /** Maximum number of calls to scavenge per pass (defence against runaway). */\n maxCalls?: number;\n}\n\nexport interface ScavengeResult {\n calls: ToolCall[];\n notes: string[];\n}\n\nexport function scavengeToolCalls(\n reasoningContent: string | null | undefined,\n opts: ScavengeOptions,\n): ScavengeResult {\n if (!reasoningContent) return { calls: [], notes: [] };\n const max = opts.maxCalls ?? 4;\n const notes: string[] = [];\n const out: ToolCall[] = [];\n\n for (const candidate of iterateJsonObjects(reasoningContent)) {\n if (out.length >= max) break;\n const call = coerceToToolCall(candidate, opts.allowedNames);\n if (call) {\n out.push(call);\n notes.push(`scavenged call: ${call.function.name}`);\n }\n }\n return { calls: out, notes };\n}\n\n/** Yield every top-level JSON object substring in `text`. */\nfunction* iterateJsonObjects(text: string): Generator<string> {\n for (let i = 0; i < text.length; i++) {\n if (text[i] !== \"{\") continue;\n let depth = 0;\n let inString = false;\n let escaped = false;\n for (let j = i; j < text.length; j++) {\n const c = text[j]!;\n if (escaped) {\n escaped = false;\n continue;\n }\n if (inString) {\n if (c === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (c === '\"') inString = false;\n continue;\n }\n if (c === '\"') inString = true;\n else if (c === \"{\") depth++;\n else if (c === \"}\") {\n depth--;\n if (depth === 0) {\n yield text.slice(i, j + 1);\n i = j;\n break;\n }\n }\n }\n }\n}\n\nfunction coerceToToolCall(\n candidateJson: string,\n allowedNames: ReadonlySet<string>,\n): ToolCall | null {\n let parsed: any;\n try {\n parsed = JSON.parse(candidateJson);\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== \"object\") return null;\n\n // Pattern 1: { name, arguments }\n if (typeof parsed.name === \"string\" && allowedNames.has(parsed.name)) {\n const args = parsed.arguments;\n return {\n function: {\n name: parsed.name,\n arguments: typeof args === \"string\" ? args : JSON.stringify(args ?? {}),\n },\n };\n }\n\n // Pattern 2: OpenAI-style { type: \"function\", function: { name, arguments } }\n if (\n parsed.type === \"function\" &&\n parsed.function &&\n typeof parsed.function.name === \"string\" &&\n allowedNames.has(parsed.function.name)\n ) {\n const args = parsed.function.arguments;\n return {\n type: \"function\",\n function: {\n name: parsed.function.name,\n arguments: typeof args === \"string\" ? args : JSON.stringify(args ?? {}),\n },\n };\n }\n\n // Pattern 3: { tool_name, tool_args } (R1 free-form variant)\n if (typeof parsed.tool_name === \"string\" && allowedNames.has(parsed.tool_name)) {\n return {\n function: {\n name: parsed.tool_name,\n arguments: JSON.stringify(parsed.tool_args ?? {}),\n },\n };\n }\n\n return null;\n}\n","import type { ToolCall } from \"../types.js\";\n\n/**\n * Call-storm breaker.\n *\n * Detects (tool, args) tuples repeating within a sliding window and suppresses\n * the offending call. Surfaces a synthetic tool_result advising the model to\n * change strategy on its next turn.\n */\nexport class StormBreaker {\n private readonly windowSize: number;\n private readonly threshold: number;\n private readonly recent: Array<readonly [string, string]> = [];\n\n constructor(windowSize = 6, threshold = 3) {\n this.windowSize = windowSize;\n this.threshold = threshold;\n }\n\n inspect(call: ToolCall): { suppress: boolean; reason?: string } {\n const sig = signature(call);\n if (!sig) return { suppress: false };\n const count = this.recent.reduce(\n (n, [name, args]) => (name === sig[0] && args === sig[1] ? n + 1 : n),\n 0,\n );\n if (count >= this.threshold - 1) {\n return {\n suppress: true,\n reason: `call-storm suppressed: ${sig[0]} called with identical args ${count + 1} times within window=${this.windowSize}`,\n };\n }\n this.recent.push(sig);\n while (this.recent.length > this.windowSize) this.recent.shift();\n return { suppress: false };\n }\n\n reset(): void {\n this.recent.length = 0;\n }\n}\n\nfunction signature(call: ToolCall): readonly [string, string] | null {\n const name = call.function?.name;\n if (!name) return null;\n return [name, call.function?.arguments ?? \"\"] as const;\n}\n","/**\n * Truncation recovery for tool-call argument JSON cut off mid-structure\n * (typically when the model hits max_tokens before finishing the JSON object).\n *\n * Strategy is purely local: balance braces, close strings, fill missing values\n * with `null`. We deliberately do NOT make a continuation API call here — that\n * decision belongs to the loop, which knows about budgets.\n */\n\nexport interface TruncationRepairResult {\n repaired: string;\n changed: boolean;\n notes: string[];\n}\n\nexport function repairTruncatedJson(input: string): TruncationRepairResult {\n const notes: string[] = [];\n if (!input || !input.trim()) {\n return { repaired: \"{}\", changed: input !== \"{}\", notes: [\"empty input → {}\"] };\n }\n // Fast path: already parseable.\n try {\n JSON.parse(input);\n return { repaired: input, changed: false, notes: [] };\n } catch {\n /* fall through */\n }\n\n const stack: (\"{\" | \"[\" | '\"')[] = [];\n let escaped = false;\n let inString = false;\n let lastSignificant = -1;\n\n for (let i = 0; i < input.length; i++) {\n const c = input[i]!;\n if (!/\\s/.test(c)) lastSignificant = i;\n if (escaped) {\n escaped = false;\n continue;\n }\n if (inString) {\n if (c === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (c === '\"') {\n inString = false;\n stack.pop();\n }\n continue;\n }\n if (c === '\"') {\n inString = true;\n stack.push('\"');\n continue;\n }\n if (c === \"{\" || c === \"[\") stack.push(c);\n else if (c === \"}\" || c === \"]\") stack.pop();\n }\n\n let s = input.slice(0, lastSignificant + 1);\n\n // Trim a trailing comma which would block re-parse.\n if (/,$/.test(s)) {\n s = s.replace(/,$/, \"\");\n notes.push(\"trimmed trailing comma\");\n }\n\n // If we ended on a key without a value: \"foo\": → \"foo\": null\n if (/\"\\s*:\\s*$/.test(s)) {\n s += \" null\";\n notes.push(\"filled dangling key with null\");\n }\n\n // If we ended inside a string, close it.\n if (inString) {\n s += '\"';\n stack.pop();\n notes.push(\"closed unterminated string\");\n }\n\n // Pop remaining open structures in reverse order.\n while (stack.length > 0) {\n const top = stack.pop();\n if (top === \"{\") s += \"}\";\n else if (top === \"[\") s += \"]\";\n else if (top === '\"') s += '\"';\n }\n\n try {\n JSON.parse(s);\n return { repaired: s, changed: true, notes };\n } catch (err) {\n notes.push(`fallback to {}: ${(err as Error).message}`);\n return { repaired: \"{}\", changed: true, notes };\n }\n}\n","/**\n * Pillar 3 — Tool-Call Repair pipeline.\n *\n * Order of passes per turn:\n * 1. scavenge — recover tool calls leaked into <think>\n * 2. truncation — close any half-emitted argument JSON\n * 3. storm breaker — drop call-storm repeats\n *\n * Schema flattening is applied during loop construction (it changes what we\n * advertise to the model), not per-turn.\n */\n\nimport type { ToolCall } from \"../types.js\";\nimport { scavengeToolCalls } from \"./scavenge.js\";\nimport { StormBreaker } from \"./storm.js\";\nimport { repairTruncatedJson } from \"./truncation.js\";\n\nexport { analyzeSchema, flattenSchema, nestArguments } from \"./flatten.js\";\nexport type { FlattenDecision } from \"./flatten.js\";\nexport { repairTruncatedJson } from \"./truncation.js\";\nexport type { TruncationRepairResult } from \"./truncation.js\";\nexport { scavengeToolCalls } from \"./scavenge.js\";\nexport type { ScavengeOptions, ScavengeResult } from \"./scavenge.js\";\nexport { StormBreaker } from \"./storm.js\";\n\nexport interface RepairReport {\n scavenged: number;\n truncationsFixed: number;\n stormsBroken: number;\n notes: string[];\n}\n\nexport interface ToolCallRepairOptions {\n allowedToolNames: ReadonlySet<string>;\n stormWindow?: number;\n stormThreshold?: number;\n maxScavenge?: number;\n}\n\nexport class ToolCallRepair {\n private readonly storm: StormBreaker;\n private readonly opts: ToolCallRepairOptions;\n\n constructor(opts: ToolCallRepairOptions) {\n this.opts = opts;\n this.storm = new StormBreaker(opts.stormWindow ?? 6, opts.stormThreshold ?? 3);\n }\n\n process(\n declaredCalls: ToolCall[],\n reasoningContent: string | null,\n ): { calls: ToolCall[]; report: RepairReport } {\n const report: RepairReport = {\n scavenged: 0,\n truncationsFixed: 0,\n stormsBroken: 0,\n notes: [],\n };\n\n // 1. Scavenge — only add calls whose (name,args) signature is novel.\n const scavenged = scavengeToolCalls(reasoningContent, {\n allowedNames: this.opts.allowedToolNames,\n maxCalls: this.opts.maxScavenge ?? 4,\n });\n const seenSignatures = new Set(declaredCalls.map(signature));\n const merged = [...declaredCalls];\n for (const sc of scavenged.calls) {\n if (!seenSignatures.has(signature(sc))) {\n merged.push(sc);\n report.scavenged++;\n seenSignatures.add(signature(sc));\n }\n }\n report.notes.push(...scavenged.notes);\n\n // 2. Truncation repair on argument JSON.\n for (const call of merged) {\n const args = call.function?.arguments ?? \"\";\n const r = repairTruncatedJson(args);\n if (r.changed) {\n call.function.arguments = r.repaired;\n report.truncationsFixed++;\n report.notes.push(...r.notes.map((n) => `[${call.function.name}] ${n}`));\n }\n }\n\n // 3. Storm breaker.\n const filtered: ToolCall[] = [];\n for (const call of merged) {\n const verdict = this.storm.inspect(call);\n if (verdict.suppress) {\n report.stormsBroken++;\n if (verdict.reason) report.notes.push(verdict.reason);\n continue;\n }\n filtered.push(call);\n }\n\n return { calls: filtered, report };\n }\n}\n\nfunction signature(call: ToolCall): string {\n return `${call.function?.name ?? \"\"}::${call.function?.arguments ?? \"\"}`;\n}\n","import type { Usage } from \"./client.js\";\n\n/** USD per 1M tokens. Update as DeepSeek pricing changes. */\nexport const DEEPSEEK_PRICING: Record<\n string,\n { inputCacheHit: number; inputCacheMiss: number; output: number }\n> = {\n \"deepseek-chat\": { inputCacheHit: 0.07, inputCacheMiss: 0.27, output: 1.1 },\n \"deepseek-reasoner\": { inputCacheHit: 0.14, inputCacheMiss: 0.55, output: 2.19 },\n};\n\n/** Reference Claude Sonnet 4.6 pricing (USD per 1M tokens). */\nexport const CLAUDE_SONNET_PRICING = { input: 3.0, output: 15.0 };\n\nexport function costUsd(model: string, usage: Usage): number {\n const p = DEEPSEEK_PRICING[model];\n if (!p) return 0;\n return (\n (usage.promptCacheHitTokens * p.inputCacheHit +\n usage.promptCacheMissTokens * p.inputCacheMiss +\n usage.completionTokens * p.output) /\n 1_000_000\n );\n}\n\nexport function claudeEquivalentCost(usage: Usage): number {\n return (\n (usage.promptTokens * CLAUDE_SONNET_PRICING.input +\n usage.completionTokens * CLAUDE_SONNET_PRICING.output) /\n 1_000_000\n );\n}\n\nexport interface TurnStats {\n turn: number;\n model: string;\n usage: Usage;\n cost: number;\n cacheHitRatio: number;\n}\n\nexport interface SessionSummary {\n turns: number;\n totalCostUsd: number;\n claudeEquivalentUsd: number;\n savingsVsClaudePct: number;\n cacheHitRatio: number;\n}\n\nexport class SessionStats {\n readonly turns: TurnStats[] = [];\n\n record(turn: number, model: string, usage: Usage): TurnStats {\n const cost = costUsd(model, usage);\n const stats: TurnStats = {\n turn,\n model,\n usage,\n cost,\n cacheHitRatio: usage.cacheHitRatio,\n };\n this.turns.push(stats);\n return stats;\n }\n\n get totalCost(): number {\n return this.turns.reduce((sum, t) => sum + t.cost, 0);\n }\n\n get totalClaudeEquivalent(): number {\n return this.turns.reduce((sum, t) => sum + claudeEquivalentCost(t.usage), 0);\n }\n\n get savingsVsClaude(): number {\n const c = this.totalClaudeEquivalent;\n return c > 0 ? 1 - this.totalCost / c : 0;\n }\n\n get aggregateCacheHitRatio(): number {\n let hit = 0;\n let miss = 0;\n for (const t of this.turns) {\n hit += t.usage.promptCacheHitTokens;\n miss += t.usage.promptCacheMissTokens;\n }\n const denom = hit + miss;\n return denom > 0 ? hit / denom : 0;\n }\n\n summary(): SessionSummary {\n return {\n turns: this.turns.length,\n totalCostUsd: round(this.totalCost, 6),\n claudeEquivalentUsd: round(this.totalClaudeEquivalent, 6),\n savingsVsClaudePct: round(this.savingsVsClaude * 100, 2),\n cacheHitRatio: round(this.aggregateCacheHitRatio, 4),\n };\n }\n}\n\nfunction round(n: number, digits: number): number {\n const f = 10 ** digits;\n return Math.round(n * f) / f;\n}\n","import type { JSONSchema, ToolSpec } from \"./types.js\";\n\nexport interface ToolDefinition<A = any, R = any> {\n name: string;\n description?: string;\n parameters?: JSONSchema;\n fn: (args: A) => R | Promise<R>;\n}\n\nexport class ToolRegistry {\n private readonly _tools = new Map<string, ToolDefinition>();\n\n register<A, R>(def: ToolDefinition<A, R>): this {\n if (!def.name) throw new Error(\"tool requires a name\");\n this._tools.set(def.name, def as ToolDefinition);\n return this;\n }\n\n has(name: string): boolean {\n return this._tools.has(name);\n }\n\n get(name: string): ToolDefinition | undefined {\n return this._tools.get(name);\n }\n\n get size(): number {\n return this._tools.size;\n }\n\n specs(): ToolSpec[] {\n return [...this._tools.values()].map((t) => ({\n type: \"function\",\n function: {\n name: t.name,\n description: t.description ?? \"\",\n parameters: t.parameters ?? { type: \"object\", properties: {} },\n },\n }));\n }\n\n async dispatch(name: string, argumentsRaw: string | Record<string, unknown>): Promise<string> {\n const tool = this._tools.get(name);\n if (!tool) {\n return JSON.stringify({ error: `unknown tool: ${name}` });\n }\n let args: any;\n try {\n args =\n typeof argumentsRaw === \"string\"\n ? argumentsRaw.trim()\n ? JSON.parse(argumentsRaw)\n : {}\n : (argumentsRaw ?? {});\n } catch (err) {\n return JSON.stringify({\n error: `invalid tool arguments JSON: ${(err as Error).message}`,\n });\n }\n try {\n const result = await tool.fn(args);\n return typeof result === \"string\" ? result : JSON.stringify(result);\n } catch (err) {\n return JSON.stringify({\n error: `${(err as Error).name}: ${(err as Error).message}`,\n });\n }\n }\n}\n","import type { DeepSeekClient } from \"./client.js\";\nimport { type TypedPlanState, harvest } from \"./harvest.js\";\nimport { AppendOnlyLog, type ImmutablePrefix, VolatileScratch } from \"./memory.js\";\nimport { type RepairReport, ToolCallRepair } from \"./repair/index.js\";\nimport { SessionStats, type TurnStats } from \"./telemetry.js\";\nimport { ToolRegistry } from \"./tools.js\";\nimport type { ChatMessage, ToolCall } from \"./types.js\";\n\nexport type EventRole = \"assistant_delta\" | \"assistant_final\" | \"tool\" | \"done\" | \"error\";\n\nexport interface LoopEvent {\n turn: number;\n role: EventRole;\n content: string;\n reasoningDelta?: string;\n toolName?: string;\n stats?: TurnStats;\n planState?: TypedPlanState;\n repair?: RepairReport;\n error?: string;\n}\n\nexport interface CacheFirstLoopOptions {\n client: DeepSeekClient;\n prefix: ImmutablePrefix;\n tools?: ToolRegistry;\n model?: string;\n maxToolIters?: number;\n stream?: boolean;\n}\n\n/**\n * Pillar 1 — Cache-First Loop.\n *\n * - prefix is immutable (cache target)\n * - log is append-only (preserves prior-turn prefix)\n * - scratch is per-turn volatile (never sent upstream)\n *\n * Yields a stream of events so a TUI can render progressively.\n */\nexport class CacheFirstLoop {\n readonly client: DeepSeekClient;\n readonly prefix: ImmutablePrefix;\n readonly tools: ToolRegistry;\n readonly model: string;\n readonly maxToolIters: number;\n readonly stream: boolean;\n readonly log = new AppendOnlyLog();\n readonly scratch = new VolatileScratch();\n readonly stats = new SessionStats();\n readonly repair: ToolCallRepair;\n private _turn = 0;\n\n constructor(opts: CacheFirstLoopOptions) {\n this.client = opts.client;\n this.prefix = opts.prefix;\n this.tools = opts.tools ?? new ToolRegistry();\n this.model = opts.model ?? \"deepseek-chat\";\n this.maxToolIters = opts.maxToolIters ?? 8;\n this.stream = opts.stream ?? true;\n const allowedNames = new Set([...this.prefix.toolSpecs.map((s) => s.function.name)]);\n this.repair = new ToolCallRepair({ allowedToolNames: allowedNames });\n }\n\n private buildMessages(pendingUser: string | null): ChatMessage[] {\n const msgs: ChatMessage[] = [...this.prefix.toMessages(), ...this.log.toMessages()];\n if (pendingUser !== null) msgs.push({ role: \"user\", content: pendingUser });\n return msgs;\n }\n\n async *step(userInput: string): AsyncGenerator<LoopEvent> {\n this._turn++;\n this.scratch.reset();\n let pendingUser: string | null = userInput;\n const toolSpecs = this.prefix.tools();\n\n for (let iter = 0; iter < this.maxToolIters; iter++) {\n const messages = this.buildMessages(pendingUser);\n\n let assistantContent = \"\";\n let reasoningContent = \"\";\n let toolCalls: ToolCall[] = [];\n let usage: TurnStats[\"usage\"] | null = null;\n\n try {\n if (this.stream) {\n const callBuf: Map<number, ToolCall> = new Map();\n for await (const chunk of this.client.stream({\n model: this.model,\n messages,\n tools: toolSpecs.length ? toolSpecs : undefined,\n })) {\n if (chunk.contentDelta) {\n assistantContent += chunk.contentDelta;\n yield {\n turn: this._turn,\n role: \"assistant_delta\",\n content: chunk.contentDelta,\n };\n }\n if (chunk.reasoningDelta) {\n reasoningContent += chunk.reasoningDelta;\n yield {\n turn: this._turn,\n role: \"assistant_delta\",\n content: \"\",\n reasoningDelta: chunk.reasoningDelta,\n };\n }\n if (chunk.toolCallDelta) {\n const d = chunk.toolCallDelta;\n const cur = callBuf.get(d.index) ?? {\n id: d.id,\n type: \"function\" as const,\n function: { name: \"\", arguments: \"\" },\n };\n if (d.id) cur.id = d.id;\n if (d.name) cur.function.name = (cur.function.name ?? \"\") + d.name;\n if (d.argumentsDelta)\n cur.function.arguments = (cur.function.arguments ?? \"\") + d.argumentsDelta;\n callBuf.set(d.index, cur);\n }\n if (chunk.usage) usage = chunk.usage;\n }\n toolCalls = [...callBuf.values()];\n } else {\n const resp = await this.client.chat({\n model: this.model,\n messages,\n tools: toolSpecs.length ? toolSpecs : undefined,\n });\n assistantContent = resp.content;\n reasoningContent = resp.reasoningContent ?? \"\";\n toolCalls = resp.toolCalls;\n usage = resp.usage;\n }\n } catch (err) {\n yield {\n turn: this._turn,\n role: \"error\",\n content: \"\",\n error: (err as Error).message,\n };\n return;\n }\n\n const turnStats = this.stats.record(\n this._turn,\n this.model,\n usage ?? new (await import(\"./client.js\")).Usage(),\n );\n\n // Commit the user turn to the log only on success of the first round-trip.\n if (pendingUser !== null) {\n this.log.append({ role: \"user\", content: pendingUser });\n pendingUser = null;\n }\n\n this.scratch.reasoning = reasoningContent || null;\n const planState = await harvest(reasoningContent || null);\n\n const { calls: repairedCalls, report } = this.repair.process(\n toolCalls,\n reasoningContent || null,\n );\n\n this.log.append(this.assistantMessage(assistantContent, repairedCalls));\n\n yield {\n turn: this._turn,\n role: \"assistant_final\",\n content: assistantContent,\n stats: turnStats,\n planState,\n repair: report,\n };\n\n if (repairedCalls.length === 0) {\n yield { turn: this._turn, role: \"done\", content: assistantContent };\n return;\n }\n\n for (const call of repairedCalls) {\n const name = call.function?.name ?? \"\";\n const args = call.function?.arguments ?? \"{}\";\n const result = await this.tools.dispatch(name, args);\n this.log.append({\n role: \"tool\",\n tool_call_id: call.id ?? \"\",\n name,\n content: result,\n });\n yield { turn: this._turn, role: \"tool\", content: result, toolName: name };\n }\n }\n\n yield { turn: this._turn, role: \"done\", content: \"[max_tool_iters reached]\" };\n }\n\n async run(userInput: string, onEvent?: (ev: LoopEvent) => void): Promise<string> {\n let final = \"\";\n for await (const ev of this.step(userInput)) {\n onEvent?.(ev);\n if (ev.role === \"assistant_final\") final = ev.content;\n if (ev.role === \"done\") break;\n }\n return final;\n }\n\n private assistantMessage(content: string, toolCalls: ToolCall[]): ChatMessage {\n const msg: ChatMessage = { role: \"assistant\", content };\n if (toolCalls.length > 0) msg.tool_calls = toolCalls;\n return msg;\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\n/**\n * Minimal `.env` loader; no dependency on dotenv.\n *\n * Reads KEY=VALUE lines and populates `process.env` for keys not already set.\n * Silently no-ops if the file is missing. Safe to call from library entry\n * points, CLI commands, examples, and benchmark runners.\n */\nexport function loadDotenv(path = \".env\"): void {\n let raw: string;\n try {\n raw = readFileSync(resolve(process.cwd(), path), \"utf8\");\n } catch {\n return;\n }\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq === -1) continue;\n const key = trimmed.slice(0, eq).trim();\n let value = trimmed.slice(eq + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (process.env[key] === undefined) process.env[key] = value;\n }\n}\n","/** Reasonix — DeepSeek-native agent framework. Library entry point. */\n\nexport { DeepSeekClient, Usage } from \"./client.js\";\nexport type { ChatResponse, StreamChunk, DeepSeekClientOptions } from \"./client.js\";\n\nexport { CacheFirstLoop } from \"./loop.js\";\nexport type { CacheFirstLoopOptions, LoopEvent, EventRole } from \"./loop.js\";\n\nexport { ImmutablePrefix, AppendOnlyLog, VolatileScratch } from \"./memory.js\";\nexport type { ImmutablePrefixOptions } from \"./memory.js\";\n\nexport { ToolRegistry } from \"./tools.js\";\nexport type { ToolDefinition } from \"./tools.js\";\n\nexport { SessionStats, costUsd, claudeEquivalentCost } from \"./telemetry.js\";\nexport type { TurnStats, SessionSummary } from \"./telemetry.js\";\n\nexport {\n ToolCallRepair,\n scavengeToolCalls,\n repairTruncatedJson,\n StormBreaker,\n analyzeSchema,\n flattenSchema,\n nestArguments,\n} from \"./repair/index.js\";\nexport type {\n RepairReport,\n ToolCallRepairOptions,\n ScavengeOptions,\n ScavengeResult,\n TruncationRepairResult,\n FlattenDecision,\n} from \"./repair/index.js\";\n\nexport { harvest, emptyPlanState, isPlanStateEmpty } from \"./harvest.js\";\nexport type { TypedPlanState } from \"./harvest.js\";\n\nexport { loadDotenv } from \"./env.js\";\n\nexport { fetchWithRetry } from \"./retry.js\";\nexport type { RetryOptions, RetryInfo } from \"./retry.js\";\n\nexport type {\n ChatMessage,\n ToolCall,\n ToolSpec,\n ToolFunctionSpec,\n Role,\n JSONSchema,\n} from \"./types.js\";\n\nexport const VERSION = \"0.0.1\";\n","import { render } from \"ink\";\nimport React from \"react\";\nimport { loadDotenv } from \"../../env.js\";\nimport { App } from \"../ui/App.js\";\n\nexport interface ChatOptions {\n model: string;\n system: string;\n transcript?: string;\n}\n\nexport async function chatCommand(opts: ChatOptions): Promise<void> {\n loadDotenv();\n if (!process.env.DEEPSEEK_API_KEY) {\n console.error(\"DEEPSEEK_API_KEY is not set. Copy .env.example to .env and fill it in.\");\n process.exit(1);\n }\n const { waitUntilExit } = render(\n <App model={opts.model} system={opts.system} transcript={opts.transcript} />,\n { exitOnCtrlC: true },\n );\n await waitUntilExit();\n}\n","import { type WriteStream, createWriteStream } from \"node:fs\";\nimport { Box, Static, useApp } from \"ink\";\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { CacheFirstLoop, DeepSeekClient, ImmutablePrefix } from \"../../index.js\";\nimport type { LoopEvent } from \"../../loop.js\";\nimport type { SessionSummary } from \"../../telemetry.js\";\nimport { type DisplayEvent, EventRow } from \"./EventLog.js\";\nimport { PromptInput } from \"./PromptInput.js\";\nimport { StatsPanel } from \"./StatsPanel.js\";\n\nexport interface AppProps {\n model: string;\n system: string;\n transcript?: string;\n}\n\n/**\n * Throttle interval in ms. We flush streaming deltas at most this often to\n * avoid re-rendering the whole UI on every single token from DeepSeek.\n * 60ms ≈ 16Hz, fast enough to feel live, slow enough to not thrash Ink.\n */\nconst FLUSH_INTERVAL_MS = 60;\n\ninterface StreamingState {\n id: string;\n text: string;\n reasoning: string;\n}\n\nexport function App({ model, system, transcript }: AppProps) {\n const { exit } = useApp();\n const [historical, setHistorical] = useState<DisplayEvent[]>([]);\n const [streaming, setStreaming] = useState<DisplayEvent | null>(null);\n const [input, setInput] = useState(\"\");\n const [busy, setBusy] = useState(false);\n const [summary, setSummary] = useState<SessionSummary>({\n turns: 0,\n totalCostUsd: 0,\n claudeEquivalentUsd: 0,\n savingsVsClaudePct: 0,\n cacheHitRatio: 0,\n });\n\n const transcriptRef = useRef<WriteStream | null>(null);\n if (transcript && !transcriptRef.current) {\n transcriptRef.current = createWriteStream(transcript, { flags: \"a\" });\n }\n useEffect(() => {\n return () => {\n transcriptRef.current?.end();\n };\n }, []);\n\n const loopRef = useRef<CacheFirstLoop | null>(null);\n const loop = useMemo(() => {\n if (loopRef.current) return loopRef.current;\n const client = new DeepSeekClient();\n const prefix = new ImmutablePrefix({ system });\n const l = new CacheFirstLoop({ client, prefix, model });\n loopRef.current = l;\n return l;\n }, [model, system]);\n\n const prefixHash = loop.prefix.fingerprint;\n\n const writeTranscript = useCallback((ev: LoopEvent) => {\n transcriptRef.current?.write(\n `${JSON.stringify({\n ts: new Date().toISOString(),\n turn: ev.turn,\n role: ev.role,\n content: ev.content,\n tool: ev.toolName,\n })}\\n`,\n );\n }, []);\n\n const handleSubmit = useCallback(\n async (raw: string) => {\n const text = raw.trim();\n if (!text || busy) return;\n setInput(\"\");\n if (text === \"/exit\" || text === \"/quit\") {\n transcriptRef.current?.end();\n exit();\n return;\n }\n if (text === \"/clear\") {\n setHistorical([]);\n return;\n }\n\n // User message is immutable — push to Static immediately.\n setHistorical((prev) => [...prev, { id: `u-${Date.now()}`, role: \"user\", text }]);\n\n const assistantId = `a-${Date.now()}`;\n // Refs are the source of truth for accumulated streaming text; the React\n // state copy below is only for rendering and gets updated on flush.\n const streamRef: StreamingState = { id: assistantId, text: \"\", reasoning: \"\" };\n const contentBuf = { current: \"\" };\n const reasoningBuf = { current: \"\" };\n\n setStreaming({ id: assistantId, role: \"assistant\", text: \"\", streaming: true });\n setBusy(true);\n\n const flush = () => {\n if (!contentBuf.current && !reasoningBuf.current) return;\n streamRef.text += contentBuf.current;\n streamRef.reasoning += reasoningBuf.current;\n contentBuf.current = \"\";\n reasoningBuf.current = \"\";\n setStreaming({\n id: assistantId,\n role: \"assistant\",\n text: streamRef.text,\n reasoning: streamRef.reasoning || undefined,\n streaming: true,\n });\n };\n const timer = setInterval(flush, FLUSH_INTERVAL_MS);\n\n try {\n for await (const ev of loop.step(text)) {\n writeTranscript(ev);\n if (ev.role === \"assistant_delta\") {\n if (ev.content) contentBuf.current += ev.content;\n if (ev.reasoningDelta) reasoningBuf.current += ev.reasoningDelta;\n } else if (ev.role === \"assistant_final\") {\n flush();\n const repairNote = ev.repair ? describeRepair(ev.repair) : \"\";\n setStreaming(null);\n setHistorical((prev) => [\n ...prev,\n {\n id: assistantId,\n role: \"assistant\",\n text: ev.content || streamRef.text,\n reasoning: streamRef.reasoning || undefined,\n stats: ev.stats,\n repair: repairNote || undefined,\n streaming: false,\n },\n ]);\n } else if (ev.role === \"tool\") {\n flush();\n setHistorical((prev) => [\n ...prev,\n {\n id: `t-${Date.now()}-${Math.random()}`,\n role: \"tool\",\n text: ev.content,\n toolName: ev.toolName,\n },\n ]);\n } else if (ev.role === \"error\") {\n setHistorical((prev) => [\n ...prev,\n { id: `e-${Date.now()}`, role: \"error\", text: ev.error ?? ev.content },\n ]);\n }\n }\n flush();\n } finally {\n clearInterval(timer);\n setStreaming(null);\n setSummary(loop.stats.summary());\n setBusy(false);\n }\n },\n [busy, exit, loop, writeTranscript],\n );\n\n return (\n <Box flexDirection=\"column\">\n <StatsPanel summary={summary} model={model} prefixHash={prefixHash} />\n <Static items={historical}>{(item) => <EventRow key={item.id} event={item} />}</Static>\n {streaming ? (\n <Box marginY={1}>\n <EventRow event={streaming} />\n </Box>\n ) : null}\n <PromptInput value={input} onChange={setInput} onSubmit={handleSubmit} disabled={busy} />\n </Box>\n );\n}\n\nfunction describeRepair(repair: {\n scavenged: number;\n truncationsFixed: number;\n stormsBroken: number;\n}): string {\n const parts: string[] = [];\n if (repair.scavenged) parts.push(`scavenged ${repair.scavenged}`);\n if (repair.truncationsFixed) parts.push(`repaired ${repair.truncationsFixed} truncation`);\n if (repair.stormsBroken) parts.push(`broke ${repair.stormsBroken} storm`);\n return parts.length ? `[repair] ${parts.join(\", \")}` : \"\";\n}\n","import { Box, Text } from \"ink\";\nimport React from \"react\";\nimport type { TurnStats } from \"../../telemetry.js\";\nimport { Markdown } from \"./markdown.js\";\n\nexport type DisplayRole = \"user\" | \"assistant\" | \"tool\" | \"system\" | \"error\" | \"info\";\n\nexport interface DisplayEvent {\n id: string;\n role: DisplayRole;\n text: string;\n reasoning?: string;\n toolName?: string;\n stats?: TurnStats;\n repair?: string;\n streaming?: boolean;\n}\n\nexport const EventRow = React.memo(function EventRow({ event }: { event: DisplayEvent }) {\n if (event.role === \"user\") {\n return (\n <Box>\n <Text bold color=\"cyan\">\n you ›{\" \"}\n </Text>\n <Text>{event.text}</Text>\n </Box>\n );\n }\n if (event.role === \"assistant\") {\n if (event.streaming) return <StreamingAssistant event={event} />;\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Text bold color=\"green\">\n assistant\n </Text>\n </Box>\n {event.reasoning ? <ReasoningBlock reasoning={event.reasoning} /> : null}\n {event.text ? <Markdown text={event.text} /> : <Text dimColor>(no content)</Text>}\n {event.stats ? <StatsLine stats={event.stats} /> : null}\n {event.repair ? <Text color=\"magenta\">{event.repair}</Text> : null}\n </Box>\n );\n }\n if (event.role === \"tool\") {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"yellow\">{`tool<${event.toolName ?? \"?\"}> →`}</Text>\n <Text dimColor> {truncate(event.text, 400)}</Text>\n </Box>\n );\n }\n if (event.role === \"error\") {\n return (\n <Box marginTop={1}>\n <Text color=\"red\" bold>\n error{\" \"}\n </Text>\n <Text color=\"red\">{event.text}</Text>\n </Box>\n );\n }\n if (event.role === \"info\") {\n return (\n <Box>\n <Text dimColor>{event.text}</Text>\n </Box>\n );\n }\n return (\n <Box>\n <Text>{event.text}</Text>\n </Box>\n );\n});\n\nfunction ReasoningBlock({ reasoning }: { reasoning: string }) {\n const max = 220;\n const flat = reasoning.replace(/\\s+/g, \" \").trim();\n const preview =\n flat.length <= max ? flat : `${flat.slice(0, max)}… (+${flat.length - max} chars)`;\n return (\n <Box marginBottom={1}>\n <Text dimColor italic>\n {\"↳ thinking: \"}\n {preview}\n </Text>\n </Box>\n );\n}\n\n/**\n * Compact progress view rendered while a turn is still streaming. We keep\n * this to a fixed ~3-line footprint so the dynamic region never scrolls past\n * the terminal viewport and leaves artifacts in scrollback.\n */\nfunction StreamingAssistant({ event }: { event: DisplayEvent }) {\n const tail = lastLine(event.text, 140);\n const reasoningTail = event.reasoning ? lastLine(event.reasoning, 120) : \"\";\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Text bold color=\"green\">\n assistant{\" \"}\n </Text>\n <Text dimColor>\n (streaming · {event.text.length}\n {event.reasoning ? ` + think ${event.reasoning.length}` : \"\"} chars)\n </Text>\n </Box>\n {reasoningTail ? (\n <Text dimColor italic>\n ↳ thinking: {reasoningTail}\n </Text>\n ) : null}\n {tail ? (\n <Text dimColor>▸ {tail}</Text>\n ) : (\n <Text dimColor italic>\n {\" (waiting for first token…)\"}\n </Text>\n )}\n </Box>\n );\n}\n\nfunction lastLine(s: string, maxChars: number): string {\n const flat = s.replace(/\\s+/g, \" \").trim();\n if (!flat) return \"\";\n return flat.length <= maxChars ? flat : `…${flat.slice(-maxChars)}`;\n}\n\nfunction StatsLine({ stats }: { stats: TurnStats }) {\n const hit = (stats.cacheHitRatio * 100).toFixed(1);\n return (\n <Text dimColor>\n {\" ↳ cache \"}\n {hit}\n {\"% · tokens \"}\n {stats.usage.promptTokens}\n {\"→\"}\n {stats.usage.completionTokens}\n {\" · $\"}\n {stats.cost.toFixed(6)}\n </Text>\n );\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max)}… (+${s.length - max} chars)`;\n}\n","/**\n * Minimal Markdown → Ink renderer for chat output.\n *\n * Handles the subset that actually shows up in LLM answers:\n * - ATX headers (# ##)\n * - Unordered / ordered lists\n * - Fenced code blocks (```lang)\n * - Inline **bold**, *italic*, `code`\n * - Paragraphs separated by blank lines\n * - LaTeX delimiters are stripped (\\( \\), \\[ \\], \\boxed{X})\n *\n * The goal is not TeX-perfect math — it's \"stop showing raw backslashes to\n * the user.\" When the model insists on LaTeX, we strip the scaffolding and\n * show the expression verbatim; terminals don't do math fonts anyway.\n */\n\nimport { Box, Text } from \"ink\";\nimport React from \"react\";\n\nfunction stripMath(s: string): string {\n return s\n .replace(/\\\\\\(\\s*/g, \"\")\n .replace(/\\s*\\\\\\)/g, \"\")\n .replace(/\\\\\\[\\s*/g, \"\\n\")\n .replace(/\\s*\\\\\\]/g, \"\\n\")\n .replace(/\\\\boxed\\{([^}]+)\\}/g, \"【$1】\")\n .replace(/\\\\sqrt\\{([^}]+)\\}/g, \"√($1)\")\n .replace(/\\\\frac\\{([^}]+)\\}\\{([^}]+)\\}/g, \"($1)/($2)\")\n .replace(/\\\\text\\{([^}]+)\\}/g, \"$1\")\n .replace(/\\\\cdot/g, \"·\")\n .replace(/\\\\times/g, \"×\")\n .replace(/\\\\div/g, \"÷\")\n .replace(/\\\\pm/g, \"±\")\n .replace(/\\\\mp/g, \"∓\")\n .replace(/\\\\leq/g, \"≤\")\n .replace(/\\\\geq/g, \"≥\")\n .replace(/\\\\neq/g, \"≠\")\n .replace(/\\\\approx/g, \"≈\")\n .replace(/\\\\in\\b/g, \"∈\")\n .replace(/\\\\notin\\b/g, \"∉\")\n .replace(/\\\\infty/g, \"∞\")\n .replace(/\\\\sum\\b/g, \"Σ\")\n .replace(/\\\\prod\\b/g, \"Π\")\n .replace(/\\\\int\\b/g, \"∫\")\n .replace(/\\\\alpha/g, \"α\")\n .replace(/\\\\beta/g, \"β\")\n .replace(/\\\\gamma/g, \"γ\")\n .replace(/\\\\delta/g, \"δ\")\n .replace(/\\\\theta/g, \"θ\")\n .replace(/\\\\lambda/g, \"λ\")\n .replace(/\\\\mu/g, \"μ\")\n .replace(/\\\\pi/g, \"π\")\n .replace(/\\\\sigma/g, \"σ\")\n .replace(/\\\\phi/g, \"φ\")\n .replace(/\\\\omega/g, \"ω\")\n .replace(/\\\\implies\\b/g, \"⇒\")\n .replace(/\\\\iff\\b/g, \"⇔\")\n .replace(/\\\\to\\b/g, \"→\")\n .replace(/\\\\rightarrow/g, \"→\")\n .replace(/\\\\Rightarrow/g, \"⇒\")\n .replace(/\\\\leftarrow/g, \"←\")\n .replace(/\\\\Leftarrow/g, \"⇐\")\n .replace(/\\\\ldots/g, \"…\")\n .replace(/\\\\cdots/g, \"⋯\")\n .replace(/\\\\quad/g, \" \")\n .replace(/\\\\qquad/g, \" \")\n .replace(/\\\\,/g, \" \")\n .replace(/\\\\;/g, \" \")\n .replace(/\\\\!/g, \"\")\n .replace(/\\\\\\\\/g, \"\\n\")\n .replace(/[ \\t]{2,}/g, \" \");\n}\n\n/** Split a single line into styled segments for bold / italic / inline code. */\nconst INLINE_RE = /(\\*\\*([^*\\n]+?)\\*\\*|`([^`\\n]+?)`|(?<![*\\w])\\*([^*\\n]+?)\\*(?!\\w))/g;\n\nfunction InlineMd({ text }: { text: string }) {\n const parts: React.ReactNode[] = [];\n let last = 0;\n let idx = 0;\n for (const m of text.matchAll(INLINE_RE)) {\n const start = m.index ?? 0;\n if (start > last) {\n parts.push(<Text key={`t${idx++}`}>{text.slice(last, start)}</Text>);\n }\n if (m[2] !== undefined) {\n parts.push(\n <Text key={`b${idx++}`} bold>\n {m[2]}\n </Text>,\n );\n } else if (m[3] !== undefined) {\n parts.push(\n <Text key={`c${idx++}`} color=\"yellow\">\n {m[3]}\n </Text>,\n );\n } else if (m[4] !== undefined) {\n parts.push(\n <Text key={`i${idx++}`} italic>\n {m[4]}\n </Text>,\n );\n }\n last = start + m[0].length;\n }\n if (last < text.length) {\n parts.push(<Text key={`t${idx++}`}>{text.slice(last)}</Text>);\n }\n return <Text>{parts}</Text>;\n}\n\ninterface ParagraphBlock {\n kind: \"paragraph\";\n text: string;\n}\ninterface HeadingBlock {\n kind: \"heading\";\n level: number;\n text: string;\n}\ninterface BulletBlock {\n kind: \"bullet\";\n items: string[];\n ordered: boolean;\n start: number;\n}\ninterface CodeBlock {\n kind: \"code\";\n lang: string;\n text: string;\n}\ninterface HrBlock {\n kind: \"hr\";\n}\n\ntype Block = ParagraphBlock | HeadingBlock | BulletBlock | CodeBlock | HrBlock;\n\nfunction parseBlocks(raw: string): Block[] {\n const lines = raw.split(/\\r?\\n/);\n const out: Block[] = [];\n let para: string[] = [];\n let inCode = false;\n let codeLang = \"\";\n let codeBuf: string[] = [];\n let listBuf: BulletBlock | null = null;\n\n const flushPara = () => {\n if (para.length) {\n out.push({ kind: \"paragraph\", text: para.join(\" \") });\n para = [];\n }\n };\n const flushList = () => {\n if (listBuf) {\n out.push(listBuf);\n listBuf = null;\n }\n };\n\n for (const rawLine of lines) {\n const line = rawLine.replace(/\\s+$/g, \"\");\n\n const fence = line.match(/^```(\\w*)/);\n if (fence) {\n if (inCode) {\n out.push({ kind: \"code\", lang: codeLang, text: codeBuf.join(\"\\n\") });\n codeBuf = [];\n codeLang = \"\";\n inCode = false;\n } else {\n flushPara();\n flushList();\n inCode = true;\n codeLang = fence[1] ?? \"\";\n }\n continue;\n }\n if (inCode) {\n codeBuf.push(rawLine);\n continue;\n }\n\n if (line.trim() === \"\") {\n flushPara();\n flushList();\n continue;\n }\n\n if (/^[-*_]{3,}\\s*$/.test(line)) {\n flushPara();\n flushList();\n out.push({ kind: \"hr\" });\n continue;\n }\n\n const hm = line.match(/^(#{1,6})\\s+(.+)$/);\n if (hm) {\n flushPara();\n flushList();\n out.push({ kind: \"heading\", level: hm[1]!.length, text: hm[2]!.trim() });\n continue;\n }\n\n const bm = line.match(/^\\s*[-*+]\\s+(.+)$/);\n if (bm) {\n flushPara();\n if (!listBuf || listBuf.ordered) {\n flushList();\n listBuf = { kind: \"bullet\", items: [], ordered: false, start: 1 };\n }\n listBuf.items.push(bm[1]!);\n continue;\n }\n\n const om = line.match(/^\\s*(\\d+)\\.\\s+(.+)$/);\n if (om) {\n flushPara();\n if (!listBuf || !listBuf.ordered) {\n flushList();\n listBuf = { kind: \"bullet\", items: [], ordered: true, start: Number(om[1]) };\n }\n listBuf.items.push(om[2]!);\n continue;\n }\n\n flushList();\n para.push(line);\n }\n\n if (inCode && codeBuf.length) {\n out.push({ kind: \"code\", lang: codeLang, text: codeBuf.join(\"\\n\") });\n }\n flushPara();\n flushList();\n return out;\n}\n\nfunction BlockView({ block }: { block: Block }) {\n switch (block.kind) {\n case \"heading\":\n return (\n <Text bold color=\"cyan\">\n <InlineMd text={block.text} />\n </Text>\n );\n case \"paragraph\":\n return <InlineMd text={block.text} />;\n case \"bullet\":\n return (\n <Box flexDirection=\"column\">\n {block.items.map((item, i) => (\n <Box key={`${i}-${item.slice(0, 24)}`}>\n <Text color=\"cyan\">{block.ordered ? ` ${block.start + i}. ` : \" • \"}</Text>\n <InlineMd text={item} />\n </Box>\n ))}\n </Box>\n );\n case \"code\":\n return (\n <Box borderStyle=\"single\" borderColor=\"gray\" paddingX={1}>\n <Text color=\"yellow\">{block.text}</Text>\n </Box>\n );\n case \"hr\":\n return <Text dimColor>{\"────────────────────────\"}</Text>;\n }\n}\n\nexport function Markdown({ text }: { text: string }) {\n const cleaned = stripMath(text);\n const blocks = React.useMemo(() => parseBlocks(cleaned), [cleaned]);\n return (\n <Box flexDirection=\"column\" gap={1}>\n {blocks.map((b, i) => (\n <BlockView key={`${i}-${b.kind}`} block={b} />\n ))}\n </Box>\n );\n}\n","import { Box, Text } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport React from \"react\";\n\nexport interface PromptInputProps {\n value: string;\n onChange: (v: string) => void;\n onSubmit: (v: string) => void;\n disabled?: boolean;\n placeholder?: string;\n}\n\nexport function PromptInput({\n value,\n onChange,\n onSubmit,\n disabled,\n placeholder,\n}: PromptInputProps) {\n return (\n <Box borderStyle=\"round\" borderColor={disabled ? \"gray\" : \"cyan\"} paddingX={1}>\n <Text bold color={disabled ? \"gray\" : \"cyan\"}>\n you ›{\" \"}\n </Text>\n {disabled ? (\n <Text dimColor>{placeholder ?? \"…waiting for response…\"}</Text>\n ) : (\n <TextInput\n value={value}\n onChange={onChange}\n onSubmit={onSubmit}\n placeholder={placeholder ?? 'type a message, or \"/exit\"'}\n />\n )}\n </Box>\n );\n}\n","import { Box, Text } from \"ink\";\nimport React from \"react\";\nimport type { SessionSummary } from \"../../telemetry.js\";\n\nexport interface StatsPanelProps {\n summary: SessionSummary;\n model: string;\n prefixHash: string;\n}\n\nexport function StatsPanel({ summary, model, prefixHash }: StatsPanelProps) {\n const hitPct = (summary.cacheHitRatio * 100).toFixed(1);\n const hitColor =\n summary.cacheHitRatio >= 0.7 ? \"green\" : summary.cacheHitRatio >= 0.4 ? \"yellow\" : \"red\";\n return (\n <Box borderStyle=\"round\" borderColor=\"cyan\" flexDirection=\"column\" paddingX={1}>\n <Box justifyContent=\"space-between\">\n <Text>\n <Text color=\"cyan\" bold>\n Reasonix\n </Text>\n <Text dimColor> · model </Text>\n <Text color=\"yellow\">{model}</Text>\n <Text dimColor> · prefix </Text>\n <Text dimColor>{prefixHash}</Text>\n </Text>\n <Text dimColor>turns {summary.turns}</Text>\n </Box>\n <Box marginTop={1} gap={3}>\n <Text>\n <Text dimColor>cache hit </Text>\n <Text color={hitColor} bold>\n {hitPct}%\n </Text>\n </Text>\n <Text>\n <Text dimColor>cost </Text>\n <Text color=\"green\">${summary.totalCostUsd.toFixed(6)}</Text>\n </Text>\n <Text>\n <Text dimColor>vs Claude </Text>\n <Text>${summary.claudeEquivalentUsd.toFixed(6)}</Text>\n </Text>\n <Text>\n <Text dimColor>saving </Text>\n <Text color=\"green\" bold>\n {summary.savingsVsClaudePct.toFixed(1)}%\n </Text>\n </Text>\n </Box>\n </Box>\n );\n}\n","import { loadDotenv } from \"../../env.js\";\nimport { CacheFirstLoop, DeepSeekClient, ImmutablePrefix } from \"../../index.js\";\n\nexport interface RunOptions {\n task: string;\n model: string;\n system: string;\n}\n\nexport async function runCommand(opts: RunOptions): Promise<void> {\n loadDotenv();\n const client = new DeepSeekClient();\n const prefix = new ImmutablePrefix({ system: opts.system });\n const loop = new CacheFirstLoop({ client, prefix, model: opts.model });\n\n for await (const ev of loop.step(opts.task)) {\n if (ev.role === \"assistant_delta\" && ev.content) process.stdout.write(ev.content);\n if (ev.role === \"tool\") process.stdout.write(`\\n[tool ${ev.toolName}] ${ev.content}\\n`);\n if (ev.role === \"error\") process.stderr.write(`\\n[error] ${ev.error}\\n`);\n if (ev.role === \"done\") process.stdout.write(\"\\n\");\n }\n const s = loop.stats.summary();\n process.stdout.write(\n `\\n— turns:${s.turns} cache:${(s.cacheHitRatio * 100).toFixed(1)}% ` +\n `cost:$${s.totalCostUsd.toFixed(6)} save-vs-claude:${s.savingsVsClaudePct.toFixed(1)}%\\n`,\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\n\nexport interface StatsOptions {\n transcript: string;\n}\n\nexport function statsCommand(opts: StatsOptions): void {\n if (!existsSync(opts.transcript)) {\n console.error(`no such transcript: ${opts.transcript}`);\n process.exit(1);\n }\n const lines = readFileSync(opts.transcript, \"utf8\").split(/\\r?\\n/).filter(Boolean);\n let assistantTurns = 0;\n let toolCalls = 0;\n let lastTurn = 0;\n for (const line of lines) {\n try {\n const rec = JSON.parse(line);\n if (rec.role === \"assistant_final\") assistantTurns++;\n if (rec.role === \"tool\") toolCalls++;\n if (typeof rec.turn === \"number\") lastTurn = Math.max(lastTurn, rec.turn);\n } catch {\n /* skip */\n }\n }\n console.log(`transcript: ${opts.transcript}`);\n console.log(`assistant turns: ${assistantTurns}`);\n console.log(`tool invocations: ${toolCalls}`);\n console.log(`last turn index: ${lastTurn}`);\n}\n","import { VERSION } from \"../../index.js\";\n\nexport function versionCommand(): void {\n console.log(`reasonix ${VERSION}`);\n}\n"],"mappings":"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","names":["signature","React","Box","React","Box","Text","React","React","EventRow","Box","Text","Box","Text","React","Box","Text","React","React","Box","React","readFileSync"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry layer for DeepSeek API calls.
|
|
3
|
+
*
|
|
4
|
+
* Wraps a `fetch` function so that transient failures (rate limiting, server
|
|
5
|
+
* overload, network blips) don't kill an agent session. We explicitly DO NOT
|
|
6
|
+
* retry:
|
|
7
|
+
* - 4xx client errors other than 408 / 429 (bad key, bad request, ...)
|
|
8
|
+
* - aborted requests (user cancelled)
|
|
9
|
+
* - mid-stream body read errors (retrying costs money AND would desync)
|
|
10
|
+
*
|
|
11
|
+
* Retrying is controlled by attempt count + exponential backoff with jitter.
|
|
12
|
+
* If the server sends a `Retry-After` header we honor it (capped by
|
|
13
|
+
* `maxBackoffMs` so a misconfigured upstream can't park us forever).
|
|
14
|
+
*/
|
|
15
|
+
interface RetryOptions {
|
|
16
|
+
/** Maximum total attempts (including the first). Default 4. */
|
|
17
|
+
maxAttempts?: number;
|
|
18
|
+
/** Initial backoff in ms. Doubles each retry, with jitter. Default 500. */
|
|
19
|
+
initialBackoffMs?: number;
|
|
20
|
+
/** Upper bound on any single backoff delay. Default 10000 (10s). */
|
|
21
|
+
maxBackoffMs?: number;
|
|
22
|
+
/** HTTP statuses to treat as retryable. Default [408, 429, 500, 502, 503, 504]. */
|
|
23
|
+
retryableStatuses?: readonly number[];
|
|
24
|
+
/** Abort signal; we do NOT retry once aborted. */
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
/** Telemetry hook — called before each wait. */
|
|
27
|
+
onRetry?: (info: RetryInfo) => void;
|
|
28
|
+
}
|
|
29
|
+
interface RetryInfo {
|
|
30
|
+
attempt: number;
|
|
31
|
+
reason: string;
|
|
32
|
+
waitMs: number;
|
|
33
|
+
}
|
|
34
|
+
declare function fetchWithRetry(fetchFn: typeof fetch, url: string, init: RequestInit, opts?: RetryOptions): Promise<Response>;
|
|
35
|
+
|
|
36
|
+
interface JSONSchema {
|
|
37
|
+
type?: string;
|
|
38
|
+
properties?: Record<string, JSONSchema>;
|
|
39
|
+
items?: JSONSchema;
|
|
40
|
+
required?: string[];
|
|
41
|
+
description?: string;
|
|
42
|
+
enum?: unknown[];
|
|
43
|
+
[k: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
interface ToolFunctionSpec {
|
|
46
|
+
name: string;
|
|
47
|
+
description: string;
|
|
48
|
+
parameters: JSONSchema;
|
|
49
|
+
}
|
|
50
|
+
interface ToolSpec {
|
|
51
|
+
type: "function";
|
|
52
|
+
function: ToolFunctionSpec;
|
|
53
|
+
}
|
|
54
|
+
interface ToolCall {
|
|
55
|
+
id?: string;
|
|
56
|
+
type?: "function";
|
|
57
|
+
function: {
|
|
58
|
+
name: string;
|
|
59
|
+
arguments: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
type Role = "system" | "user" | "assistant" | "tool";
|
|
63
|
+
interface ChatMessage {
|
|
64
|
+
role: Role;
|
|
65
|
+
content?: string | null;
|
|
66
|
+
name?: string;
|
|
67
|
+
tool_call_id?: string;
|
|
68
|
+
tool_calls?: ToolCall[];
|
|
69
|
+
}
|
|
70
|
+
interface RawUsage {
|
|
71
|
+
prompt_tokens?: number;
|
|
72
|
+
completion_tokens?: number;
|
|
73
|
+
total_tokens?: number;
|
|
74
|
+
prompt_cache_hit_tokens?: number;
|
|
75
|
+
prompt_cache_miss_tokens?: number;
|
|
76
|
+
}
|
|
77
|
+
interface ChatRequestOptions {
|
|
78
|
+
model: string;
|
|
79
|
+
messages: ChatMessage[];
|
|
80
|
+
tools?: ToolSpec[];
|
|
81
|
+
temperature?: number;
|
|
82
|
+
maxTokens?: number;
|
|
83
|
+
stream?: boolean;
|
|
84
|
+
signal?: AbortSignal;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
declare class Usage {
|
|
88
|
+
promptTokens: number;
|
|
89
|
+
completionTokens: number;
|
|
90
|
+
totalTokens: number;
|
|
91
|
+
promptCacheHitTokens: number;
|
|
92
|
+
promptCacheMissTokens: number;
|
|
93
|
+
constructor(promptTokens?: number, completionTokens?: number, totalTokens?: number, promptCacheHitTokens?: number, promptCacheMissTokens?: number);
|
|
94
|
+
get cacheHitRatio(): number;
|
|
95
|
+
static fromApi(raw: RawUsage | undefined | null): Usage;
|
|
96
|
+
}
|
|
97
|
+
interface ChatResponse {
|
|
98
|
+
content: string;
|
|
99
|
+
reasoningContent: string | null;
|
|
100
|
+
toolCalls: ToolCall[];
|
|
101
|
+
usage: Usage;
|
|
102
|
+
raw: unknown;
|
|
103
|
+
}
|
|
104
|
+
interface StreamChunk {
|
|
105
|
+
contentDelta?: string;
|
|
106
|
+
reasoningDelta?: string;
|
|
107
|
+
toolCallDelta?: {
|
|
108
|
+
index: number;
|
|
109
|
+
id?: string;
|
|
110
|
+
name?: string;
|
|
111
|
+
argumentsDelta?: string;
|
|
112
|
+
};
|
|
113
|
+
usage?: Usage;
|
|
114
|
+
finishReason?: string;
|
|
115
|
+
raw: any;
|
|
116
|
+
}
|
|
117
|
+
interface DeepSeekClientOptions {
|
|
118
|
+
apiKey?: string;
|
|
119
|
+
baseUrl?: string;
|
|
120
|
+
timeoutMs?: number;
|
|
121
|
+
fetch?: typeof fetch;
|
|
122
|
+
/** Retry configuration. Pass `{ maxAttempts: 1 }` to disable retries. */
|
|
123
|
+
retry?: RetryOptions;
|
|
124
|
+
}
|
|
125
|
+
declare class DeepSeekClient {
|
|
126
|
+
readonly apiKey: string;
|
|
127
|
+
readonly baseUrl: string;
|
|
128
|
+
readonly timeoutMs: number;
|
|
129
|
+
readonly retry: RetryOptions;
|
|
130
|
+
private readonly _fetch;
|
|
131
|
+
constructor(opts?: DeepSeekClientOptions);
|
|
132
|
+
private buildPayload;
|
|
133
|
+
chat(opts: ChatRequestOptions): Promise<ChatResponse>;
|
|
134
|
+
stream(opts: ChatRequestOptions): AsyncGenerator<StreamChunk>;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Pillar 2 — R1 Thought Harvesting.
|
|
139
|
+
*
|
|
140
|
+
* v0.0.1 stub. Real implementation lands in v0.2 as a constrained V3 call
|
|
141
|
+
* against a strict JSON schema. The shape below is the public contract that
|
|
142
|
+
* downstream code may already depend on.
|
|
143
|
+
*/
|
|
144
|
+
interface TypedPlanState {
|
|
145
|
+
subgoals: string[];
|
|
146
|
+
hypotheses: string[];
|
|
147
|
+
uncertainties: string[];
|
|
148
|
+
rejectedPaths: string[];
|
|
149
|
+
}
|
|
150
|
+
declare function emptyPlanState(): TypedPlanState;
|
|
151
|
+
declare function isPlanStateEmpty(s: TypedPlanState): boolean;
|
|
152
|
+
/** v0.0.1 stub — returns empty state. */
|
|
153
|
+
declare function harvest(_reasoningContent: string | null): Promise<TypedPlanState>;
|
|
154
|
+
|
|
155
|
+
interface ImmutablePrefixOptions {
|
|
156
|
+
system: string;
|
|
157
|
+
toolSpecs?: readonly ToolSpec[];
|
|
158
|
+
fewShots?: readonly ChatMessage[];
|
|
159
|
+
}
|
|
160
|
+
declare class ImmutablePrefix {
|
|
161
|
+
readonly system: string;
|
|
162
|
+
readonly toolSpecs: readonly ToolSpec[];
|
|
163
|
+
readonly fewShots: readonly ChatMessage[];
|
|
164
|
+
constructor(opts: ImmutablePrefixOptions);
|
|
165
|
+
toMessages(): ChatMessage[];
|
|
166
|
+
tools(): ToolSpec[];
|
|
167
|
+
get fingerprint(): string;
|
|
168
|
+
}
|
|
169
|
+
declare class AppendOnlyLog {
|
|
170
|
+
private _entries;
|
|
171
|
+
append(message: ChatMessage): void;
|
|
172
|
+
extend(messages: ChatMessage[]): void;
|
|
173
|
+
get entries(): readonly ChatMessage[];
|
|
174
|
+
toMessages(): ChatMessage[];
|
|
175
|
+
get length(): number;
|
|
176
|
+
}
|
|
177
|
+
declare class VolatileScratch {
|
|
178
|
+
reasoning: string | null;
|
|
179
|
+
planState: Record<string, unknown> | null;
|
|
180
|
+
notes: string[];
|
|
181
|
+
reset(): void;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Schema flattening for DeepSeek tool calls.
|
|
186
|
+
*
|
|
187
|
+
* DeepSeek loses arguments on schemas that are deep (>2 levels of nesting) or
|
|
188
|
+
* wide (>10 leaf parameters). This module transforms such schemas into a
|
|
189
|
+
* dot-notation flat schema and re-nests the model's arguments before dispatch.
|
|
190
|
+
*
|
|
191
|
+
* Example:
|
|
192
|
+
* { user: { profile: { name, age } } } ⇄ "user.profile.name", "user.profile.age"
|
|
193
|
+
*/
|
|
194
|
+
|
|
195
|
+
interface FlattenDecision {
|
|
196
|
+
shouldFlatten: boolean;
|
|
197
|
+
leafCount: number;
|
|
198
|
+
maxDepth: number;
|
|
199
|
+
}
|
|
200
|
+
declare function analyzeSchema(schema: JSONSchema | undefined): FlattenDecision;
|
|
201
|
+
declare function flattenSchema(schema: JSONSchema): JSONSchema;
|
|
202
|
+
declare function nestArguments(flatArgs: Record<string, unknown>): Record<string, unknown>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Truncation recovery for tool-call argument JSON cut off mid-structure
|
|
206
|
+
* (typically when the model hits max_tokens before finishing the JSON object).
|
|
207
|
+
*
|
|
208
|
+
* Strategy is purely local: balance braces, close strings, fill missing values
|
|
209
|
+
* with `null`. We deliberately do NOT make a continuation API call here — that
|
|
210
|
+
* decision belongs to the loop, which knows about budgets.
|
|
211
|
+
*/
|
|
212
|
+
interface TruncationRepairResult {
|
|
213
|
+
repaired: string;
|
|
214
|
+
changed: boolean;
|
|
215
|
+
notes: string[];
|
|
216
|
+
}
|
|
217
|
+
declare function repairTruncatedJson(input: string): TruncationRepairResult;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Scavenge tool calls leaked into reasoning_content.
|
|
221
|
+
*
|
|
222
|
+
* R1 sometimes emits tool-call JSON inside <think>…</think> and then forgets
|
|
223
|
+
* to surface it in `tool_calls`. This pass extracts plausible calls and
|
|
224
|
+
* proposes them to the loop, which decides whether to merge them with the
|
|
225
|
+
* declared calls.
|
|
226
|
+
*/
|
|
227
|
+
|
|
228
|
+
interface ScavengeOptions {
|
|
229
|
+
/** Names of tools the model may legitimately call. Other names are ignored. */
|
|
230
|
+
allowedNames: ReadonlySet<string>;
|
|
231
|
+
/** Maximum number of calls to scavenge per pass (defence against runaway). */
|
|
232
|
+
maxCalls?: number;
|
|
233
|
+
}
|
|
234
|
+
interface ScavengeResult {
|
|
235
|
+
calls: ToolCall[];
|
|
236
|
+
notes: string[];
|
|
237
|
+
}
|
|
238
|
+
declare function scavengeToolCalls(reasoningContent: string | null | undefined, opts: ScavengeOptions): ScavengeResult;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Call-storm breaker.
|
|
242
|
+
*
|
|
243
|
+
* Detects (tool, args) tuples repeating within a sliding window and suppresses
|
|
244
|
+
* the offending call. Surfaces a synthetic tool_result advising the model to
|
|
245
|
+
* change strategy on its next turn.
|
|
246
|
+
*/
|
|
247
|
+
declare class StormBreaker {
|
|
248
|
+
private readonly windowSize;
|
|
249
|
+
private readonly threshold;
|
|
250
|
+
private readonly recent;
|
|
251
|
+
constructor(windowSize?: number, threshold?: number);
|
|
252
|
+
inspect(call: ToolCall): {
|
|
253
|
+
suppress: boolean;
|
|
254
|
+
reason?: string;
|
|
255
|
+
};
|
|
256
|
+
reset(): void;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Pillar 3 — Tool-Call Repair pipeline.
|
|
261
|
+
*
|
|
262
|
+
* Order of passes per turn:
|
|
263
|
+
* 1. scavenge — recover tool calls leaked into <think>
|
|
264
|
+
* 2. truncation — close any half-emitted argument JSON
|
|
265
|
+
* 3. storm breaker — drop call-storm repeats
|
|
266
|
+
*
|
|
267
|
+
* Schema flattening is applied during loop construction (it changes what we
|
|
268
|
+
* advertise to the model), not per-turn.
|
|
269
|
+
*/
|
|
270
|
+
|
|
271
|
+
interface RepairReport {
|
|
272
|
+
scavenged: number;
|
|
273
|
+
truncationsFixed: number;
|
|
274
|
+
stormsBroken: number;
|
|
275
|
+
notes: string[];
|
|
276
|
+
}
|
|
277
|
+
interface ToolCallRepairOptions {
|
|
278
|
+
allowedToolNames: ReadonlySet<string>;
|
|
279
|
+
stormWindow?: number;
|
|
280
|
+
stormThreshold?: number;
|
|
281
|
+
maxScavenge?: number;
|
|
282
|
+
}
|
|
283
|
+
declare class ToolCallRepair {
|
|
284
|
+
private readonly storm;
|
|
285
|
+
private readonly opts;
|
|
286
|
+
constructor(opts: ToolCallRepairOptions);
|
|
287
|
+
process(declaredCalls: ToolCall[], reasoningContent: string | null): {
|
|
288
|
+
calls: ToolCall[];
|
|
289
|
+
report: RepairReport;
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
declare function costUsd(model: string, usage: Usage): number;
|
|
294
|
+
declare function claudeEquivalentCost(usage: Usage): number;
|
|
295
|
+
interface TurnStats {
|
|
296
|
+
turn: number;
|
|
297
|
+
model: string;
|
|
298
|
+
usage: Usage;
|
|
299
|
+
cost: number;
|
|
300
|
+
cacheHitRatio: number;
|
|
301
|
+
}
|
|
302
|
+
interface SessionSummary {
|
|
303
|
+
turns: number;
|
|
304
|
+
totalCostUsd: number;
|
|
305
|
+
claudeEquivalentUsd: number;
|
|
306
|
+
savingsVsClaudePct: number;
|
|
307
|
+
cacheHitRatio: number;
|
|
308
|
+
}
|
|
309
|
+
declare class SessionStats {
|
|
310
|
+
readonly turns: TurnStats[];
|
|
311
|
+
record(turn: number, model: string, usage: Usage): TurnStats;
|
|
312
|
+
get totalCost(): number;
|
|
313
|
+
get totalClaudeEquivalent(): number;
|
|
314
|
+
get savingsVsClaude(): number;
|
|
315
|
+
get aggregateCacheHitRatio(): number;
|
|
316
|
+
summary(): SessionSummary;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
interface ToolDefinition<A = any, R = any> {
|
|
320
|
+
name: string;
|
|
321
|
+
description?: string;
|
|
322
|
+
parameters?: JSONSchema;
|
|
323
|
+
fn: (args: A) => R | Promise<R>;
|
|
324
|
+
}
|
|
325
|
+
declare class ToolRegistry {
|
|
326
|
+
private readonly _tools;
|
|
327
|
+
register<A, R>(def: ToolDefinition<A, R>): this;
|
|
328
|
+
has(name: string): boolean;
|
|
329
|
+
get(name: string): ToolDefinition | undefined;
|
|
330
|
+
get size(): number;
|
|
331
|
+
specs(): ToolSpec[];
|
|
332
|
+
dispatch(name: string, argumentsRaw: string | Record<string, unknown>): Promise<string>;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
type EventRole = "assistant_delta" | "assistant_final" | "tool" | "done" | "error";
|
|
336
|
+
interface LoopEvent {
|
|
337
|
+
turn: number;
|
|
338
|
+
role: EventRole;
|
|
339
|
+
content: string;
|
|
340
|
+
reasoningDelta?: string;
|
|
341
|
+
toolName?: string;
|
|
342
|
+
stats?: TurnStats;
|
|
343
|
+
planState?: TypedPlanState;
|
|
344
|
+
repair?: RepairReport;
|
|
345
|
+
error?: string;
|
|
346
|
+
}
|
|
347
|
+
interface CacheFirstLoopOptions {
|
|
348
|
+
client: DeepSeekClient;
|
|
349
|
+
prefix: ImmutablePrefix;
|
|
350
|
+
tools?: ToolRegistry;
|
|
351
|
+
model?: string;
|
|
352
|
+
maxToolIters?: number;
|
|
353
|
+
stream?: boolean;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Pillar 1 — Cache-First Loop.
|
|
357
|
+
*
|
|
358
|
+
* - prefix is immutable (cache target)
|
|
359
|
+
* - log is append-only (preserves prior-turn prefix)
|
|
360
|
+
* - scratch is per-turn volatile (never sent upstream)
|
|
361
|
+
*
|
|
362
|
+
* Yields a stream of events so a TUI can render progressively.
|
|
363
|
+
*/
|
|
364
|
+
declare class CacheFirstLoop {
|
|
365
|
+
readonly client: DeepSeekClient;
|
|
366
|
+
readonly prefix: ImmutablePrefix;
|
|
367
|
+
readonly tools: ToolRegistry;
|
|
368
|
+
readonly model: string;
|
|
369
|
+
readonly maxToolIters: number;
|
|
370
|
+
readonly stream: boolean;
|
|
371
|
+
readonly log: AppendOnlyLog;
|
|
372
|
+
readonly scratch: VolatileScratch;
|
|
373
|
+
readonly stats: SessionStats;
|
|
374
|
+
readonly repair: ToolCallRepair;
|
|
375
|
+
private _turn;
|
|
376
|
+
constructor(opts: CacheFirstLoopOptions);
|
|
377
|
+
private buildMessages;
|
|
378
|
+
step(userInput: string): AsyncGenerator<LoopEvent>;
|
|
379
|
+
run(userInput: string, onEvent?: (ev: LoopEvent) => void): Promise<string>;
|
|
380
|
+
private assistantMessage;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Minimal `.env` loader; no dependency on dotenv.
|
|
385
|
+
*
|
|
386
|
+
* Reads KEY=VALUE lines and populates `process.env` for keys not already set.
|
|
387
|
+
* Silently no-ops if the file is missing. Safe to call from library entry
|
|
388
|
+
* points, CLI commands, examples, and benchmark runners.
|
|
389
|
+
*/
|
|
390
|
+
declare function loadDotenv(path?: string): void;
|
|
391
|
+
|
|
392
|
+
/** Reasonix — DeepSeek-native agent framework. Library entry point. */
|
|
393
|
+
|
|
394
|
+
declare const VERSION = "0.0.1";
|
|
395
|
+
|
|
396
|
+
export { AppendOnlyLog, CacheFirstLoop, type CacheFirstLoopOptions, type ChatMessage, type ChatResponse, DeepSeekClient, type DeepSeekClientOptions, type EventRole, type FlattenDecision, ImmutablePrefix, type ImmutablePrefixOptions, type JSONSchema, type LoopEvent, type RepairReport, type RetryInfo, type RetryOptions, type Role, type ScavengeOptions, type ScavengeResult, SessionStats, type SessionSummary, StormBreaker, type StreamChunk, type ToolCall, ToolCallRepair, type ToolCallRepairOptions, type ToolDefinition, type ToolFunctionSpec, ToolRegistry, type ToolSpec, type TruncationRepairResult, type TurnStats, type TypedPlanState, Usage, VERSION, VolatileScratch, analyzeSchema, claudeEquivalentCost, costUsd, emptyPlanState, fetchWithRetry, flattenSchema, harvest, isPlanStateEmpty, loadDotenv, nestArguments, repairTruncatedJson, scavengeToolCalls };
|