reasonix 0.3.0-alpha.3 → 0.3.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -527,6 +527,26 @@ declare class CacheFirstLoop {
527
527
  run(userInput: string, onEvent?: (ev: LoopEvent) => void): Promise<string>;
528
528
  private assistantMessage;
529
529
  }
530
+ /**
531
+ * Truncate any tool-role message whose content exceeds the cap. User
532
+ * and assistant messages are left alone because (a) they're almost
533
+ * always small, (b) truncating user prompts would corrupt conversational
534
+ * intent in a way the user didn't author. Exported for tests.
535
+ */
536
+ declare function healLoadedMessages(messages: ChatMessage[], maxChars: number): {
537
+ messages: ChatMessage[];
538
+ healedCount: number;
539
+ healedFrom: number;
540
+ };
541
+ /**
542
+ * Annotate the `DeepSeek 400: … maximum context length …` error the API
543
+ * returns when a session's history has grown past 131,072 tokens. The
544
+ * raw message is a JSON blob; we surface a short actionable hint on top
545
+ * so the user knows to `/forget` or `/clear` rather than parsing the
546
+ * JSON themselves. Other errors pass through unchanged — the loop's
547
+ * error channel already formats them well enough.
548
+ */
549
+ declare function formatLoopError(err: Error): string;
530
550
 
531
551
  /**
532
552
  * Session persistence.
@@ -994,6 +1014,61 @@ declare class McpClient {
994
1014
  private dispatch;
995
1015
  }
996
1016
 
1017
+ /**
1018
+ * HTTP+SSE transport for MCP (spec version 2024-11-05).
1019
+ *
1020
+ * Wire shape:
1021
+ * 1. Client opens GET to the SSE URL with `Accept: text/event-stream`.
1022
+ * 2. Server's first SSE event is `event: endpoint`, `data: <url>` — the
1023
+ * URL (relative or absolute) the client must POST JSON-RPC requests
1024
+ * to. All subsequent server → client messages arrive as `event: message`
1025
+ * SSE frames carrying a JSON-RPC response or server-initiated frame.
1026
+ * 3. Client POSTs each outgoing JSON-RPC frame to the endpoint URL.
1027
+ * The POST response body is ignored — replies land on the SSE stream.
1028
+ *
1029
+ * This transport exists so Reasonix can talk to hosted/remote MCP servers
1030
+ * (e.g. a company's internal knowledge server fronted by auth). Stdio
1031
+ * covers local subprocesses; SSE covers everything else.
1032
+ *
1033
+ * Note: the newer "Streamable HTTP" transport (2025 spec) folds the POST
1034
+ * and SSE streams onto a single endpoint. We stay on 2024-11-05 here —
1035
+ * that's what `MCP_PROTOCOL_VERSION` advertises in the initialize handshake
1036
+ * and what currently-published servers implement.
1037
+ */
1038
+
1039
+ interface SseTransportOptions {
1040
+ /** SSE endpoint URL, e.g. `https://mcp.example.com/sse`. */
1041
+ url: string;
1042
+ /** Extra headers sent on both the SSE GET and the JSON-RPC POSTs (e.g. `Authorization`). */
1043
+ headers?: Record<string, string>;
1044
+ }
1045
+ /**
1046
+ * Open an SSE stream to `url`, parse incoming events into JsonRpcMessages,
1047
+ * POST outgoing frames to the endpoint URL the server advertises.
1048
+ */
1049
+ declare class SseTransport implements McpTransport {
1050
+ private readonly url;
1051
+ private readonly headers;
1052
+ private readonly queue;
1053
+ private readonly waiters;
1054
+ private readonly controller;
1055
+ private closed;
1056
+ private postUrl;
1057
+ private readonly endpointReady;
1058
+ private resolveEndpoint;
1059
+ private rejectEndpoint;
1060
+ constructor(opts: SseTransportOptions);
1061
+ send(message: JsonRpcMessage): Promise<void>;
1062
+ messages(): AsyncIterableIterator<JsonRpcMessage>;
1063
+ close(): Promise<void>;
1064
+ private runStream;
1065
+ private handleEvent;
1066
+ private failHandshake;
1067
+ private pushMessage;
1068
+ private pushError;
1069
+ private markClosed;
1070
+ }
1071
+
997
1072
  /**
998
1073
  * Bridge: register an MCP server's tools into a Reasonix ToolRegistry.
999
1074
  *
@@ -1014,7 +1089,26 @@ interface BridgeOptions {
1014
1089
  registry?: ToolRegistry;
1015
1090
  /** Auto-flatten deep schemas (Pillar 3). Defaults to the registry's own default (true). */
