@corenel/sidecar 0.8.8 → 0.9.0
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/cli.js +213 -40
- package/package.json +6 -6
package/dist/cli.js
CHANGED
|
@@ -17291,8 +17291,8 @@ ${yamlContent}` : yamlContent;
|
|
|
17291
17291
|
processedContent = content;
|
|
17292
17292
|
}
|
|
17293
17293
|
if (this.verbose) {
|
|
17294
|
-
const
|
|
17295
|
-
console.log(`[include] Loaded ${ext} file: ${filePath} (${
|
|
17294
|
+
const preview2 = processedContent.substring(0, 50).replace(/\n/g, "\\n");
|
|
17295
|
+
console.log(`[include] Loaded ${ext} file: ${filePath} (${preview2}...)`);
|
|
17296
17296
|
}
|
|
17297
17297
|
return {
|
|
17298
17298
|
src: processedContent,
|
|
@@ -17914,8 +17914,8 @@ ${content}` : parentData.content;
|
|
|
17914
17914
|
}
|
|
17915
17915
|
removedCount++;
|
|
17916
17916
|
if (verbose) {
|
|
17917
|
-
const
|
|
17918
|
-
console.log(` - Removing \`\`\`${lang} block: "${
|
|
17917
|
+
const preview2 = blockContent.substring(0, 50).replace(/\n/g, "\\n");
|
|
17918
|
+
console.log(` - Removing \`\`\`${lang} block: "${preview2}..."`);
|
|
17919
17919
|
}
|
|
17920
17920
|
return "";
|
|
17921
17921
|
});
|
|
@@ -18765,6 +18765,25 @@ ${firstUserMsg.content}`;
|
|
|
18765
18765
|
}
|
|
18766
18766
|
});
|
|
18767
18767
|
|
|
18768
|
+
// ../tools-node/toolGuidance.ts
|
|
18769
|
+
function nodeToolGuidance(toolNames) {
|
|
18770
|
+
const has3 = new Set(toolNames);
|
|
18771
|
+
const parts = [];
|
|
18772
|
+
if (has3.has(SHELL_TOOL)) parts.push(SHELL);
|
|
18773
|
+
if (PROC_TOOLS.some((t2) => has3.has(t2))) parts.push(PROCS);
|
|
18774
|
+
return parts.join("\n\n");
|
|
18775
|
+
}
|
|
18776
|
+
var SHELL_TOOL, PROC_TOOLS, SHELL, PROCS;
|
|
18777
|
+
var init_toolGuidance = __esm({
|
|
18778
|
+
"../tools-node/toolGuidance.ts"() {
|
|
18779
|
+
"use strict";
|
|
18780
|
+
SHELL_TOOL = "shell";
|
|
18781
|
+
PROC_TOOLS = ["proc_start", "proc_stop", "proc_list"];
|
|
18782
|
+
SHELL = `Running a command is often the shortest correct answer: use \`${SHELL_TOOL}\` for anything a command already does well -- listing, searching, git, package managers, build and test runners -- instead of reconstructing it from file reads. It waits for the command to finish and returns its output, so it is the wrong tool for anything that does not exit on its own.`;
|
|
18783
|
+
PROCS = `A command that keeps running (a dev server, a watcher, a queue worker) belongs to \`${PROC_TOOLS[0]}\`, not \`${SHELL_TOOL}\` -- starting one with \`${SHELL_TOOL}\` hangs the turn until it is killed. Use \`${PROC_TOOLS[2]}\` to see what is already running before starting anything, and \`${PROC_TOOLS[1]}\` to stop what you started. Do not stop a process you did not start.`;
|
|
18784
|
+
}
|
|
18785
|
+
});
|
|
18786
|
+
|
|
18768
18787
|
// ../tools-node/promptHost.ts
|
|
18769
18788
|
function backend(svc) {
|
|
18770
18789
|
return {
|
|
@@ -18822,8 +18841,22 @@ function nodePromptHost(workspace, project) {
|
|
|
18822
18841
|
sources[p2] = liveSrc;
|
|
18823
18842
|
return compile("", values, new HybridFileSystem(sources, backend(workspace)), "/" + p2);
|
|
18824
18843
|
},
|
|
18825
|
-
siteIndex: () => ""
|
|
18844
|
+
siteIndex: () => "",
|
|
18826
18845
|
// no site index in node (the help chat is browser-only)
|
|
18846
|
+
/* Who the agent says it IS. Without this, `composeAgentSystem` falls back
|
|
18847
|
+
* to its `'Prompd'` default and the `corenel` binary's agent introduced
|
|
18848
|
+
* itself as "the Prompd assistant" -- the same leak already fixed for the
|
|
18849
|
+
* browser help chat (composeHelpSystem) and missed here, because the node
|
|
18850
|
+
* host is the one PromptHost that never implemented the hook.
|
|
18851
|
+
*
|
|
18852
|
+
* Constant, not a parameter: every node consumer of this host (the CLI and
|
|
18853
|
+
* the sidecar) IS Corenel. A host that is not should implement its own. */
|
|
18854
|
+
appName: () => "Corenel",
|
|
18855
|
+
/* The product's guidance for the tools this run actually has -- the shell,
|
|
18856
|
+
* long-running processes, and deferred MCP tools. Gated per tool inside
|
|
18857
|
+
* nodeToolGuidance, because this same host serves the sidecar, whose shell
|
|
18858
|
+
* is behind --allow-shell. */
|
|
18859
|
+
toolGuidance: (names) => nodeToolGuidance(names)
|
|
18827
18860
|
};
|
|
18828
18861
|
}
|
|
18829
18862
|
var parser, compiler;
|
|
@@ -18832,6 +18865,7 @@ var init_promptHost = __esm({
|
|
|
18832
18865
|
"use strict";
|
|
18833
18866
|
init_dist();
|
|
18834
18867
|
init_protocol();
|
|
18868
|
+
init_toolGuidance();
|
|
18835
18869
|
parser = new PrompdParser();
|
|
18836
18870
|
compiler = new PrompdCompiler();
|
|
18837
18871
|
}
|
|
@@ -29290,7 +29324,11 @@ var STANDARD_POLICY = {
|
|
|
29290
29324
|
name: "standard",
|
|
29291
29325
|
description: "Read-only tools run automatically; writes ask for approval.",
|
|
29292
29326
|
onViolation: "stop",
|
|
29293
|
-
maxTurns
|
|
29327
|
+
// maxTurns counts iterations WITHIN one user message (one model call plus
|
|
29328
|
+
// its tool round-trip), not messages across a conversation -- 8 was
|
|
29329
|
+
// exhausted inside a single tool-heavy reply. 0 means unlimited (see
|
|
29330
|
+
// core/loop.ts); this default stays a finite backstop.
|
|
29331
|
+
maxTurns: 40,
|
|
29294
29332
|
permissions: {
|
|
29295
29333
|
"prompd:propose_edit": "allow",
|
|
29296
29334
|
// proposals are reviewed in the diff UI, not applied directly
|
|
@@ -29304,7 +29342,8 @@ var READ_ONLY_POLICY = {
|
|
|
29304
29342
|
name: "read-only",
|
|
29305
29343
|
description: "Inspection only \u2014 all writes and side effects are refused.",
|
|
29306
29344
|
onViolation: "stop",
|
|
29307
|
-
maxTurns:
|
|
29345
|
+
maxTurns: 40,
|
|
29346
|
+
// see STANDARD_POLICY: counts iterations within one reply, not conversation turns
|
|
29308
29347
|
tools: {
|
|
29309
29348
|
deny: [
|
|
29310
29349
|
"fs:write_file",
|
|
@@ -29347,7 +29386,9 @@ var AUTONOMOUS_POLICY = {
|
|
|
29347
29386
|
name: "autonomous",
|
|
29348
29387
|
description: "Everything runs automatically \u2014 no approval prompts (system config still asks).",
|
|
29349
29388
|
onViolation: "warn",
|
|
29350
|
-
|
|
29389
|
+
// Higher than the other builtins: nobody is watching an autonomous run turn
|
|
29390
|
+
// by turn, so it gets more headroom before the backstop kicks in.
|
|
29391
|
+
maxTurns: 80,
|
|
29351
29392
|
permissions: {
|
|
29352
29393
|
"system:*": "ask"
|
|
29353
29394
|
// even unattended, never silently reconfigure the harness
|
|
@@ -30080,6 +30121,10 @@ var forgetMemoryTool = {
|
|
|
30080
30121
|
return `Forgot memory "${name}".`;
|
|
30081
30122
|
}
|
|
30082
30123
|
};
|
|
30124
|
+
function preview(v2, max = 200) {
|
|
30125
|
+
if (v2.length <= max) return JSON.stringify(v2);
|
|
30126
|
+
return `${JSON.stringify(v2.slice(0, max))}... (${v2.length} chars total)`;
|
|
30127
|
+
}
|
|
30083
30128
|
var kvGetTool = {
|
|
30084
30129
|
name: "kv_get",
|
|
30085
30130
|
description: "Read a value you previously saved with kv_set, by key, from the local key/value store. This is a general note store \u2014 NOT a filesystem, working directory, or settings: use list_files/read_file for files.",
|
|
@@ -30099,10 +30144,42 @@ var kvSetTool = {
|
|
|
30099
30144
|
required: ["key", "value"]
|
|
30100
30145
|
},
|
|
30101
30146
|
// Permission is gated centrally by the loop's policy/permission layer.
|
|
30147
|
+
/*
|
|
30148
|
+
* THE RESULT STATES WHAT WAS STORED, AND WHAT IT REPLACED.
|
|
30149
|
+
*
|
|
30150
|
+
* This used to return `Set ${key}.` -- nothing else. Two consequences, both
|
|
30151
|
+
* observed in a real run:
|
|
30152
|
+
*
|
|
30153
|
+
* 1. "set bread=true" and "set bread=false" produced BYTE-IDENTICAL tool
|
|
30154
|
+
* results. An agent had no feedback that could distinguish a correct
|
|
30155
|
+
* write from a wrong one, so a mistaken value was indistinguishable from
|
|
30156
|
+
* a correct one for the rest of the conversation.
|
|
30157
|
+
*
|
|
30158
|
+
* 2. A LOST UPDATE was invisible. The common shape here is a list kept as
|
|
30159
|
+
* one blob under one key, updated read-modify-write: a later write
|
|
30160
|
+
* carrying a stale copy silently reverts an earlier one, and every
|
|
30161
|
+
* result still says "Set". A run marked two items done and only one
|
|
30162
|
+
* stayed done, with nothing anywhere to show the second had been undone.
|
|
30163
|
+
*
|
|
30164
|
+
* So: report the value, and name the value being replaced. An agent that
|
|
30165
|
+
* overwrites "apples done, bread done" with "apples done, bread pending"
|
|
30166
|
+
* now reads back, in the tool result it already has to process, exactly
|
|
30167
|
+
* what it just destroyed. The read-back is what makes this a check rather
|
|
30168
|
+
* than an echo of the argument -- a store that transformed, truncated or
|
|
30169
|
+
* dropped the write is caught here instead of at the summary.
|
|
30170
|
+
*/
|
|
30102
30171
|
async run(args, ctx) {
|
|
30103
30172
|
const key = str4(args, "key");
|
|
30104
|
-
|
|
30105
|
-
|
|
30173
|
+
const value = str4(args, "value");
|
|
30174
|
+
const before = await ctx.kv.get(key);
|
|
30175
|
+
await ctx.kv.set(key, value);
|
|
30176
|
+
const after = await ctx.kv.get(key);
|
|
30177
|
+
if (after !== value) {
|
|
30178
|
+
return `WRITE DID NOT TAKE. "${key}" was set to ${preview(value)} but reads back as ${after == null ? "(not set)" : preview(after)}. Do not rely on this key; do not report it as saved.`;
|
|
30179
|
+
}
|
|
30180
|
+
if (before == null) return `Set "${key}" = ${preview(value)} (new key).`;
|
|
30181
|
+
if (before === value) return `Set "${key}" = ${preview(value)} (unchanged).`;
|
|
30182
|
+
return `Set "${key}" = ${preview(value)}, REPLACING ${preview(before)}. If that previous value held anything you did not mean to discard, it is gone.`;
|
|
30106
30183
|
}
|
|
30107
30184
|
};
|
|
30108
30185
|
var recallResultTool = {
|
|
@@ -30604,6 +30681,18 @@ parameters:
|
|
|
30604
30681
|
type: string
|
|
30605
30682
|
description: The editor file / selection / compiled-output context block.
|
|
30606
30683
|
default: ""
|
|
30684
|
+
- name: skills
|
|
30685
|
+
type: string
|
|
30686
|
+
description: Instructions contributed by the skills enabled for this run.
|
|
30687
|
+
default: ""
|
|
30688
|
+
- name: memory
|
|
30689
|
+
type: string
|
|
30690
|
+
description: The index of notes saved to this run's memory plane.
|
|
30691
|
+
default: ""
|
|
30692
|
+
- name: run_context
|
|
30693
|
+
type: string
|
|
30694
|
+
description: Facts about THIS run the model cannot otherwise know \u2014 the date, and whatever the host adds (working directory, platform).
|
|
30695
|
+
default: ""
|
|
30607
30696
|
- name: app
|
|
30608
30697
|
type: string
|
|
30609
30698
|
description: Product name of the host application, used for the agent's own identity.
|
|
@@ -30611,13 +30700,22 @@ parameters:
|
|
|
30611
30700
|
---
|
|
30612
30701
|
{% if persona %}{{ persona }}
|
|
30613
30702
|
|
|
30614
|
-
{% endif %}You are the {{ app }} assistant. You help the user do real work
|
|
30703
|
+
{% endif %}You are the {{ app }} assistant. You help the user do real work: reading and changing files, composing and running prompts and workflows, and building software. Work from the context you were given below rather than assuming a particular screen.
|
|
30615
30704
|
|
|
30616
|
-
|
|
30705
|
+
Verify before you claim. Do not say something is done, fixed, passing or ready unless you checked it in this conversation and can point at what you checked. If you did not run it, say you did not run it. If a check failed, say so plainly and show what failed. A wrong claim of success costs the user far more than the check would have.
|
|
30617
30706
|
|
|
30618
30707
|
Say what you assumed and what you did not do. A request that leaves room for interpretation gets its decisions named, one line each, so the user can correct one without unpicking the rest. How much you decide for yourself versus ask about is the mode's call, below.
|
|
30619
30708
|
|
|
30620
|
-
|
|
30709
|
+
A tool call that comes back denied, blocked or unavailable is a decision, not a failure to route around. Do not retry it, do not reach for another tool to accomplish the same thing, and never describe the change as made. Say what you wanted to do and stop.
|
|
30710
|
+
|
|
30711
|
+
Prefer calling a tool over guessing: read the file rather than recalling it, run the command rather than predicting its output. Use the file tools to read and change files, and compile_prompd to preview rendered output. For a job with several steps, keep a visible task list with todo_write and mark each step as you finish it.
|
|
30712
|
+
|
|
30713
|
+
Be brief. Lead with the answer, then only what the user needs to act on or check it. Use headings, lists and tables where they carry something prose would not, and prose everywhere else. Do not restate the request back, do not narrate what you are about to do, and do not end by summarizing what the user has just read.
|
|
30714
|
+
|
|
30715
|
+
{% if run_context %}## This run
|
|
30716
|
+
{{ run_context }}
|
|
30717
|
+
|
|
30718
|
+
{% endif %}## Tools available this run
|
|
30621
30719
|
{{ tools }}
|
|
30622
30720
|
{% if tool_guidance %}
|
|
30623
30721
|
|
|
@@ -30628,6 +30726,14 @@ Say what you assumed and what you did not do. A request that leaves room for int
|
|
|
30628
30726
|
## Mode
|
|
30629
30727
|
{{ mode_hint }}
|
|
30630
30728
|
{% endif %}
|
|
30729
|
+
{% if skills %}
|
|
30730
|
+
|
|
30731
|
+
{{ skills }}
|
|
30732
|
+
{% endif %}
|
|
30733
|
+
{% if memory %}
|
|
30734
|
+
|
|
30735
|
+
{{ memory }}
|
|
30736
|
+
{% endif %}
|
|
30631
30737
|
{% if file_context %}
|
|
30632
30738
|
|
|
30633
30739
|
{{ file_context }}
|
|
@@ -42367,6 +42473,44 @@ function formatOffloadRef(ref) {
|
|
|
42367
42473
|
${ref.preview}${ref.bytes > ref.preview.length ? "\n\u2026(truncated)" : ""}` : head;
|
|
42368
42474
|
}
|
|
42369
42475
|
|
|
42476
|
+
// ../harness/core/contextPressure.ts
|
|
42477
|
+
var CONTEXT_MARKER = "[context] ";
|
|
42478
|
+
var PRESSURE_BANDS = [0.6, 0.8, 0.9];
|
|
42479
|
+
var PRESSURE_HYSTERESIS = 0.05;
|
|
42480
|
+
var initialPressureGate = { crossed: 0 };
|
|
42481
|
+
function highestBandAtOrBelow(fill, slack = 0) {
|
|
42482
|
+
let best = 0;
|
|
42483
|
+
for (const b2 of PRESSURE_BANDS) if (fill >= b2 - slack) best = b2;
|
|
42484
|
+
return best;
|
|
42485
|
+
}
|
|
42486
|
+
function pressureDecision(fill, gate) {
|
|
42487
|
+
const current2 = highestBandAtOrBelow(fill);
|
|
42488
|
+
if (current2 > gate.crossed) return { band: current2, next: { crossed: current2 } };
|
|
42489
|
+
const held = highestBandAtOrBelow(fill, PRESSURE_HYSTERESIS);
|
|
42490
|
+
return { band: null, next: { crossed: Math.min(gate.crossed, held) } };
|
|
42491
|
+
}
|
|
42492
|
+
function pressureMessage(band, fill) {
|
|
42493
|
+
const pct = Math.round(fill * 100);
|
|
42494
|
+
switch (band) {
|
|
42495
|
+
case 0.6:
|
|
42496
|
+
return `${CONTEXT_MARKER}Context is ${pct}% full. Read files in ranges rather than whole, summarize tool output rather than quoting it back, and stop re-reading things already in this conversation.`;
|
|
42497
|
+
case 0.8:
|
|
42498
|
+
return `${CONTEXT_MARKER}Context is ${pct}% full. Finish the task in progress and report it; start no new exploration, and open nothing large. If the work does not fit, say what is left rather than beginning it.`;
|
|
42499
|
+
case 0.9:
|
|
42500
|
+
return `${CONTEXT_MARKER}Context is ${pct}% full. Stop gathering and answer now with what you already have, naming what you did not get to. Further reading will be lost.`;
|
|
42501
|
+
}
|
|
42502
|
+
}
|
|
42503
|
+
function contextWindowLine(contextWindow) {
|
|
42504
|
+
if (!contextWindow || contextWindow <= 0) return "";
|
|
42505
|
+
return `Your context window is ${contextWindow.toLocaleString("en-US")} tokens. You will be told when it is filling up.`;
|
|
42506
|
+
}
|
|
42507
|
+
function isContextNote(m2) {
|
|
42508
|
+
return m2.role === "assistant" && typeof m2.content === "string" && m2.content.startsWith(CONTEXT_MARKER);
|
|
42509
|
+
}
|
|
42510
|
+
function contextNote(band, fill) {
|
|
42511
|
+
return { role: "assistant", content: pressureMessage(band, fill) };
|
|
42512
|
+
}
|
|
42513
|
+
|
|
42370
42514
|
// ../harness/core/compactHistory.ts
|
|
42371
42515
|
var CHECKPOINT_MARKER = "[checkpoint] ";
|
|
42372
42516
|
var ANCHOR_MARKER = "[anchor] ";
|
|
@@ -42416,11 +42560,11 @@ async function compactHistory(messages, opts) {
|
|
|
42416
42560
|
const pending = tail3 && isUnansweredToolCall(tail3) ? tail3 : null;
|
|
42417
42561
|
const body2 = pending ? messages.slice(0, -1) : messages;
|
|
42418
42562
|
const system = body2.filter((m2) => m2.role === "system");
|
|
42419
|
-
const collapsed = body2.filter((m2) => m2.role !== "system" && m2.role !== "user");
|
|
42563
|
+
const collapsed = body2.filter((m2) => m2.role !== "system" && m2.role !== "user" && !isContextNote(m2));
|
|
42420
42564
|
const kept = [];
|
|
42421
42565
|
let answered = null;
|
|
42422
42566
|
for (const m2 of body2) {
|
|
42423
|
-
if (isOwnMarker(m2)) continue;
|
|
42567
|
+
if (isOwnMarker(m2) || isContextNote(m2)) continue;
|
|
42424
42568
|
if (m2.role === "assistant" && typeof m2.content === "string") answered = m2;
|
|
42425
42569
|
if (m2.role !== "user") continue;
|
|
42426
42570
|
if (opts.anchor) {
|
|
@@ -42574,9 +42718,11 @@ async function runAgent(args) {
|
|
|
42574
42718
|
const ctxWindow = compression?.contextWindow;
|
|
42575
42719
|
const compressionStrategy = compression?.strategy ?? "eager";
|
|
42576
42720
|
let fill = 0;
|
|
42721
|
+
let pressureGate = initialPressureGate;
|
|
42577
42722
|
let compactGate = { armed: true, floor: null };
|
|
42578
42723
|
const deferredOffloads = [];
|
|
42579
|
-
const maxTurns = policy.maxTurns
|
|
42724
|
+
const maxTurns = policy.maxTurns !== void 0 ? policy.maxTurns : args.maxTurns !== void 0 ? args.maxTurns : 40;
|
|
42725
|
+
const unlimitedTurns = maxTurns === 0;
|
|
42580
42726
|
const signal = args.signal ?? new AbortController().signal;
|
|
42581
42727
|
const emit = (e2) => args.onEvent?.(e2);
|
|
42582
42728
|
const gstate = initialState();
|
|
@@ -42608,9 +42754,8 @@ async function runAgent(args) {
|
|
|
42608
42754
|
const capped = (list) => list.length > MAX_PROVIDER_TOOLS ? list.slice(0, MAX_PROVIDER_TOOLS) : list;
|
|
42609
42755
|
const activeTools = () => capped(loader ? [...eager, ...loader.loaded()] : eager);
|
|
42610
42756
|
let sent = activeTools();
|
|
42611
|
-
const
|
|
42612
|
-
|
|
42613
|
-
${serverIndex(deferred)}` : serverIndex(deferred) : system;
|
|
42757
|
+
const systemParts = [system, loader ? serverIndex(deferred) : "", contextWindowLine(ctxWindow)].filter(Boolean);
|
|
42758
|
+
const indexedSystem = systemParts.length ? systemParts.join("\n\n") : system;
|
|
42614
42759
|
const filledSystem = indexedSystem ? fillToolsMarker(indexedSystem, sent) : indexedSystem;
|
|
42615
42760
|
if (filledSystem && !messages.some((m2) => m2.role === "system")) {
|
|
42616
42761
|
messages.unshift({ role: "system", content: filledSystem });
|
|
@@ -42630,7 +42775,7 @@ ${serverIndex(deferred)}` : serverIndex(deferred) : system;
|
|
|
42630
42775
|
let stopReason = "stop";
|
|
42631
42776
|
let lastToolSig = null;
|
|
42632
42777
|
let lastStreamErr = "";
|
|
42633
|
-
for (let turn = 1; turn <= maxTurns; turn++) {
|
|
42778
|
+
for (let turn = 1; unlimitedTurns || turn <= maxTurns; turn++) {
|
|
42634
42779
|
if (signal.aborted) {
|
|
42635
42780
|
stopReason = "aborted";
|
|
42636
42781
|
break;
|
|
@@ -42668,13 +42813,28 @@ ${serverIndex(deferred)}` : serverIndex(deferred) : system;
|
|
|
42668
42813
|
alog("compaction failed", e2 instanceof Error ? e2.message : String(e2));
|
|
42669
42814
|
}
|
|
42670
42815
|
}
|
|
42671
|
-
|
|
42672
|
-
const
|
|
42673
|
-
|
|
42674
|
-
|
|
42675
|
-
|
|
42676
|
-
|
|
42677
|
-
|
|
42816
|
+
const pressureFill = fill || estimateFill(messages, ctxWindow);
|
|
42817
|
+
const pressure = pressureDecision(pressureFill, pressureGate);
|
|
42818
|
+
pressureGate = pressure.next;
|
|
42819
|
+
if (pressure.band !== null && ctxWindow) {
|
|
42820
|
+
messages.push(contextNote(pressure.band, pressureFill));
|
|
42821
|
+
emit({
|
|
42822
|
+
type: "context-pressure",
|
|
42823
|
+
band: pressure.band,
|
|
42824
|
+
fill: pressureFill,
|
|
42825
|
+
contextWindow: ctxWindow,
|
|
42826
|
+
promptTokens: Math.round(pressureFill * ctxWindow)
|
|
42827
|
+
});
|
|
42828
|
+
}
|
|
42829
|
+
if (!unlimitedTurns) {
|
|
42830
|
+
gstate.turn = turn - 1;
|
|
42831
|
+
const turnGate = evaluateTurnStart(policy, gstate);
|
|
42832
|
+
if (!turnGate.ok) {
|
|
42833
|
+
emit({ type: "policy-violation", kind: turnGate.violation.kind, message: turnGate.violation.message, action: turnGate.action, tool: turnGate.violation.tool });
|
|
42834
|
+
if (turnGate.action === "stop") {
|
|
42835
|
+
stopReason = "policy";
|
|
42836
|
+
break;
|
|
42837
|
+
}
|
|
42678
42838
|
}
|
|
42679
42839
|
}
|
|
42680
42840
|
if (loader) {
|
|
@@ -42892,7 +43052,7 @@ ${serverIndex(deferred)}` : serverIndex(deferred) : system;
|
|
|
42892
43052
|
stopReason = "policy";
|
|
42893
43053
|
break;
|
|
42894
43054
|
}
|
|
42895
|
-
if (turn === maxTurns) stopReason = "max_turns";
|
|
43055
|
+
if (!unlimitedTurns && turn === maxTurns) stopReason = "max_turns";
|
|
42896
43056
|
}
|
|
42897
43057
|
reconcileDanglingToolCalls(messages);
|
|
42898
43058
|
for (const v2 of evaluateCompletion(policy, gstate)) {
|
|
@@ -43347,30 +43507,43 @@ function pricedForUsd(rates) {
|
|
|
43347
43507
|
if (!rates) return false;
|
|
43348
43508
|
return rates.inPrice > 0 || rates.outPrice > 0;
|
|
43349
43509
|
}
|
|
43350
|
-
async function
|
|
43351
|
-
const table = /* @__PURE__ */ new Map();
|
|
43510
|
+
async function fetchAvailableModels(endpoint, getToken, fetchImpl) {
|
|
43352
43511
|
let token = null;
|
|
43353
43512
|
try {
|
|
43354
43513
|
token = await getToken();
|
|
43355
43514
|
} catch {
|
|
43356
43515
|
token = null;
|
|
43357
43516
|
}
|
|
43358
|
-
if (!token) return
|
|
43517
|
+
if (!token) return [];
|
|
43359
43518
|
try {
|
|
43360
43519
|
const res = await fetchImpl(`${endpoint.replace(/\/$/, "")}/llm-providers/available`, {
|
|
43361
43520
|
headers: { Authorization: `Bearer ${token}` }
|
|
43362
43521
|
});
|
|
43363
|
-
if (!res.ok) return
|
|
43522
|
+
if (!res.ok) return [];
|
|
43364
43523
|
const json = await res.json();
|
|
43365
|
-
|
|
43366
|
-
|
|
43367
|
-
|
|
43368
|
-
table.set(m2.model, { inPrice: m2.inputPrice, outPrice: m2.outputPrice });
|
|
43369
|
-
}
|
|
43370
|
-
}
|
|
43524
|
+
const out = [];
|
|
43525
|
+
for (const p2 of json.providers ?? []) out.push(...p2.models ?? []);
|
|
43526
|
+
return out;
|
|
43371
43527
|
} catch {
|
|
43528
|
+
return [];
|
|
43372
43529
|
}
|
|
43373
|
-
|
|
43530
|
+
}
|
|
43531
|
+
async function hydrateCatalog(endpoint, getToken, fetchImpl = fetch) {
|
|
43532
|
+
const prices = /* @__PURE__ */ new Map();
|
|
43533
|
+
const windows = /* @__PURE__ */ new Map();
|
|
43534
|
+
const models = await fetchAvailableModels(endpoint, getToken, fetchImpl);
|
|
43535
|
+
for (const m2 of models) {
|
|
43536
|
+
if (m2.inputPrice != null && m2.outputPrice != null) {
|
|
43537
|
+
prices.set(m2.model, { inPrice: m2.inputPrice, outPrice: m2.outputPrice });
|
|
43538
|
+
}
|
|
43539
|
+
if (typeof m2.contextWindow === "number" && m2.contextWindow > 0) {
|
|
43540
|
+
windows.set(m2.model, m2.contextWindow);
|
|
43541
|
+
}
|
|
43542
|
+
}
|
|
43543
|
+
return { prices, windows };
|
|
43544
|
+
}
|
|
43545
|
+
async function hydratePrices(endpoint, getToken, fetchImpl = fetch) {
|
|
43546
|
+
return (await hydrateCatalog(endpoint, getToken, fetchImpl)).prices;
|
|
43374
43547
|
}
|
|
43375
43548
|
|
|
43376
43549
|
// src/runner/permissionMessage.ts
|
|
@@ -47206,7 +47379,7 @@ var FLAG_TO_KEY = {
|
|
|
47206
47379
|
"--default-model": "defaultModel",
|
|
47207
47380
|
"--name": "name"
|
|
47208
47381
|
};
|
|
47209
|
-
var DEFAULT_GUEST_IMAGE2 = "prompd/corenel-sandbox:0.
|
|
47382
|
+
var DEFAULT_GUEST_IMAGE2 = "prompd/corenel-sandbox:0.9.0";
|
|
47210
47383
|
function parseArgsWithProvenance(argv) {
|
|
47211
47384
|
const explicit = /* @__PURE__ */ new Set();
|
|
47212
47385
|
for (const a2 of argv) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corenel/sidecar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Elastic-2.0",
|
|
6
6
|
"description": "Prompd sidecar — a local capability server. Run it next to Prompd (prompd.app) so the browser app can reach your machine: local LLMs (Ollama/LM Studio/vLLM) without CORS, your filesystem, and (opt-in) shell.",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"esbuild": "^0.21.5",
|
|
37
37
|
"tsx": "^4.19.2",
|
|
38
38
|
"typescript": "^5.9.3",
|
|
39
|
-
"@corenel/config": "0.
|
|
40
|
-
"@corenel/
|
|
41
|
-
"@corenel/
|
|
42
|
-
"@corenel/
|
|
43
|
-
"@corenel/harness": "0.
|
|
39
|
+
"@corenel/config": "0.2.0",
|
|
40
|
+
"@corenel/protocol": "0.8.0",
|
|
41
|
+
"@corenel/tools-node": "0.5.0",
|
|
42
|
+
"@corenel/mcp": "0.2.0",
|
|
43
|
+
"@corenel/harness": "0.9.0",
|
|
44
44
|
"@corenel/crew": "0.0.0"
|
|
45
45
|
},
|
|
46
46
|
"repository": {
|