@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.
Files changed (2) hide show
  1. package/dist/cli.js +213 -40
  2. 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 preview = processedContent.substring(0, 50).replace(/\n/g, "\\n");
17295
- console.log(`[include] Loaded ${ext} file: ${filePath} (${preview}...)`);
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 preview = blockContent.substring(0, 50).replace(/\n/g, "\\n");
17918
- console.log(` - Removing \`\`\`${lang} block: "${preview}..."`);
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: 8,
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: 8,
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
- maxTurns: 16,
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
- await ctx.kv.set(key, str4(args, "value"));
30105
- return `Set ${key}.`;
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 in {{ app }}: reading and changing files, composing and running prompts and workflows, and building software. What is in front of you differs by surface \u2014 an open file, a workflow canvas, a workspace, or nothing but this conversation \u2014 so work from the context you were actually given rather than assuming a particular screen.
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
- To read or change files in the workspace, use the file tools; writes ask the user for permission first. Use compile_prompd to preview rendered output and search_packages to find registry packages. For any multi-step job, maintain a visible task list with todo_write: lay out the steps, keep one task in_progress, and mark each completed as you go. Prefer calling a tool over guessing, and be concise.
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
- ## Tools available this run
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 ?? args.maxTurns ?? 8;
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 indexedSystem = loader ? system ? `${system}
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
- gstate.turn = turn - 1;
42672
- const turnGate = evaluateTurnStart(policy, gstate);
42673
- if (!turnGate.ok) {
42674
- emit({ type: "policy-violation", kind: turnGate.violation.kind, message: turnGate.violation.message, action: turnGate.action, tool: turnGate.violation.tool });
42675
- if (turnGate.action === "stop") {
42676
- stopReason = "policy";
42677
- break;
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 hydratePrices(endpoint, getToken, fetchImpl = fetch) {
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 table;
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 table;
43522
+ if (!res.ok) return [];
43364
43523
  const json = await res.json();
43365
- for (const p2 of json.providers ?? []) {
43366
- for (const m2 of p2.models ?? []) {
43367
- if (m2.inputPrice == null || m2.outputPrice == null) continue;
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
- return table;
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.8.8";
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.8.8",
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.1.0",
40
- "@corenel/mcp": "0.1.0",
41
- "@corenel/protocol": "0.7.3",
42
- "@corenel/tools-node": "0.4.0",
43
- "@corenel/harness": "0.8.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": {