@ouro.bot/cli 0.1.0-alpha.985 → 0.1.0-alpha.986

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/changelog.json CHANGED
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.986",
6
+ "changes": [
7
+ "A huge tool result (a glob over a whole folder, a long log) no longer overflows the agent's context and kills the turn: the model sees its start and end with a line saying how big it was and how to narrow it."
8
+ ]
9
+ },
4
10
  {
5
11
  "version": "0.1.0-alpha.985",
6
12
  "changes": [
@@ -1,5 +1,5 @@
1
1
  {
2
- "runtimeVersion": "0.1.0-alpha.985",
2
+ "runtimeVersion": "0.1.0-alpha.986",
3
3
  "bundleSchemaVersion": 3,
4
4
  "lastUpdated": "2026-09-03T00:00:00.000Z"
5
5
  }
@@ -1,7 +1,7 @@
1
1
  <?xml version="1.0"?>
2
2
  <Container version="2">
3
3
  <Name>ouro-butler</Name>
4
- <Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.985</Repository>
4
+ <Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.986</Repository>
5
5
  <Registry>https://github.com/ourostack/ouroboros/pkgs/container/ouroboros-butler</Registry>
6
6
  <Network>host</Network>
7
7
  <Shell>sh</Shell>
@@ -63,6 +63,7 @@ const obligations_1 = require("../arc/obligations");
63
63
  const tool_loop_1 = require("./tool-loop");
64
64
  const packets_1 = require("../arc/packets");
65
65
  const tool_friction_1 = require("./tool-friction");
66
+ const tool_output_budget_1 = require("./tool-output-budget");
66
67
  const delegated_command_1 = require("../a2a/delegated-command");
67
68
  const provider_models_1 = require("./provider-models");
68
69
  const provider_credentials_1 = require("./provider-credentials");
@@ -2606,7 +2607,7 @@ async function runAgent(messages, callbacks, channel, signal, options) {
2606
2607
  if (invoked && requiredToolCallNames.includes(tc.name) && !options?.requiredToolCalls?.requireSuccessfulResults)
2607
2608
  dispatchedRequiredToolCalls.add(tc.name);
2608
2609
  turnToolRecords.push({ name: tc.name, args, result: toolResult });
2609
- const modelResult = (0, delegated_command_1.shieldDelegatedBanner)((0, tool_friction_1.rewriteToolResultForModel)(tc.name, toolResult, toolFrictionLedger));
2610
+ const modelResult = (0, delegated_command_1.shieldDelegatedBanner)((0, tool_output_budget_1.fitToolOutputForModel)(tc.name, (0, tool_friction_1.rewriteToolResultForModel)(tc.name, toolResult, toolFrictionLedger)));
2610
2611
  pushGenerated({ role: "tool", tool_call_id: tc.id, content: modelResult });
2611
2612
  providerRuntime.appendToolOutput(tc.id, modelResult);
2612
2613
  if (!success)
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TOOL_OUTPUT_MAX_CHARS = void 0;
4
+ exports.fitToolOutputForModel = fitToolOutputForModel;
5
+ const runtime_1 = require("../nerves/runtime");
6
+ /** The most characters one tool result may put in front of the model (about 8k tokens). */
7
+ exports.TOOL_OUTPUT_MAX_CHARS = 32_000;
8
+ const HEAD_SHARE = 0.75;
9
+ /** Cut to the last line break at or before `limit`, or to `limit` when the text has none there. */
10
+ function headWithin(text, limit) {
11
+ const head = text.slice(0, limit);
12
+ const lastBreak = head.lastIndexOf("\n");
13
+ return lastBreak > 0 ? head.slice(0, lastBreak) : head;
14
+ }
15
+ /** Keep the last `limit` characters, starting after a line break when there is one. */
16
+ function tailWithin(text, limit) {
17
+ const tail = text.slice(text.length - limit);
18
+ const firstBreak = tail.indexOf("\n");
19
+ return firstBreak >= 0 ? tail.slice(firstBreak + 1) : tail;
20
+ }
21
+ /**
22
+ * Fit one tool result into the model's view. Output within the budget is returned unchanged.
23
+ * Larger output keeps its start and its end, on line boundaries, around one line that says how
24
+ * big the whole result was and how to see the rest, so a huge listing or log never overflows
25
+ * the context window and kills the turn.
26
+ */
27
+ function fitToolOutputForModel(tool, text) {
28
+ if (text.length <= exports.TOOL_OUTPUT_MAX_CHARS)
29
+ return text;
30
+ const head = headWithin(text, Math.floor(exports.TOOL_OUTPUT_MAX_CHARS * HEAD_SHARE));
31
+ const tail = tailWithin(text, exports.TOOL_OUTPUT_MAX_CHARS - head.length);
32
+ const omitted = text.length - head.length - tail.length;
33
+ (0, runtime_1.emitNervesEvent)({
34
+ component: "engine",
35
+ event: "engine.tool_output_fitted",
36
+ message: "tool output fitted to the model's budget",
37
+ meta: { tool, totalChars: text.length, omittedChars: omitted },
38
+ });
39
+ const notice = `[${tool} returned ${text.length.toLocaleString("en-US")} characters; the middle ${omitted.toLocaleString("en-US")} are not shown. To see them, narrow the request: a tighter pattern or folder, a line range, or a filter such as head, tail or grep.]`;
40
+ return `${head}\n${notice}\n${tail}`;
41
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.985",
3
+ "version": "0.1.0-alpha.986",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@ouro.bot/cli",
9
- "version": "0.1.0-alpha.985",
9
+ "version": "0.1.0-alpha.986",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.78.0",
12
12
  "@azure/identity": "^4.13.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.985",
3
+ "version": "0.1.0-alpha.986",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },