@opencow-ai/opencow-agent-sdk 0.4.8 → 0.4.10

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.mjs CHANGED
@@ -85609,6 +85609,32 @@ function buildOpenAIRequestBody(params, ctx) {
85609
85609
  }
85610
85610
  return body;
85611
85611
  }
85612
+ function normalizeDsmlSentinelPrefix(value) {
85613
+ return value.replace(/|/g, "|").replace(/\s+/g, "");
85614
+ }
85615
+ function isDsmlFunctionCallSentinelPrefix(value) {
85616
+ const normalized = normalizeDsmlSentinelPrefix(value);
85617
+ return normalized.length > 0 && DSML_FUNCTION_CALL_SENTINEL.startsWith(normalized);
85618
+ }
85619
+ function findTrailingDsmlSentinelCandidateStart(text) {
85620
+ const lt = text.lastIndexOf("<");
85621
+ if (lt === -1)
85622
+ return null;
85623
+ return isDsmlFunctionCallSentinelPrefix(text.slice(lt)) ? lt : null;
85624
+ }
85625
+ function findBufferedTextFlushBoundary(text) {
85626
+ const sentinelStart = findTrailingDsmlSentinelCandidateStart(text);
85627
+ if (sentinelStart === null)
85628
+ return text.length;
85629
+ return text.slice(0, sentinelStart).trimEnd().length;
85630
+ }
85631
+ function findDsmlFunctionCallSentinel(text) {
85632
+ const re = /<\s*[||]\s*DSML\s*[||]\s*function_calls\b/;
85633
+ const match = re.exec(text);
85634
+ if (!match || match.index === undefined)
85635
+ return null;
85636
+ return { start: match.index, end: match.index + match[0].length };
85637
+ }
85612
85638
  async function* openaiStreamToAnthropic(response, model) {
85613
85639
  const messageId = makeMessageId2();
85614
85640
  let contentBlockIndex = 0;
@@ -85619,6 +85645,50 @@ async function* openaiStreamToAnthropic(response, model) {
85619
85645
  let lastStopReason = null;
85620
85646
  let hasEmittedFinalUsage = false;
85621
85647
  let hasProcessedFinishReason = false;
85648
+ let pendingTextBuffer = "";
85649
+ const emitBufferedText = (mode) => {
85650
+ const events = [];
85651
+ if (!pendingTextBuffer)
85652
+ return events;
85653
+ const sentinel = findDsmlFunctionCallSentinel(pendingTextBuffer);
85654
+ if (sentinel) {
85655
+ const visible2 = pendingTextBuffer.slice(0, sentinel.start).trimEnd();
85656
+ pendingTextBuffer = pendingTextBuffer.slice(sentinel.end);
85657
+ if (visible2) {
85658
+ events.push(...emitTextDeltaEvents(visible2));
85659
+ }
85660
+ if (pendingTextBuffer) {
85661
+ events.push(...emitBufferedText(mode));
85662
+ }
85663
+ return events;
85664
+ }
85665
+ const emitUntil = mode === "final" ? pendingTextBuffer.length : mode === "before_tool_call" ? findTrailingDsmlSentinelCandidateStart(pendingTextBuffer) ?? pendingTextBuffer.length : findBufferedTextFlushBoundary(pendingTextBuffer);
85666
+ if (emitUntil <= 0)
85667
+ return events;
85668
+ const visible = pendingTextBuffer.slice(0, emitUntil);
85669
+ pendingTextBuffer = pendingTextBuffer.slice(emitUntil);
85670
+ if (visible) {
85671
+ events.push(...emitTextDeltaEvents(visible));
85672
+ }
85673
+ return events;
85674
+ };
85675
+ const emitTextDeltaEvents = (text) => {
85676
+ const events = [];
85677
+ if (!hasEmittedContentStart) {
85678
+ events.push({
85679
+ type: "content_block_start",
85680
+ index: contentBlockIndex,
85681
+ content_block: { type: "text", text: "" }
85682
+ });
85683
+ hasEmittedContentStart = true;
85684
+ }
85685
+ events.push({
85686
+ type: "content_block_delta",
85687
+ index: contentBlockIndex,
85688
+ delta: { type: "text_delta", text }
85689
+ });
85690
+ return events;
85691
+ };
85622
85692
  yield {
85623
85693
  type: "message_start",
85624
85694
  message: {
@@ -85726,21 +85796,13 @@ async function* openaiStreamToAnthropic(response, model) {
85726
85796
  hasClosedReasoning = true;
85727
85797
  }
85728
85798
  if (delta.content != null) {
85729
- if (!hasEmittedContentStart) {
85730
- yield {
85731
- type: "content_block_start",
85732
- index: contentBlockIndex,
85733
- content_block: { type: "text", text: "" }
85734
- };
85735
- hasEmittedContentStart = true;
85736
- }
85737
- yield {
85738
- type: "content_block_delta",
85739
- index: contentBlockIndex,
85740
- delta: { type: "text_delta", text: delta.content }
85741
- };
85799
+ pendingTextBuffer += delta.content;
85800
+ for (const event of emitBufferedText("streaming"))
85801
+ yield event;
85742
85802
  }
85743
85803
  if (delta.tool_calls) {
85804
+ for (const event of emitBufferedText("before_tool_call"))
85805
+ yield event;
85744
85806
  for (const tc of delta.tool_calls) {
85745
85807
  if (tc.id && tc.function?.name) {
85746
85808
  if (hasEmittedContentStart) {
@@ -85807,6 +85869,8 @@ async function* openaiStreamToAnthropic(response, model) {
85807
85869
  };
85808
85870
  hasClosedReasoning = true;
85809
85871
  }
85872
+ for (const event of emitBufferedText("final"))
85873
+ yield event;
85810
85874
  if (hasEmittedContentStart) {
85811
85875
  yield {
85812
85876
  type: "content_block_stop",
@@ -86179,7 +86243,7 @@ function createOpenAIShimClient(options) {
86179
86243
  messages: beta.messages
86180
86244
  };
86181
86245
  }
86182
- var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, OpenAIShimStream;
86246
+ var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, DSML_FUNCTION_CALL_SENTINEL = "<|DSML|function_calls", OpenAIShimStream;
86183
86247
  var init_shim2 = __esm(() => {
86184
86248
  init_sdk();
86185
86249
  init_envUtils();
@@ -94436,7 +94500,7 @@ function printStartupScreen() {
94436
94500
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
94437
94501
  out.push(boxRow(sRow, W2, sLen));
94438
94502
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W2 - 2)}╝${RESET}`);
94439
- out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.8"}${RESET}`);
94503
+ out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.10"}${RESET}`);
94440
94504
  out.push("");
94441
94505
  process.stdout.write(out.join(`
94442
94506
  `) + `
@@ -244306,7 +244370,7 @@ function getAnthropicEnvMetadata() {
244306
244370
  function getBuildAgeMinutes() {
244307
244371
  if (false)
244308
244372
  ;
244309
- const buildTime = new Date("2026-06-20T04:27:50.766Z").getTime();
244373
+ const buildTime = new Date("2026-06-23T14:32:49.206Z").getTime();
244310
244374
  if (isNaN(buildTime))
244311
244375
  return;
244312
244376
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -277643,11 +277707,14 @@ ${stderr}` : stdout;
277643
277707
  }
277644
277708
  } while (!generatorResult.done);
277645
277709
  result = generatorResult.value;
277646
- trackGitOperations(input.command, result.code, result.stdout);
277710
+ const stdout2 = result.stdout || "";
277711
+ const stderr = result.stderr || "";
277712
+ const combinedOutput = [stdout2, stderr].filter(Boolean).join(stdout2 && stderr ? EOL : "");
277713
+ trackGitOperations(input.command, result.code, combinedOutput);
277647
277714
  const isInterrupt = result.interrupted && abortController.signal.reason === "interrupt";
277648
- stdoutAccumulator.append((result.stdout || "").trimEnd() + EOL);
277649
- interpretationResult = interpretCommandResult(input.command, result.code, result.stdout || "", "");
277650
- if (result.stdout && result.stdout.includes(".git/index.lock': File exists")) {
277715
+ stdoutAccumulator.append(combinedOutput.trimEnd() + EOL);
277716
+ interpretationResult = interpretCommandResult(input.command, result.code, stdout2, stderr);
277717
+ if (combinedOutput.includes(".git/index.lock': File exists")) {
277651
277718
  logEvent("tengu_git_index_lock_error", {});
277652
277719
  }
277653
277720
  if (interpretationResult.isError && !isInterrupt) {
@@ -277661,7 +277728,8 @@ ${stderr}` : stdout;
277661
277728
  stderrForShellReset = stdErrAppendShellResetMessage("");
277662
277729
  }
277663
277730
  }
277664
- const outputWithSbFailures = SandboxManager4.annotateStderrWithSandboxFailures(input.command, result.stdout || "");
277731
+ const annotatedOutput = SandboxManager4.annotateStderrWithSandboxFailures(input.command, combinedOutput);
277732
+ const outputWithSbFailures = annotatedOutput || combinedOutput;
277665
277733
  if (result.preSpawnError) {
277666
277734
  throw new Error(result.preSpawnError);
277667
277735
  }
@@ -319222,6 +319290,7 @@ class ShellCommandImpl {
319222
319290
  #shouldAutoBackground;
319223
319291
  #resultResolver = null;
319224
319292
  #exitCodeResolver = null;
319293
+ #stdioClosedPromise = null;
319225
319294
  #boundAbortHandler = null;
319226
319295
  taskOutput;
319227
319296
  static #handleTimeout(self2) {
@@ -319309,6 +319378,11 @@ class ShellCommandImpl {
319309
319378
  });
319310
319379
  this.#childProcess.once("exit", this.#exitHandler.bind(this));
319311
319380
  this.#childProcess.once("error", this.#errorHandler.bind(this));
319381
+ this.#stdioClosedPromise = new Promise((resolve34) => {
319382
+ this.#childProcess.once("close", () => {
319383
+ resolve34();
319384
+ });
319385
+ });
319312
319386
  this.#timeoutId = setTimeout(ShellCommandImpl.#handleTimeout, this.#timeout, this);
319313
319387
  const exitPromise = new Promise((resolve34) => {
319314
319388
  this.#exitCodeResolver = resolve34;
@@ -319323,6 +319397,9 @@ class ShellCommandImpl {
319323
319397
  if (this.#status === "running" || this.#status === "backgrounded") {
319324
319398
  this.#status = "completed";
319325
319399
  }
319400
+ if (this.taskOutput.stdoutToFile && !this.#backgroundTaskId) {
319401
+ await this.#waitForFileOutputFlush(code);
319402
+ }
319326
319403
  const stdout = await this.taskOutput.getStdout();
319327
319404
  const result = {
319328
319405
  code,
@@ -319351,6 +319428,20 @@ class ShellCommandImpl {
319351
319428
  resultResolver(result);
319352
319429
  }
319353
319430
  }
319431
+ async#waitForFileOutputFlush(code) {
319432
+ const stdioClosedPromise = this.#stdioClosedPromise;
319433
+ if (!stdioClosedPromise) {
319434
+ return;
319435
+ }
319436
+ const graceMs = code === 0 ? OUTPUT_CLOSE_GRACE_MS : ERROR_OUTPUT_CLOSE_GRACE_MS;
319437
+ await Promise.race([
319438
+ stdioClosedPromise,
319439
+ new Promise((resolve34) => {
319440
+ const timeout = setTimeout(resolve34, graceMs);
319441
+ timeout.unref();
319442
+ })
319443
+ ]);
319444
+ }
319354
319445
  #doKill(code) {
319355
319446
  this.#status = "killed";
319356
319447
  if (this.#childProcess.pid) {
@@ -319434,7 +319525,7 @@ function createFailedCommand(preSpawnError) {
319434
319525
  cleanup() {}
319435
319526
  };
319436
319527
  }
319437
- var import_tree_kill, SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000;
319528
+ var import_tree_kill, SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000, OUTPUT_CLOSE_GRACE_MS = 100, ERROR_OUTPUT_CLOSE_GRACE_MS = 1000;
319438
319529
  var init_ShellCommand = __esm(() => {
319439
319530
  init_Task();
319440
319531
  init_format2();
@@ -479642,7 +479733,7 @@ function buildPrimarySection() {
479642
479733
  }, undefined, false, undefined, this);
479643
479734
  return [{
479644
479735
  label: "Version",
479645
- value: "0.4.8"
479736
+ value: "0.4.10"
479646
479737
  }, {
479647
479738
  label: "Session name",
479648
479739
  value: nameValue
@@ -535964,7 +536055,7 @@ var init_bridge_kick = __esm(() => {
535964
536055
  var call58 = async () => {
535965
536056
  return {
535966
536057
  type: "text",
535967
- value: `${"99.0.0"} (built ${"2026-06-20T04:27:50.766Z"})`
536058
+ value: `${"99.0.0"} (built ${"2026-06-23T14:32:49.206Z"})`
535968
536059
  };
535969
536060
  }, version2, version_default;
535970
536061
  var init_version = __esm(() => {
@@ -558074,7 +558165,7 @@ function WelcomeV2() {
558074
558165
  dimColor: true,
558075
558166
  children: [
558076
558167
  "v",
558077
- "0.4.8",
558168
+ "0.4.10",
558078
558169
  " "
558079
558170
  ]
558080
558171
  }, undefined, true, undefined, this)
@@ -558274,7 +558365,7 @@ function WelcomeV2() {
558274
558365
  dimColor: true,
558275
558366
  children: [
558276
558367
  "v",
558277
- "0.4.8",
558368
+ "0.4.10",
558278
558369
  " "
558279
558370
  ]
558280
558371
  }, undefined, true, undefined, this)
@@ -558500,7 +558591,7 @@ function AppleTerminalWelcomeV2(t0) {
558500
558591
  dimColor: true,
558501
558592
  children: [
558502
558593
  "v",
558503
- "0.4.8",
558594
+ "0.4.10",
558504
558595
  " "
558505
558596
  ]
558506
558597
  }, undefined, true, undefined, this);
@@ -558754,7 +558845,7 @@ function AppleTerminalWelcomeV2(t0) {
558754
558845
  dimColor: true,
558755
558846
  children: [
558756
558847
  "v",
558757
- "0.4.8",
558848
+ "0.4.10",
558758
558849
  " "
558759
558850
  ]
558760
558851
  }, undefined, true, undefined, this);
@@ -579611,7 +579702,7 @@ Usage: claude --remote "your task description"`, () => gracefulShutdown(1));
579611
579702
  pendingHookMessages
579612
579703
  }, renderAndRun);
579613
579704
  }
579614
- }).version("0.4.8 (OpenCow)", "-v, --version", "Output the version number");
579705
+ }).version("0.4.10 (OpenCow)", "-v, --version", "Output the version number");
579615
579706
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
579616
579707
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
579617
579708
  if (canUserConfigureAdvisor()) {
@@ -580257,7 +580348,7 @@ if (false) {}
580257
580348
  async function main2() {
580258
580349
  const args = process.argv.slice(2);
580259
580350
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
580260
- console.log(`${"0.4.8"} (OpenCow)`);
580351
+ console.log(`${"0.4.10"} (OpenCow)`);
580261
580352
  return;
580262
580353
  }
580263
580354
  if (args.includes("--provider")) {
@@ -580375,4 +580466,4 @@ async function main2() {
580375
580466
  }
580376
580467
  main2();
580377
580468
 
580378
- //# debugId=1F12E9ABEA6E5ED964756E2164756E21
580469
+ //# debugId=10DA61343644BBA264756E2164756E21
package/dist/client.js CHANGED
@@ -96433,6 +96433,32 @@ function buildOpenAIRequestBody(params, ctx) {
96433
96433
  }
96434
96434
  return body;
96435
96435
  }
96436
+ function normalizeDsmlSentinelPrefix(value) {
96437
+ return value.replace(/|/g, "|").replace(/\s+/g, "");
96438
+ }
96439
+ function isDsmlFunctionCallSentinelPrefix(value) {
96440
+ const normalized = normalizeDsmlSentinelPrefix(value);
96441
+ return normalized.length > 0 && DSML_FUNCTION_CALL_SENTINEL.startsWith(normalized);
96442
+ }
96443
+ function findTrailingDsmlSentinelCandidateStart(text) {
96444
+ const lt = text.lastIndexOf("<");
96445
+ if (lt === -1)
96446
+ return null;
96447
+ return isDsmlFunctionCallSentinelPrefix(text.slice(lt)) ? lt : null;
96448
+ }
96449
+ function findBufferedTextFlushBoundary(text) {
96450
+ const sentinelStart = findTrailingDsmlSentinelCandidateStart(text);
96451
+ if (sentinelStart === null)
96452
+ return text.length;
96453
+ return text.slice(0, sentinelStart).trimEnd().length;
96454
+ }
96455
+ function findDsmlFunctionCallSentinel(text) {
96456
+ const re = /<\s*[||]\s*DSML\s*[||]\s*function_calls\b/;
96457
+ const match = re.exec(text);
96458
+ if (!match || match.index === undefined)
96459
+ return null;
96460
+ return { start: match.index, end: match.index + match[0].length };
96461
+ }
96436
96462
  async function* openaiStreamToAnthropic(response, model) {
96437
96463
  const messageId = makeMessageId2();
96438
96464
  let contentBlockIndex = 0;
@@ -96443,6 +96469,50 @@ async function* openaiStreamToAnthropic(response, model) {
96443
96469
  let lastStopReason = null;
96444
96470
  let hasEmittedFinalUsage = false;
96445
96471
  let hasProcessedFinishReason = false;
96472
+ let pendingTextBuffer = "";
96473
+ const emitBufferedText = (mode) => {
96474
+ const events = [];
96475
+ if (!pendingTextBuffer)
96476
+ return events;
96477
+ const sentinel = findDsmlFunctionCallSentinel(pendingTextBuffer);
96478
+ if (sentinel) {
96479
+ const visible2 = pendingTextBuffer.slice(0, sentinel.start).trimEnd();
96480
+ pendingTextBuffer = pendingTextBuffer.slice(sentinel.end);
96481
+ if (visible2) {
96482
+ events.push(...emitTextDeltaEvents(visible2));
96483
+ }
96484
+ if (pendingTextBuffer) {
96485
+ events.push(...emitBufferedText(mode));
96486
+ }
96487
+ return events;
96488
+ }
96489
+ const emitUntil = mode === "final" ? pendingTextBuffer.length : mode === "before_tool_call" ? findTrailingDsmlSentinelCandidateStart(pendingTextBuffer) ?? pendingTextBuffer.length : findBufferedTextFlushBoundary(pendingTextBuffer);
96490
+ if (emitUntil <= 0)
96491
+ return events;
96492
+ const visible = pendingTextBuffer.slice(0, emitUntil);
96493
+ pendingTextBuffer = pendingTextBuffer.slice(emitUntil);
96494
+ if (visible) {
96495
+ events.push(...emitTextDeltaEvents(visible));
96496
+ }
96497
+ return events;
96498
+ };
96499
+ const emitTextDeltaEvents = (text) => {
96500
+ const events = [];
96501
+ if (!hasEmittedContentStart) {
96502
+ events.push({
96503
+ type: "content_block_start",
96504
+ index: contentBlockIndex,
96505
+ content_block: { type: "text", text: "" }
96506
+ });
96507
+ hasEmittedContentStart = true;
96508
+ }
96509
+ events.push({
96510
+ type: "content_block_delta",
96511
+ index: contentBlockIndex,
96512
+ delta: { type: "text_delta", text }
96513
+ });
96514
+ return events;
96515
+ };
96446
96516
  yield {
96447
96517
  type: "message_start",
96448
96518
  message: {
@@ -96550,21 +96620,13 @@ async function* openaiStreamToAnthropic(response, model) {
96550
96620
  hasClosedReasoning = true;
96551
96621
  }
96552
96622
  if (delta.content != null) {
96553
- if (!hasEmittedContentStart) {
96554
- yield {
96555
- type: "content_block_start",
96556
- index: contentBlockIndex,
96557
- content_block: { type: "text", text: "" }
96558
- };
96559
- hasEmittedContentStart = true;
96560
- }
96561
- yield {
96562
- type: "content_block_delta",
96563
- index: contentBlockIndex,
96564
- delta: { type: "text_delta", text: delta.content }
96565
- };
96623
+ pendingTextBuffer += delta.content;
96624
+ for (const event of emitBufferedText("streaming"))
96625
+ yield event;
96566
96626
  }
96567
96627
  if (delta.tool_calls) {
96628
+ for (const event of emitBufferedText("before_tool_call"))
96629
+ yield event;
96568
96630
  for (const tc of delta.tool_calls) {
96569
96631
  if (tc.id && tc.function?.name) {
96570
96632
  if (hasEmittedContentStart) {
@@ -96631,6 +96693,8 @@ async function* openaiStreamToAnthropic(response, model) {
96631
96693
  };
96632
96694
  hasClosedReasoning = true;
96633
96695
  }
96696
+ for (const event of emitBufferedText("final"))
96697
+ yield event;
96634
96698
  if (hasEmittedContentStart) {
96635
96699
  yield {
96636
96700
  type: "content_block_stop",
@@ -97003,7 +97067,7 @@ function createOpenAIShimClient(options) {
97003
97067
  messages: beta.messages
97004
97068
  };
97005
97069
  }
97006
- var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, OpenAIShimStream;
97070
+ var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, DSML_FUNCTION_CALL_SENTINEL = "<|DSML|function_calls", OpenAIShimStream;
97007
97071
  var init_shim2 = __esm(() => {
97008
97072
  init_sdk();
97009
97073
  init_envUtils();
@@ -116633,6 +116697,7 @@ class ShellCommandImpl {
116633
116697
  #shouldAutoBackground;
116634
116698
  #resultResolver = null;
116635
116699
  #exitCodeResolver = null;
116700
+ #stdioClosedPromise = null;
116636
116701
  #boundAbortHandler = null;
116637
116702
  taskOutput;
116638
116703
  static #handleTimeout(self2) {
@@ -116720,6 +116785,11 @@ class ShellCommandImpl {
116720
116785
  });
116721
116786
  this.#childProcess.once("exit", this.#exitHandler.bind(this));
116722
116787
  this.#childProcess.once("error", this.#errorHandler.bind(this));
116788
+ this.#stdioClosedPromise = new Promise((resolve10) => {
116789
+ this.#childProcess.once("close", () => {
116790
+ resolve10();
116791
+ });
116792
+ });
116723
116793
  this.#timeoutId = setTimeout(ShellCommandImpl.#handleTimeout, this.#timeout, this);
116724
116794
  const exitPromise = new Promise((resolve10) => {
116725
116795
  this.#exitCodeResolver = resolve10;
@@ -116734,6 +116804,9 @@ class ShellCommandImpl {
116734
116804
  if (this.#status === "running" || this.#status === "backgrounded") {
116735
116805
  this.#status = "completed";
116736
116806
  }
116807
+ if (this.taskOutput.stdoutToFile && !this.#backgroundTaskId) {
116808
+ await this.#waitForFileOutputFlush(code);
116809
+ }
116737
116810
  const stdout = await this.taskOutput.getStdout();
116738
116811
  const result = {
116739
116812
  code,
@@ -116762,6 +116835,20 @@ class ShellCommandImpl {
116762
116835
  resultResolver(result);
116763
116836
  }
116764
116837
  }
116838
+ async#waitForFileOutputFlush(code) {
116839
+ const stdioClosedPromise = this.#stdioClosedPromise;
116840
+ if (!stdioClosedPromise) {
116841
+ return;
116842
+ }
116843
+ const graceMs = code === 0 ? OUTPUT_CLOSE_GRACE_MS : ERROR_OUTPUT_CLOSE_GRACE_MS;
116844
+ await Promise.race([
116845
+ stdioClosedPromise,
116846
+ new Promise((resolve10) => {
116847
+ const timeout = setTimeout(resolve10, graceMs);
116848
+ timeout.unref();
116849
+ })
116850
+ ]);
116851
+ }
116765
116852
  #doKill(code) {
116766
116853
  this.#status = "killed";
116767
116854
  if (this.#childProcess.pid) {
@@ -116845,7 +116932,7 @@ function createFailedCommand(preSpawnError) {
116845
116932
  cleanup() {}
116846
116933
  };
116847
116934
  }
116848
- var import_tree_kill, SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000;
116935
+ var import_tree_kill, SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000, OUTPUT_CLOSE_GRACE_MS = 100, ERROR_OUTPUT_CLOSE_GRACE_MS = 1000;
116849
116936
  var init_ShellCommand = __esm(() => {
116850
116937
  init_Task();
116851
116938
  init_format2();
@@ -259485,11 +259572,14 @@ ${stderr}` : stdout;
259485
259572
  }
259486
259573
  } while (!generatorResult.done);
259487
259574
  result = generatorResult.value;
259488
- trackGitOperations(input.command, result.code, result.stdout);
259575
+ const stdout2 = result.stdout || "";
259576
+ const stderr = result.stderr || "";
259577
+ const combinedOutput = [stdout2, stderr].filter(Boolean).join(stdout2 && stderr ? EOL : "");
259578
+ trackGitOperations(input.command, result.code, combinedOutput);
259489
259579
  const isInterrupt = result.interrupted && abortController.signal.reason === "interrupt";
259490
- stdoutAccumulator.append((result.stdout || "").trimEnd() + EOL);
259491
- interpretationResult = interpretCommandResult(input.command, result.code, result.stdout || "", "");
259492
- if (result.stdout && result.stdout.includes(".git/index.lock': File exists")) {
259580
+ stdoutAccumulator.append(combinedOutput.trimEnd() + EOL);
259581
+ interpretationResult = interpretCommandResult(input.command, result.code, stdout2, stderr);
259582
+ if (combinedOutput.includes(".git/index.lock': File exists")) {
259493
259583
  logEvent("tengu_git_index_lock_error", {});
259494
259584
  }
259495
259585
  if (interpretationResult.isError && !isInterrupt) {
@@ -259503,7 +259593,8 @@ ${stderr}` : stdout;
259503
259593
  stderrForShellReset = stdErrAppendShellResetMessage("");
259504
259594
  }
259505
259595
  }
259506
- const outputWithSbFailures = SandboxManager3.annotateStderrWithSandboxFailures(input.command, result.stdout || "");
259596
+ const annotatedOutput = SandboxManager3.annotateStderrWithSandboxFailures(input.command, combinedOutput);
259597
+ const outputWithSbFailures = annotatedOutput || combinedOutput;
259507
259598
  if (result.preSpawnError) {
259508
259599
  throw new Error(result.preSpawnError);
259509
259600
  }
@@ -282561,7 +282652,7 @@ function getAnthropicEnvMetadata() {
282561
282652
  function getBuildAgeMinutes() {
282562
282653
  if (false)
282563
282654
  ;
282564
- const buildTime = new Date("2026-06-20T04:27:50.766Z").getTime();
282655
+ const buildTime = new Date("2026-06-23T14:32:49.206Z").getTime();
282565
282656
  if (isNaN(buildTime))
282566
282657
  return;
282567
282658
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -335911,4 +336002,4 @@ export {
335911
336002
  AbortError2 as AbortError
335912
336003
  };
335913
336004
 
335914
- //# debugId=1F8F3CFC5E2DADCB64756E2164756E21
336005
+ //# debugId=F1D1A50370F2E48F64756E2164756E21
package/dist/sdk.js CHANGED
@@ -96433,6 +96433,32 @@ function buildOpenAIRequestBody(params, ctx) {
96433
96433
  }
96434
96434
  return body;
96435
96435
  }
96436
+ function normalizeDsmlSentinelPrefix(value) {
96437
+ return value.replace(/|/g, "|").replace(/\s+/g, "");
96438
+ }
96439
+ function isDsmlFunctionCallSentinelPrefix(value) {
96440
+ const normalized = normalizeDsmlSentinelPrefix(value);
96441
+ return normalized.length > 0 && DSML_FUNCTION_CALL_SENTINEL.startsWith(normalized);
96442
+ }
96443
+ function findTrailingDsmlSentinelCandidateStart(text) {
96444
+ const lt = text.lastIndexOf("<");
96445
+ if (lt === -1)
96446
+ return null;
96447
+ return isDsmlFunctionCallSentinelPrefix(text.slice(lt)) ? lt : null;
96448
+ }
96449
+ function findBufferedTextFlushBoundary(text) {
96450
+ const sentinelStart = findTrailingDsmlSentinelCandidateStart(text);
96451
+ if (sentinelStart === null)
96452
+ return text.length;
96453
+ return text.slice(0, sentinelStart).trimEnd().length;
96454
+ }
96455
+ function findDsmlFunctionCallSentinel(text) {
96456
+ const re = /<\s*[||]\s*DSML\s*[||]\s*function_calls\b/;
96457
+ const match = re.exec(text);
96458
+ if (!match || match.index === undefined)
96459
+ return null;
96460
+ return { start: match.index, end: match.index + match[0].length };
96461
+ }
96436
96462
  async function* openaiStreamToAnthropic(response, model) {
96437
96463
  const messageId = makeMessageId2();
96438
96464
  let contentBlockIndex = 0;
@@ -96443,6 +96469,50 @@ async function* openaiStreamToAnthropic(response, model) {
96443
96469
  let lastStopReason = null;
96444
96470
  let hasEmittedFinalUsage = false;
96445
96471
  let hasProcessedFinishReason = false;
96472
+ let pendingTextBuffer = "";
96473
+ const emitBufferedText = (mode) => {
96474
+ const events = [];
96475
+ if (!pendingTextBuffer)
96476
+ return events;
96477
+ const sentinel = findDsmlFunctionCallSentinel(pendingTextBuffer);
96478
+ if (sentinel) {
96479
+ const visible2 = pendingTextBuffer.slice(0, sentinel.start).trimEnd();
96480
+ pendingTextBuffer = pendingTextBuffer.slice(sentinel.end);
96481
+ if (visible2) {
96482
+ events.push(...emitTextDeltaEvents(visible2));
96483
+ }
96484
+ if (pendingTextBuffer) {
96485
+ events.push(...emitBufferedText(mode));
96486
+ }
96487
+ return events;
96488
+ }
96489
+ const emitUntil = mode === "final" ? pendingTextBuffer.length : mode === "before_tool_call" ? findTrailingDsmlSentinelCandidateStart(pendingTextBuffer) ?? pendingTextBuffer.length : findBufferedTextFlushBoundary(pendingTextBuffer);
96490
+ if (emitUntil <= 0)
96491
+ return events;
96492
+ const visible = pendingTextBuffer.slice(0, emitUntil);
96493
+ pendingTextBuffer = pendingTextBuffer.slice(emitUntil);
96494
+ if (visible) {
96495
+ events.push(...emitTextDeltaEvents(visible));
96496
+ }
96497
+ return events;
96498
+ };
96499
+ const emitTextDeltaEvents = (text) => {
96500
+ const events = [];
96501
+ if (!hasEmittedContentStart) {
96502
+ events.push({
96503
+ type: "content_block_start",
96504
+ index: contentBlockIndex,
96505
+ content_block: { type: "text", text: "" }
96506
+ });
96507
+ hasEmittedContentStart = true;
96508
+ }
96509
+ events.push({
96510
+ type: "content_block_delta",
96511
+ index: contentBlockIndex,
96512
+ delta: { type: "text_delta", text }
96513
+ });
96514
+ return events;
96515
+ };
96446
96516
  yield {
96447
96517
  type: "message_start",
96448
96518
  message: {
@@ -96550,21 +96620,13 @@ async function* openaiStreamToAnthropic(response, model) {
96550
96620
  hasClosedReasoning = true;
96551
96621
  }
96552
96622
  if (delta.content != null) {
96553
- if (!hasEmittedContentStart) {
96554
- yield {
96555
- type: "content_block_start",
96556
- index: contentBlockIndex,
96557
- content_block: { type: "text", text: "" }
96558
- };
96559
- hasEmittedContentStart = true;
96560
- }
96561
- yield {
96562
- type: "content_block_delta",
96563
- index: contentBlockIndex,
96564
- delta: { type: "text_delta", text: delta.content }
96565
- };
96623
+ pendingTextBuffer += delta.content;
96624
+ for (const event of emitBufferedText("streaming"))
96625
+ yield event;
96566
96626
  }
96567
96627
  if (delta.tool_calls) {
96628
+ for (const event of emitBufferedText("before_tool_call"))
96629
+ yield event;
96568
96630
  for (const tc of delta.tool_calls) {
96569
96631
  if (tc.id && tc.function?.name) {
96570
96632
  if (hasEmittedContentStart) {
@@ -96631,6 +96693,8 @@ async function* openaiStreamToAnthropic(response, model) {
96631
96693
  };
96632
96694
  hasClosedReasoning = true;
96633
96695
  }
96696
+ for (const event of emitBufferedText("final"))
96697
+ yield event;
96634
96698
  if (hasEmittedContentStart) {
96635
96699
  yield {
96636
96700
  type: "content_block_stop",
@@ -97003,7 +97067,7 @@ function createOpenAIShimClient(options) {
97003
97067
  messages: beta.messages
97004
97068
  };
97005
97069
  }
97006
- var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, OpenAIShimStream;
97070
+ var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, DSML_FUNCTION_CALL_SENTINEL = "<|DSML|function_calls", OpenAIShimStream;
97007
97071
  var init_shim2 = __esm(() => {
97008
97072
  init_sdk();
97009
97073
  init_envUtils();
@@ -116633,6 +116697,7 @@ class ShellCommandImpl {
116633
116697
  #shouldAutoBackground;
116634
116698
  #resultResolver = null;
116635
116699
  #exitCodeResolver = null;
116700
+ #stdioClosedPromise = null;
116636
116701
  #boundAbortHandler = null;
116637
116702
  taskOutput;
116638
116703
  static #handleTimeout(self2) {
@@ -116720,6 +116785,11 @@ class ShellCommandImpl {
116720
116785
  });
116721
116786
  this.#childProcess.once("exit", this.#exitHandler.bind(this));
116722
116787
  this.#childProcess.once("error", this.#errorHandler.bind(this));
116788
+ this.#stdioClosedPromise = new Promise((resolve10) => {
116789
+ this.#childProcess.once("close", () => {
116790
+ resolve10();
116791
+ });
116792
+ });
116723
116793
  this.#timeoutId = setTimeout(ShellCommandImpl.#handleTimeout, this.#timeout, this);
116724
116794
  const exitPromise = new Promise((resolve10) => {
116725
116795
  this.#exitCodeResolver = resolve10;
@@ -116734,6 +116804,9 @@ class ShellCommandImpl {
116734
116804
  if (this.#status === "running" || this.#status === "backgrounded") {
116735
116805
  this.#status = "completed";
116736
116806
  }
116807
+ if (this.taskOutput.stdoutToFile && !this.#backgroundTaskId) {
116808
+ await this.#waitForFileOutputFlush(code);
116809
+ }
116737
116810
  const stdout = await this.taskOutput.getStdout();
116738
116811
  const result = {
116739
116812
  code,
@@ -116762,6 +116835,20 @@ class ShellCommandImpl {
116762
116835
  resultResolver(result);
116763
116836
  }
116764
116837
  }
116838
+ async#waitForFileOutputFlush(code) {
116839
+ const stdioClosedPromise = this.#stdioClosedPromise;
116840
+ if (!stdioClosedPromise) {
116841
+ return;
116842
+ }
116843
+ const graceMs = code === 0 ? OUTPUT_CLOSE_GRACE_MS : ERROR_OUTPUT_CLOSE_GRACE_MS;
116844
+ await Promise.race([
116845
+ stdioClosedPromise,
116846
+ new Promise((resolve10) => {
116847
+ const timeout = setTimeout(resolve10, graceMs);
116848
+ timeout.unref();
116849
+ })
116850
+ ]);
116851
+ }
116765
116852
  #doKill(code) {
116766
116853
  this.#status = "killed";
116767
116854
  if (this.#childProcess.pid) {
@@ -116845,7 +116932,7 @@ function createFailedCommand(preSpawnError) {
116845
116932
  cleanup() {}
116846
116933
  };
116847
116934
  }
116848
- var import_tree_kill, SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000;
116935
+ var import_tree_kill, SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000, OUTPUT_CLOSE_GRACE_MS = 100, ERROR_OUTPUT_CLOSE_GRACE_MS = 1000;
116849
116936
  var init_ShellCommand = __esm(() => {
116850
116937
  init_Task();
116851
116938
  init_format2();
@@ -259485,11 +259572,14 @@ ${stderr}` : stdout;
259485
259572
  }
259486
259573
  } while (!generatorResult.done);
259487
259574
  result = generatorResult.value;
259488
- trackGitOperations(input.command, result.code, result.stdout);
259575
+ const stdout2 = result.stdout || "";
259576
+ const stderr = result.stderr || "";
259577
+ const combinedOutput = [stdout2, stderr].filter(Boolean).join(stdout2 && stderr ? EOL : "");
259578
+ trackGitOperations(input.command, result.code, combinedOutput);
259489
259579
  const isInterrupt = result.interrupted && abortController.signal.reason === "interrupt";
259490
- stdoutAccumulator.append((result.stdout || "").trimEnd() + EOL);
259491
- interpretationResult = interpretCommandResult(input.command, result.code, result.stdout || "", "");
259492
- if (result.stdout && result.stdout.includes(".git/index.lock': File exists")) {
259580
+ stdoutAccumulator.append(combinedOutput.trimEnd() + EOL);
259581
+ interpretationResult = interpretCommandResult(input.command, result.code, stdout2, stderr);
259582
+ if (combinedOutput.includes(".git/index.lock': File exists")) {
259493
259583
  logEvent("tengu_git_index_lock_error", {});
259494
259584
  }
259495
259585
  if (interpretationResult.isError && !isInterrupt) {
@@ -259503,7 +259593,8 @@ ${stderr}` : stdout;
259503
259593
  stderrForShellReset = stdErrAppendShellResetMessage("");
259504
259594
  }
259505
259595
  }
259506
- const outputWithSbFailures = SandboxManager3.annotateStderrWithSandboxFailures(input.command, result.stdout || "");
259596
+ const annotatedOutput = SandboxManager3.annotateStderrWithSandboxFailures(input.command, combinedOutput);
259597
+ const outputWithSbFailures = annotatedOutput || combinedOutput;
259507
259598
  if (result.preSpawnError) {
259508
259599
  throw new Error(result.preSpawnError);
259509
259600
  }
@@ -282561,7 +282652,7 @@ function getAnthropicEnvMetadata() {
282561
282652
  function getBuildAgeMinutes() {
282562
282653
  if (false)
282563
282654
  ;
282564
- const buildTime = new Date("2026-06-20T04:27:50.766Z").getTime();
282655
+ const buildTime = new Date("2026-06-23T14:32:49.206Z").getTime();
282565
282656
  if (isNaN(buildTime))
282566
282657
  return;
282567
282658
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -335911,4 +336002,4 @@ export {
335911
336002
  AbortError2 as AbortError
335912
336003
  };
335913
336004
 
335914
- //# debugId=8D264B0B42FBE9F564756E2164756E21
336005
+ //# debugId=432C8411F9337F1F64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencow-ai/opencow-agent-sdk",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "description": "Claude Code opened to any LLM — OpenAI, Gemini, DeepSeek, Ollama, and 200+ models",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk.js",