reasonix 0.12.8 → 0.12.14
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/dashboard/app.css +194 -0
- package/dashboard/app.js +670 -41
- package/dist/cli/index.js +10804 -10418
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +38 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -491,11 +491,28 @@ interface ImmutablePrefixOptions {
|
|
|
491
491
|
}
|
|
492
492
|
declare class ImmutablePrefix {
|
|
493
493
|
readonly system: string;
|
|
494
|
-
|
|
494
|
+
/**
|
|
495
|
+
* Backing array for `toolSpecs`. Originally `Object.freeze`d at
|
|
496
|
+
* construction (hence the class name) — but `addTool` now lets the
|
|
497
|
+
* dashboard register `semantic_search` after a mid-session
|
|
498
|
+
* `reasonix index` build without forcing the user to restart. Each
|
|
499
|
+
* add is documented to cost one cache-miss turn (the cached prefix
|
|
500
|
+
* on DeepSeek's side is keyed by the full tool list); subsequent
|
|
501
|
+
* turns re-cache against the new shape.
|
|
502
|
+
*/
|
|
503
|
+
private _toolSpecs;
|
|
495
504
|
readonly fewShots: readonly ChatMessage[];
|
|
496
505
|
constructor(opts: ImmutablePrefixOptions);
|
|
506
|
+
get toolSpecs(): readonly ToolSpec[];
|
|
497
507
|
toMessages(): ChatMessage[];
|
|
498
508
|
tools(): ToolSpec[];
|
|
509
|
+
/**
|
|
510
|
+
* Add a tool spec to the prefix. Returns `true` if added, `false`
|
|
511
|
+
* if a tool with the same name was already present (callers can
|
|
512
|
+
* decide whether to ignore or surface the no-op). The model picks
|
|
513
|
+
* up the new tool on the next turn after the cache busts once.
|
|
514
|
+
*/
|
|
515
|
+
addTool(spec: ToolSpec): boolean;
|
|
499
516
|
get fingerprint(): string;
|
|
500
517
|
}
|
|
501
518
|
declare class AppendOnlyLog {
|
package/dist/index.js
CHANGED
|
@@ -1157,23 +1157,48 @@ function blockToString(block) {
|
|
|
1157
1157
|
import { createHash } from "crypto";
|
|
1158
1158
|
var ImmutablePrefix = class {
|
|
1159
1159
|
system;
|
|
1160
|
-
|
|
1160
|
+
/**
|
|
1161
|
+
* Backing array for `toolSpecs`. Originally `Object.freeze`d at
|
|
1162
|
+
* construction (hence the class name) — but `addTool` now lets the
|
|
1163
|
+
* dashboard register `semantic_search` after a mid-session
|
|
1164
|
+
* `reasonix index` build without forcing the user to restart. Each
|
|
1165
|
+
* add is documented to cost one cache-miss turn (the cached prefix
|
|
1166
|
+
* on DeepSeek's side is keyed by the full tool list); subsequent
|
|
1167
|
+
* turns re-cache against the new shape.
|
|
1168
|
+
*/
|
|
1169
|
+
_toolSpecs;
|
|
1161
1170
|
fewShots;
|
|
1162
1171
|
constructor(opts) {
|
|
1163
1172
|
this.system = opts.system;
|
|
1164
|
-
this.
|
|
1173
|
+
this._toolSpecs = [...opts.toolSpecs ?? []];
|
|
1165
1174
|
this.fewShots = Object.freeze([...opts.fewShots ?? []]);
|
|
1166
1175
|
}
|
|
1176
|
+
get toolSpecs() {
|
|
1177
|
+
return this._toolSpecs;
|
|
1178
|
+
}
|
|
1167
1179
|
toMessages() {
|
|
1168
1180
|
return [{ role: "system", content: this.system }, ...this.fewShots.map((m) => ({ ...m }))];
|
|
1169
1181
|
}
|
|
1170
1182
|
tools() {
|
|
1171
|
-
return this.
|
|
1183
|
+
return this._toolSpecs.map((t) => structuredClone(t));
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Add a tool spec to the prefix. Returns `true` if added, `false`
|
|
1187
|
+
* if a tool with the same name was already present (callers can
|
|
1188
|
+
* decide whether to ignore or surface the no-op). The model picks
|
|
1189
|
+
* up the new tool on the next turn after the cache busts once.
|
|
1190
|
+
*/
|
|
1191
|
+
addTool(spec) {
|
|
1192
|
+
const name = spec.function?.name;
|
|
1193
|
+
if (!name) return false;
|
|
1194
|
+
if (this._toolSpecs.some((t) => t.function?.name === name)) return false;
|
|
1195
|
+
this._toolSpecs.push(spec);
|
|
1196
|
+
return true;
|
|
1172
1197
|
}
|
|
1173
1198
|
get fingerprint() {
|
|
1174
1199
|
const blob = JSON.stringify({
|
|
1175
1200
|
system: this.system,
|
|
1176
|
-
tools: this.
|
|
1201
|
+
tools: this._toolSpecs,
|
|
1177
1202
|
shots: this.fewShots
|
|
1178
1203
|
});
|
|
1179
1204
|
return createHash("sha256").update(blob).digest("hex").slice(0, 16);
|
|
@@ -2657,6 +2682,7 @@ var CacheFirstLoop = class {
|
|
|
2657
2682
|
return;
|
|
2658
2683
|
}
|
|
2659
2684
|
}
|
|
2685
|
+
let workspaceSwitchPending = false;
|
|
2660
2686
|
for (const call of repairedCalls) {
|
|
2661
2687
|
const name = call.function?.name ?? "";
|
|
2662
2688
|
const args = call.function?.arguments ?? "{}";
|
|
@@ -2679,7 +2705,11 @@ var CacheFirstLoop = class {
|
|
|
2679
2705
|
});
|
|
2680
2706
|
for (const w of hookWarnings(preReport.outcomes, this._turn)) yield w;
|
|
2681
2707
|
let result;
|
|
2682
|
-
if (
|
|
2708
|
+
if (workspaceSwitchPending) {
|
|
2709
|
+
result = JSON.stringify({
|
|
2710
|
+
error: `${name}: deferred because change_workspace in the same batch is awaiting the user's approval. Re-issue this call on your next turn \u2014 the sandbox root may have changed.`
|
|
2711
|
+
});
|
|
2712
|
+
} else if (preReport.blocked) {
|
|
2683
2713
|
const blocking = preReport.outcomes[preReport.outcomes.length - 1];
|
|
2684
2714
|
const reason = (blocking?.stderr || blocking?.stdout || "blocked by PreToolUse hook").trim();
|
|
2685
2715
|
result = `[hook block] ${blocking?.hook.command ?? "<unknown>"}
|
|
@@ -2689,6 +2719,9 @@ ${reason}`;
|
|
|
2689
2719
|
signal,
|
|
2690
2720
|
maxResultTokens: DEFAULT_MAX_RESULT_TOKENS
|
|
2691
2721
|
});
|
|
2722
|
+
if (name === "change_workspace" && result.includes('"WorkspaceConfirmationError:')) {
|
|
2723
|
+
workspaceSwitchPending = true;
|
|
2724
|
+
}
|
|
2692
2725
|
const postReport = await runHooks({
|
|
2693
2726
|
hooks: this.hooks,
|
|
2694
2727
|
payload: {
|