reasonix 0.3.1 → 0.3.2
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/README.md +84 -79
- package/dist/cli/index.js +73 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +16 -2
- package/dist/index.js +43 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -433,7 +433,7 @@ declare class ToolRegistry {
|
|
|
433
433
|
dispatch(name: string, argumentsRaw: string | Record<string, unknown>): Promise<string>;
|
|
434
434
|
}
|
|
435
435
|
|
|
436
|
-
type EventRole = "assistant_delta" | "assistant_final" | "tool" | "done" | "error" | "branch_start" | "branch_progress" | "branch_done";
|
|
436
|
+
type EventRole = "assistant_delta" | "assistant_final" | "tool" | "done" | "error" | "warning" | "branch_start" | "branch_progress" | "branch_done";
|
|
437
437
|
interface BranchSummary {
|
|
438
438
|
budget: number;
|
|
439
439
|
chosenIndex: number;
|
|
@@ -528,6 +528,12 @@ declare class CacheFirstLoop {
|
|
|
528
528
|
readonly resumedMessageCount: number;
|
|
529
529
|
private _turn;
|
|
530
530
|
private _streamPreference;
|
|
531
|
+
/**
|
|
532
|
+
* Set by {@link abort} to short-circuit the tool-call loop after the
|
|
533
|
+
* current iteration. Reset at the start of each `step()` so an Esc
|
|
534
|
+
* during one turn doesn't poison the next.
|
|
535
|
+
*/
|
|
536
|
+
private _aborted;
|
|
531
537
|
constructor(opts: CacheFirstLoopOptions);
|
|
532
538
|
/**
|
|
533
539
|
* Shrink the log by re-truncating oversized tool results to a tighter
|
|
@@ -553,6 +559,14 @@ declare class CacheFirstLoop {
|
|
|
553
559
|
*/
|
|
554
560
|
configure(opts: ReconfigurableOptions): void;
|
|
555
561
|
private buildMessages;
|
|
562
|
+
/**
|
|
563
|
+
* Signal the currently-running {@link step} that the user wants to
|
|
564
|
+
* stop exploring. Takes effect at the next iteration boundary — if a
|
|
565
|
+
* tool call is mid-flight it will be allowed to finish, then the
|
|
566
|
+
* loop diverts to the forced-summary path so the user gets an
|
|
567
|
+
* answer instead of a cliff. Called by the TUI on Esc.
|
|
568
|
+
*/
|
|
569
|
+
abort(): void;
|
|
556
570
|
step(userInput: string): AsyncGenerator<LoopEvent>;
|
|
557
571
|
private forceSummaryAfterIterLimit;
|
|
558
572
|
run(userInput: string, onEvent?: (ev: LoopEvent) => void): Promise<string>;
|
|
@@ -1277,6 +1291,6 @@ declare function redactKey(key: string): string;
|
|
|
1277
1291
|
|
|
1278
1292
|
/** Reasonix — DeepSeek-native agent framework. Library entry point. */
|
|
1279
1293
|
|
|
1280
|
-
declare const VERSION = "0.3.
|
|
1294
|
+
declare const VERSION = "0.3.2";
|
|
1281
1295
|
|
|
1282
1296
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1102,6 +1102,12 @@ var CacheFirstLoop = class {
|
|
|
1102
1102
|
resumedMessageCount;
|
|
1103
1103
|
_turn = 0;
|
|
1104
1104
|
_streamPreference;
|
|
1105
|
+
/**
|
|
1106
|
+
* Set by {@link abort} to short-circuit the tool-call loop after the
|
|
1107
|
+
* current iteration. Reset at the start of each `step()` so an Esc
|
|
1108
|
+
* during one turn doesn't poison the next.
|
|
1109
|
+
*/
|
|
1110
|
+
_aborted = false;
|
|
1105
1111
|
constructor(opts) {
|
|
1106
1112
|
this.client = opts.client;
|
|
1107
1113
|
this.prefix = opts.prefix;
|
|
@@ -1213,12 +1219,42 @@ var CacheFirstLoop = class {
|
|
|
1213
1219
|
if (pendingUser !== null) msgs.push({ role: "user", content: pendingUser });
|
|
1214
1220
|
return msgs;
|
|
1215
1221
|
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Signal the currently-running {@link step} that the user wants to
|
|
1224
|
+
* stop exploring. Takes effect at the next iteration boundary — if a
|
|
1225
|
+
* tool call is mid-flight it will be allowed to finish, then the
|
|
1226
|
+
* loop diverts to the forced-summary path so the user gets an
|
|
1227
|
+
* answer instead of a cliff. Called by the TUI on Esc.
|
|
1228
|
+
*/
|
|
1229
|
+
abort() {
|
|
1230
|
+
this._aborted = true;
|
|
1231
|
+
}
|
|
1216
1232
|
async *step(userInput) {
|
|
1217
1233
|
this._turn++;
|
|
1218
1234
|
this.scratch.reset();
|
|
1235
|
+
this._aborted = false;
|
|
1219
1236
|
let pendingUser = userInput;
|
|
1220
1237
|
const toolSpecs = this.prefix.tools();
|
|
1238
|
+
const warnAt = Math.max(1, Math.floor(this.maxToolIters * 0.7));
|
|
1239
|
+
let warnedForIterBudget = false;
|
|
1221
1240
|
for (let iter = 0; iter < this.maxToolIters; iter++) {
|
|
1241
|
+
if (this._aborted) {
|
|
1242
|
+
yield {
|
|
1243
|
+
turn: this._turn,
|
|
1244
|
+
role: "warning",
|
|
1245
|
+
content: `aborted at iter ${iter}/${this.maxToolIters} \u2014 forcing summary from what was gathered`
|
|
1246
|
+
};
|
|
1247
|
+
yield* this.forceSummaryAfterIterLimit({ reason: "aborted" });
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
if (!warnedForIterBudget && iter >= warnAt) {
|
|
1251
|
+
warnedForIterBudget = true;
|
|
1252
|
+
yield {
|
|
1253
|
+
turn: this._turn,
|
|
1254
|
+
role: "warning",
|
|
1255
|
+
content: `${iter}/${this.maxToolIters} tool calls used \u2014 approaching budget. Press Esc to force a summary now.`
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1222
1258
|
const messages = this.buildMessages(pendingUser);
|
|
1223
1259
|
let assistantContent = "";
|
|
1224
1260
|
let reasoningContent = "";
|
|
@@ -1406,9 +1442,9 @@ var CacheFirstLoop = class {
|
|
|
1406
1442
|
};
|
|
1407
1443
|
}
|
|
1408
1444
|
}
|
|
1409
|
-
yield* this.forceSummaryAfterIterLimit();
|
|
1445
|
+
yield* this.forceSummaryAfterIterLimit({ reason: "budget" });
|
|
1410
1446
|
}
|
|
1411
|
-
async *forceSummaryAfterIterLimit() {
|
|
1447
|
+
async *forceSummaryAfterIterLimit(opts = { reason: "budget" }) {
|
|
1412
1448
|
try {
|
|
1413
1449
|
const messages = this.buildMessages(null);
|
|
1414
1450
|
const resp = await this.client.chat({
|
|
@@ -1417,7 +1453,8 @@ var CacheFirstLoop = class {
|
|
|
1417
1453
|
// no tools → model is forced to answer in text
|
|
1418
1454
|
});
|
|
1419
1455
|
const summary = resp.content?.trim() || "(model returned no text; try a narrower question or raise --max-tool-iters)";
|
|
1420
|
-
const
|
|
1456
|
+
const reasonPrefix = opts.reason === "aborted" ? "[aborted by user (Esc) \u2014 summarizing what I found so far]" : `[tool-call budget (${this.maxToolIters}) reached \u2014 forcing summary from what I found]`;
|
|
1457
|
+
const annotated = `${reasonPrefix}
|
|
1421
1458
|
|
|
1422
1459
|
${summary}`;
|
|
1423
1460
|
const summaryStats = this.stats.record(this._turn, this.model, resp.usage ?? new Usage());
|
|
@@ -1430,11 +1467,12 @@ ${summary}`;
|
|
|
1430
1467
|
};
|
|
1431
1468
|
yield { turn: this._turn, role: "done", content: summary };
|
|
1432
1469
|
} catch (err) {
|
|
1470
|
+
const label = opts.reason === "aborted" ? "aborted by user" : `tool-call budget (${this.maxToolIters}) reached`;
|
|
1433
1471
|
yield {
|
|
1434
1472
|
turn: this._turn,
|
|
1435
1473
|
role: "error",
|
|
1436
1474
|
content: "",
|
|
1437
|
-
error:
|
|
1475
|
+
error: `${label} and the fallback summary call failed: ${err.message}. Run /clear and retry with a narrower question, or raise --max-tool-iters.`
|
|
1438
1476
|
};
|
|
1439
1477
|
yield { turn: this._turn, role: "done", content: "" };
|
|
1440
1478
|
}
|
|
@@ -2492,7 +2530,7 @@ function redactKey(key) {
|
|
|
2492
2530
|
}
|
|
2493
2531
|
|
|
2494
2532
|
// src/index.ts
|
|
2495
|
-
var VERSION = "0.3.
|
|
2533
|
+
var VERSION = "0.3.2";
|
|
2496
2534
|
export {
|
|
2497
2535
|
AppendOnlyLog,
|
|
2498
2536
|
CacheFirstLoop,
|