1016
1091
  autoFlatten?: boolean;
1092
+ /**
1093
+ * Per-tool-call result cap, in characters. If a tool returns more than
1094
+ * this, the result is truncated and a `[…truncated N chars…]` marker is
1095
+ * appended before the last KB so the model still sees a useful tail.
1096
+ * Defaults to {@link DEFAULT_MAX_RESULT_CHARS}.
1097
+ *
1098
+ * Why this exists: DeepSeek V3's context is 131,072 tokens. A single
1099
+ * `read_file` against a big source file can return >3 MB of text
1100
+ * (~900k tokens) and permanently poison the session — every subsequent
1101
+ * turn rebuilds the history and 400s. This cap is a floor. Users who
1102
+ * legitimately want bigger payloads can raise it explicitly.
1103
+ */
1104
+ maxResultChars?: number;
1017
1105
  }
1106
+ /**
1107
+ * 32,000 chars ≈ 8k English tokens, or ~16k CJK tokens. Small enough to
1108
+ * fit comfortably in history even across 5–10 tool calls, large enough
1109
+ * that most file reads and directory listings fit un-truncated.
1110
+ */
1111
+ declare const DEFAULT_MAX_RESULT_CHARS = 32000;
1018
1112
  interface BridgeResult {
1019
1113
  registry: ToolRegistry;
1020
1114
  /** Names actually registered (may differ from MCP names when a prefix is applied). */
@@ -1033,6 +1127,10 @@ interface BridgeResult {
1033
1127
  * they fit Reasonix's existing tool-dispatch contract.
1034
1128
  */
1035
1129
  declare function bridgeMcpTools(client: McpClient, opts?: BridgeOptions): Promise<BridgeResult>;
1130
+ interface FlattenOptions {
1131
+ /** Cap the flattened string at this many characters. Default: no cap. */
1132
+ maxChars?: number;
1133
+ }
1036
1134
  /**
1037
1135
  * Turn an MCP CallToolResult into a string — the contract Reasonix's
1038
1136
  * ToolRegistry.dispatch returns. We:
@@ -1042,8 +1140,58 @@ declare function bridgeMcpTools(client: McpClient, opts?: BridgeOptions): Promis
1042
1140
  * prompts later)
1043
1141
  * - prefix error results with "ERROR: " so the calling model sees the
1044
1142
  * failure clearly even through JSON mode
1143
+ * - optionally truncate to `maxChars` so a single oversized tool result
1144
+ * (e.g. a big `read_file`) can't poison the session by blowing past
1145
+ * the model's context window
1146
+ */
1147
+ declare function flattenMcpResult(result: CallToolResult, opts?: FlattenOptions): string;
1148
+ /**
1149
+ * Keep the head AND a short tail so the model sees both "what the tool
1150
+ * started returning" and "how it ended". Head-only loses file endings
1151
+ * (e.g. an error message appended at the bottom of a stack trace); the
1152
+ * 1KB tail window covers that while costing almost nothing. Exported for
1153
+ * tests and reuse by non-MCP tool adapters that want the same policy.
1045
1154
  */
1046
- declare function flattenMcpResult(result: CallToolResult): string;
1155
+ declare function truncateForModel(s: string, maxChars: number): string;
1156
+
1157
+ /**
1158
+ * Parse the `--mcp` CLI argument into a transport-tagged spec.
1159
+ *
1160
+ * Accepted forms:
1161
+ * "name=command args..." → stdio, namespaced (tools prefixed with `name_`)
1162
+ * "command args..." → stdio, anonymous
1163
+ * "name=https://host/sse" → SSE, namespaced
1164
+ * "https://host/sse" → SSE, anonymous
1165
+ * ("http://" is also honored — useful for local dev servers.)
1166
+ *
1167
+ * The identifier regex before `=` is deliberately narrow
1168
+ * (`[a-zA-Z_][a-zA-Z0-9_]*`) so Windows drive letters ("C:\\...") and
1169
+ * other strings containing `=` or `:` don't accidentally trigger the
1170
+ * namespace branch. If a user ever wants their command to literally start
1171
+ * with `foo=...` as a bare command, they can wrap it in quotes inside the
1172
+ * shell command string.
1173
+ *
1174
+ * Transport is selected solely by whether the body begins with `http://`
1175
+ * or `https://`. Anything else is stdio — including ws:// (unsupported)
1176
+ * which will surface later as a spawn error, keeping the rule local.
1177
+ */
1178
+ interface StdioMcpSpec {
1179
+ transport: "stdio";
1180
+ /** Namespace prefix applied to each registered tool, or null if anonymous. */
1181
+ name: string | null;
1182
+ /** Argv[0]. */
1183
+ command: string;
1184
+ /** Remaining argv. */
1185
+ args: string[];
1186
+ }
1187
+ interface SseMcpSpec {
1188
+ transport: "sse";
1189
+ name: string | null;
1190
+ /** Fully qualified SSE endpoint URL. */
1191
+ url: string;
1192
+ }
1193
+ type McpSpec = StdioMcpSpec | SseMcpSpec;
1194
+ declare function parseMcpSpec(input: string): McpSpec;
1047
1195
 
1048
1196
  /**
1049
1197
  * User-level config storage for the Reasonix CLI.
@@ -1055,10 +1203,36 @@ declare function flattenMcpResult(result: CallToolResult): string;
1055
1203
  * The library itself never touches the config file — it only reads
1056
1204
  * `DEEPSEEK_API_KEY` from the environment. The CLI is responsible for
1057
1205
  * pulling from the config file and exposing it via env var to the loop.
1206
+ *
1207
+ * Beyond the API key, the config also remembers the user's *defaults*
1208
+ * from `reasonix setup`: preset, MCP servers, session. This is what
1209
+ * makes `reasonix chat` with no flags "just work" after first-run.
1058
1210
  */
1211
+ /** One of the preset bundles (model + harvest + branch combo). */
1212
+ type PresetName = "fast" | "smart" | "max";
1059
1213
  interface ReasonixConfig {
1060
1214
  apiKey?: string;
1061
1215
  baseUrl?: string;
1216
+ /**
1217
+ * Default preset for `reasonix chat` / `reasonix run` when no flags override.
1218
+ * Maps to model + harvest + branch combos (see presets.ts). Missing → "fast".
1219
+ */
1220
+ preset?: PresetName;
1221
+ /**
1222
+ * Default MCP server specs to bridge on every `reasonix chat`, in the
1223
+ * same `"name=cmd args..."` format that `--mcp` takes. Stored as strings
1224
+ * so `reasonix setup` stays symmetrical with the flag — one parser, one
1225
+ * format in the config file, grep-friendly.
1226
+ */
1227
+ mcp?: string[];
1228
+ /**
1229
+ * Default session name (null/missing → "default", which is what the
1230
+ * CLI has been doing anyway). `reasonix setup` lets users pick a name
1231
+ * or opt into ephemeral.
1232
+ */
1233
+ session?: string | null;
1234
+ /** Marks that `reasonix setup` has completed at least once. */
1235
+ setupCompleted?: boolean;
1062
1236
  }
1063
1237
  declare function defaultConfigPath(): string;
1064
1238
  declare function readConfig(path?: string): ReasonixConfig;
@@ -1072,6 +1246,6 @@ declare function redactKey(key: string): string;
1072
1246
 
1073
1247
  /** Reasonix — DeepSeek-native agent framework. Library entry point. */
1074
1248
 
1075
- declare const VERSION = "0.3.0-alpha.3";
1249
+ declare const VERSION = "0.3.0-alpha.6";
1076
1250
 
1077
- export { AppendOnlyLog, type BranchOptions, type BranchProgress, type BranchResult, type BranchSample, type BranchSelector, type BranchSummary, type BridgeOptions, type BridgeResult, CacheFirstLoop, type CacheFirstLoopOptions, type CallToolResult, type ChatMessage, type ChatResponse, DeepSeekClient, type DeepSeekClientOptions, type RenderOptions as DiffRenderOptions, type DiffReport, type DiffSide, type EventRole, type FlattenDecision, type HarvestOptions, ImmutablePrefix, type ImmutablePrefixOptions, type InitializeResult, type JSONSchema, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcResponse, type ListToolsResult, type LoopEvent, MCP_PROTOCOL_VERSION, McpClient, type McpClientOptions, type McpContentBlock, type McpTool, type McpToolSchema, type McpTransport, type ReadTranscriptResult, type ReasonixConfig, type ReconfigurableOptions, type RepairReport, type ReplayStats, type RetryInfo, type RetryOptions, type Role, type ScavengeOptions, type ScavengeResult, type SessionInfo, SessionStats, type SessionSummary, StdioTransport, type StdioTransportOptions, StormBreaker, type StreamChunk, type ToolCall, ToolCallRepair, type ToolCallRepairOptions, type ToolDefinition, type ToolFunctionSpec, ToolRegistry, type ToolSpec, type TranscriptMeta, type TranscriptRecord, type TruncationRepairResult, type TurnPair, type TurnStats, type TypedPlanState, Usage, VERSION, VolatileScratch, aggregateBranchUsage, analyzeSchema, appendSessionMessage, bridgeMcpTools, claudeEquivalentCost, computeReplayStats, costUsd, defaultConfigPath, defaultSelector, deleteSession, diffTranscripts, emptyPlanState, fetchWithRetry, flattenMcpResult, flattenSchema, harvest, isJsonRpcError, isPlanStateEmpty, isPlausibleKey, listSessions, loadApiKey, loadDotenv, loadSessionMessages, nestArguments, openTranscriptFile, parseTranscript, readConfig, readTranscript, recordFromLoopEvent, redactKey, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, runBranches, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, writeConfig, writeMeta, writeRecord };
1251
+ export { AppendOnlyLog, type BranchOptions, type BranchProgress, type BranchResult, type BranchSample, type BranchSelector, type BranchSummary, type BridgeOptions, type BridgeResult, CacheFirstLoop, type CacheFirstLoopOptions, type CallToolResult, type ChatMessage, type ChatResponse, DEFAULT_MAX_RESULT_CHARS, DeepSeekClient, type DeepSeekClientOptions, type RenderOptions as DiffRenderOptions, type DiffReport, type DiffSide, type EventRole, type FlattenDecision, type FlattenOptions, type HarvestOptions, ImmutablePrefix, type ImmutablePrefixOptions, type InitializeResult, type JSONSchema, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcResponse, type ListToolsResult, type LoopEvent, MCP_PROTOCOL_VERSION, McpClient, type McpClientOptions, type McpContentBlock, type McpSpec, type McpTool, type McpToolSchema, type McpTransport, type ReadTranscriptResult, type ReasonixConfig, type ReconfigurableOptions, type RepairReport, type ReplayStats, type RetryInfo, type RetryOptions, type Role, type ScavengeOptions, type ScavengeResult, type SessionInfo, SessionStats, type SessionSummary, type SseMcpSpec, SseTransport, type SseTransportOptions, type StdioMcpSpec, StdioTransport, type StdioTransportOptions, StormBreaker, type StreamChunk, type ToolCall, ToolCallRepair, type ToolCallRepairOptions, type ToolDefinition, type ToolFunctionSpec, ToolRegistry, type ToolSpec, type TranscriptMeta, type TranscriptRecord, type TruncationRepairResult, type TurnPair, type TurnStats, type TypedPlanState, Usage, VERSION, VolatileScratch, aggregateBranchUsage, analyzeSchema, appendSessionMessage, bridgeMcpTools, claudeEquivalentCost, computeReplayStats, costUsd, defaultConfigPath, defaultSelector, deleteSession, diffTranscripts, emptyPlanState, fetchWithRetry, flattenMcpResult, flattenSchema, formatLoopError, harvest, healLoadedMessages, isJsonRpcError, isPlanStateEmpty, isPlausibleKey, listSessions, loadApiKey, loadDotenv, loadSessionMessages, nestArguments, openTranscriptFile, parseMcpSpec, parseTranscript, readConfig, readTranscript, recordFromLoopEvent, redactKey, renderMarkdown as renderDiffMarkdown, renderSummaryTable as renderDiffSummary, repairTruncatedJson, replayFromFile, runBranches, sanitizeName as sanitizeSessionName, saveApiKey, scavengeToolCalls, sessionPath, sessionsDir, similarity, truncateForModel, writeConfig, writeMeta, writeRecord };