@odla-ai/cli 0.16.2 → 0.16.3

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/index.cjs CHANGED
@@ -1995,10 +1995,10 @@ var import_node_fs7 = require("fs");
1995
1995
  var import_node_os = require("os");
1996
1996
  var import_node_path4 = require("path");
1997
1997
 
1998
- // ../harness/dist/chunk-7SN5SG4N.js
1998
+ // ../harness/dist/chunk-QTUEF2HZ.js
1999
1999
  var HARNESS_PROTOCOL_VERSION = 1;
2000
2000
 
2001
- // ../harness/dist/chunk-HX4QYGWE.js
2001
+ // ../harness/dist/chunk-GE6CCN7W.js
2002
2002
  var CONTROL = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/;
2003
2003
  var HarnessProtocolError = class extends Error {
2004
2004
  name = "HarnessProtocolError";
@@ -2076,7 +2076,7 @@ function encodeAgentInput(message2) {
2076
2076
  `;
2077
2077
  }
2078
2078
 
2079
- // ../harness/dist/chunk-QWWRL7M4.js
2079
+ // ../harness/dist/chunk-IRFCMVKU.js
2080
2080
  var import_child_process = require("child_process");
2081
2081
  var import_fs = require("fs");
2082
2082
  var import_promises2 = require("fs/promises");
@@ -2593,7 +2593,7 @@ async function stageWorkspacePair(baselineSource, workspaceSource, options = {})
2593
2593
  }
2594
2594
  }
2595
2595
 
2596
- // ../harness/dist/chunk-T2RD6ZAW.js
2596
+ // ../harness/dist/chunk-4MOSEKB6.js
2597
2597
  var import_crypto = require("crypto");
2598
2598
  var import_promises5 = require("fs/promises");
2599
2599
  var import_path5 = require("path");
@@ -2930,7 +2930,7 @@ function validateSnapshot(snapshot, limits) {
2930
2930
  }
2931
2931
  }
2932
2932
 
2933
- // ../harness/dist/chunk-T2RD6ZAW.js
2933
+ // ../harness/dist/chunk-4MOSEKB6.js
2934
2934
  var import_child_process4 = require("child_process");
2935
2935
  var import_promises6 = require("fs/promises");
2936
2936
  var import_path6 = require("path");
@@ -3223,7 +3223,7 @@ function looksLikeDestination(value) {
3223
3223
  return /^(?:[a-z][a-z0-9+.-]*:\/\/|\/|\\\\)/i.test(text) || /^[\w.-]+\.[a-z]{2,}(?:[/:]|$)/i.test(text);
3224
3224
  }
3225
3225
 
3226
- // ../harness/dist/chunk-T2RD6ZAW.js
3226
+ // ../harness/dist/chunk-4MOSEKB6.js
3227
3227
  var import_crypto4 = require("crypto");
3228
3228
  async function digestStagedWorkspace(root, limits) {
3229
3229
  const files = [];
@@ -4414,6 +4414,7 @@ function codeCommandMetadata(payload, resume) {
4414
4414
  const role = payload.role;
4415
4415
  const title = payload.title;
4416
4416
  const prompt = payload.prompt;
4417
+ const maxTokensPerInteraction = payload.maxTokensPerInteraction ?? 32e3;
4417
4418
  if (role !== "coding" && role !== "review" || typeof title !== "string" || typeof prompt !== "string") {
4418
4419
  throw new TypeError(`invalid Code ${resume ? "resume" : "start"} metadata`);
4419
4420
  }
@@ -4425,10 +4426,14 @@ function codeCommandMetadata(payload, resume) {
4425
4426
  if (typeof repository !== "string" || !repository.includes("/") || typeof baseCommitSha !== "string" || !/^[0-9a-f]{40}$/.test(baseCommitSha) || typeof sourceTreeDigest !== "string" || !/^sha256:[0-9a-f]{64}$/.test(sourceTreeDigest)) {
4426
4427
  throw new TypeError(`invalid Code ${resume ? "resume" : "start"} trusted base`);
4427
4428
  }
4429
+ if (!Number.isSafeInteger(maxTokensPerInteraction) || Number(maxTokensPerInteraction) < 4e3 || Number(maxTokensPerInteraction) > 2e5) {
4430
+ throw new TypeError(`invalid Code ${resume ? "resume" : "start"} interaction token limit`);
4431
+ }
4428
4432
  return {
4429
4433
  role,
4430
4434
  title,
4431
4435
  prompt,
4436
+ maxTokensPerInteraction: Number(maxTokensPerInteraction),
4432
4437
  planningInputDigest: typeof planning === "string" && /^sha256:[0-9a-f]{64}$/.test(planning) ? planning : null,
4433
4438
  attestationDigest: typeof attestation === "string" ? attestation : "resume",
4434
4439
  repository,
@@ -4504,6 +4509,57 @@ function createCodeRuntimeToolBroker(input, lease, role) {
4504
4509
  });
4505
4510
  return role === "coding" ? broker : { execute: (context, request) => request.tool === "sandbox.read" ? broker.execute(context, request) : Promise.resolve({ requestId: request.requestId, ok: false, content: "review sessions are read-only" }) };
4506
4511
  }
4512
+ async function handleCodeRuntimeInference(input) {
4513
+ const { command, metadata: metadata2, request, state } = input;
4514
+ if (state.tokens >= metadata2.maxTokensPerInteraction) {
4515
+ if (!state.noticeEmitted) {
4516
+ state.noticeEmitted = true;
4517
+ await input.event({
4518
+ type: "message",
4519
+ actor: "system",
4520
+ body: `Pi paused at the ${metadata2.maxTokensPerInteraction.toLocaleString("en-US")}-token per-interaction limit. Send a new instruction to continue.`
4521
+ }).catch(() => void 0);
4522
+ }
4523
+ return {
4524
+ protocolVersion: HARNESS_PROTOCOL_VERSION,
4525
+ type: "inference.response",
4526
+ requestId: request.requestId,
4527
+ response: {
4528
+ id: `budget:${command.commandId}`,
4529
+ provider: "openai",
4530
+ model: "interaction-budget",
4531
+ role: "assistant",
4532
+ content: [{ type: "text", text: "Pause now. The owner-set token limit for this interaction has been reached." }],
4533
+ stopReason: "end_turn",
4534
+ usage: { inputTokens: 0, outputTokens: 0 }
4535
+ }
4536
+ };
4537
+ }
4538
+ const startedAt = Date.now();
4539
+ const response2 = await input.control.infer(command.sessionId, {
4540
+ requestId: request.requestId,
4541
+ interactionId: command.commandId,
4542
+ call: request.call
4543
+ });
4544
+ state.tokens += response2.receipt.inputTokens + response2.receipt.outputTokens;
4545
+ await input.event({
4546
+ type: "usage",
4547
+ provider: response2.receipt.provider,
4548
+ model: response2.receipt.model,
4549
+ inputTokens: response2.receipt.inputTokens,
4550
+ outputTokens: response2.receipt.outputTokens,
4551
+ durationMs: Date.now() - startedAt,
4552
+ interactionId: command.commandId,
4553
+ interactionTokens: state.tokens,
4554
+ interactionMaxTokens: metadata2.maxTokensPerInteraction
4555
+ }).catch(() => void 0);
4556
+ return {
4557
+ protocolVersion: HARNESS_PROTOCOL_VERSION,
4558
+ type: "inference.response",
4559
+ requestId: request.requestId,
4560
+ response: response2.response
4561
+ };
4562
+ }
4507
4563
  async function appendCodeRuntimeEvent(control, command, event, refs) {
4508
4564
  const eventId = `${command.commandId.slice(0, 45)}:${refs.length + 1}`;
4509
4565
  refs.push(eventId);
@@ -4615,6 +4671,7 @@ var CodePiRuntimeEngine = class {
4615
4671
  acknowledged: false,
4616
4672
  role: metadata2.role,
4617
4673
  title: metadata2.title,
4674
+ maxTokensPerInteraction: metadata2.maxTokensPerInteraction,
4618
4675
  baseCommitSha: metadata2.baseCommitSha,
4619
4676
  repository: metadata2.repository,
4620
4677
  sourceTreeDigest: metadata2.sourceTreeDigest,
@@ -4651,6 +4708,11 @@ var CodePiRuntimeEngine = class {
4651
4708
  if (!active || typeof prompt !== "string" || !prompt.trim() || prompt.length > 2e4) {
4652
4709
  throw new TypeError("prompt requires an active Code session and bounded text");
4653
4710
  }
4711
+ const requestedLimit = command.payload.maxTokensPerInteraction ?? active.maxTokensPerInteraction;
4712
+ if (!Number.isSafeInteger(requestedLimit) || Number(requestedLimit) < 4e3 || Number(requestedLimit) > 2e5) {
4713
+ throw new TypeError("prompt requires a valid interaction token limit");
4714
+ }
4715
+ active.maxTokensPerInteraction = Number(requestedLimit);
4654
4716
  await active.done;
4655
4717
  active.abort = new AbortController();
4656
4718
  active.acknowledged = false;
@@ -4659,6 +4721,7 @@ var CodePiRuntimeEngine = class {
4659
4721
  role: active.role,
4660
4722
  title: active.title,
4661
4723
  prompt,
4724
+ maxTokensPerInteraction: active.maxTokensPerInteraction,
4662
4725
  planningInputDigest: active.planningInputDigest,
4663
4726
  attestationDigest: "follow-up",
4664
4727
  repository: active.repository,
@@ -4687,6 +4750,7 @@ var CodePiRuntimeEngine = class {
4687
4750
  }, lease, metadata2.role);
4688
4751
  const startedAt = Date.now();
4689
4752
  let completionSeen = false;
4753
+ const interaction = { tokens: 0, noticeEmitted: false };
4690
4754
  const result = await this.#run({
4691
4755
  engine: this.options.engine,
4692
4756
  image: this.options.image,
@@ -4702,25 +4766,18 @@ var CodePiRuntimeEngine = class {
4702
4766
  }, active.conversationRefs),
4703
4767
  onMessage: async (output) => {
4704
4768
  if (output.type === "inference.request") {
4705
- const inferenceStarted = Date.now();
4706
- const response2 = await this.options.control.infer(command.sessionId, {
4707
- requestId: output.requestId,
4708
- call: output.call
4769
+ return handleCodeRuntimeInference({
4770
+ command,
4771
+ metadata: metadata2,
4772
+ request: output,
4773
+ state: interaction,
4774
+ control: this.options.control,
4775
+ event: (event) => this.#event(
4776
+ command,
4777
+ event,
4778
+ active.conversationRefs
4779
+ )
4709
4780
  });
4710
- await this.#event(command, {
4711
- type: "usage",
4712
- provider: response2.receipt.provider,
4713
- model: response2.receipt.model,
4714
- inputTokens: response2.receipt.inputTokens,
4715
- outputTokens: response2.receipt.outputTokens,
4716
- durationMs: Date.now() - inferenceStarted
4717
- }, active.conversationRefs).catch(() => void 0);
4718
- return {
4719
- protocolVersion: HARNESS_PROTOCOL_VERSION,
4720
- type: "inference.response",
4721
- requestId: output.requestId,
4722
- response: response2.response
4723
- };
4724
4781
  }
4725
4782
  if (output.type === "tool.request") {
4726
4783
  const toolStarted = Date.now();
@@ -5219,12 +5276,15 @@ async function prepareCodeImages(engine, images) {
5219
5276
  }
5220
5277
 
5221
5278
  // src/code-runtime-config.ts
5222
- var CODE_PI_IMAGE = "ghcr.io/cory/odla-pi-agent@sha256:e7858b4f0291543171b2659b47c5d00f97acc4767cafd9b74ae5228899e0cde4";
5279
+ var CODE_PI_IMAGE = "ghcr.io/cory/odla-pi-agent@sha256:2a52a1c8eed66ad167e7bccab4d603ed8fcd75c42dddfb320083436ed89b7c9c";
5223
5280
  var CODE_BUILD_RECIPES = Object.freeze([{
5224
5281
  id: "odla-code-contracts",
5225
5282
  image: "node:24-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd",
5226
5283
  command: [
5227
5284
  "node",
5285
+ // The clean source mount deliberately has no node_modules. Reuse the
5286
+ // semver copy inside this digest-pinned npm image without network access.
5287
+ "--import=data:text/javascript,import%20Module%20from%20%22node%3Amodule%22%3Bprocess.env.NODE_PATH%3D%22%2Fusr%2Flocal%2Flib%2Fnode_modules%2Fnpm%2Fnode_modules%22%3BModule._initPaths%28%29",
5228
5288
  "--test",
5229
5289
  "scripts/lib/directories.test.mjs",
5230
5290
  "scripts/lib/internal-deps.test.mjs",