@odla-ai/harness 0.9.3 → 0.10.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.
@@ -164,7 +164,7 @@ function createCodeRuntimeControlClient(options) {
164
164
  }
165
165
 
166
166
  // src/code-runtime.ts
167
- var CODE_RUNTIME_PROTOCOL_VERSION = 1;
167
+ var CODE_RUNTIME_PROTOCOL_VERSION = 2;
168
168
  async function runCodeRuntimeHeartbeatLoop(options) {
169
169
  const heartbeatMs = options.heartbeatMs ?? 15e3;
170
170
  if (!Number.isSafeInteger(heartbeatMs) || heartbeatMs < 1e3 || heartbeatMs > 3e5) {
@@ -1090,6 +1090,10 @@ function codeCommandMetadata(payload, resume) {
1090
1090
  if (role !== "coding" && role !== "review" || typeof title !== "string" || typeof prompt !== "string") {
1091
1091
  throw new TypeError(`invalid Code ${resume ? "resume" : "start"} metadata`);
1092
1092
  }
1093
+ if (payload.readOnly !== void 0 && typeof payload.readOnly !== "boolean") {
1094
+ throw new TypeError(`invalid Code ${resume ? "resume" : "start"} read-only capability`);
1095
+ }
1096
+ const readOnly = role === "review" || payload.readOnly === true;
1093
1097
  const planning = trusted?.planningInputDigest;
1094
1098
  const attestation = trusted?.attestationDigest;
1095
1099
  const repository = trusted?.repository;
@@ -1103,6 +1107,7 @@ function codeCommandMetadata(payload, resume) {
1103
1107
  }
1104
1108
  return {
1105
1109
  role,
1110
+ readOnly,
1106
1111
  title,
1107
1112
  prompt,
1108
1113
  maxTokensPerInteraction: Number(maxTokensPerInteraction),
@@ -1489,7 +1494,8 @@ function codeSkill(opts) {
1489
1494
  true
1490
1495
  )
1491
1496
  ];
1492
- const tools = opts.surface === "v3" ? [...orientation, searchFiles, read2, applyPatch, runRecipe] : opts.surface === "v2" ? [listFiles, searchFiles, read2, applyPatch, runRecipe] : [read2, applyPatch, runRecipe];
1497
+ const effects = opts.readOnly ? [] : [applyPatch, runRecipe];
1498
+ const tools = opts.surface === "v3" ? [...orientation, searchFiles, read2, ...effects] : opts.surface === "v2" ? [listFiles, searchFiles, read2, ...effects] : [read2, ...effects];
1493
1499
  return { name: "code", tools };
1494
1500
  }
1495
1501
 
@@ -1506,6 +1512,7 @@ async function runCodeAgent(options) {
1506
1512
  lease: options.lease,
1507
1513
  workspaceDir: options.workspaceDir,
1508
1514
  surface,
1515
+ ...options.readOnly === void 0 ? {} : { readOnly: options.readOnly },
1509
1516
  ...options.recipeIds ? { recipeIds: options.recipeIds } : {},
1510
1517
  onToolCall: (call) => {
1511
1518
  toolCalls.push(call);
@@ -1518,7 +1525,7 @@ async function runCodeAgent(options) {
1518
1525
  {
1519
1526
  name: "odla-code",
1520
1527
  model: options.model,
1521
- system: options.system ?? SYSTEM_PROMPT_FOR[surface],
1528
+ system: options.system ?? `${SYSTEM_PROMPT_FOR[surface]}${options.readOnly ? "\n\nThis session is read-only. Inspect and report; repository mutation and recipe execution are intentionally unavailable." : ""}`,
1522
1529
  skills: [skill, ...options.extraSkills ?? []],
1523
1530
  maxSteps: options.maxSteps ?? 24,
1524
1531
  maxTokens: options.maxTokens ?? 16384
@@ -1549,6 +1556,7 @@ async function runCodeAgentAttempt(options) {
1549
1556
  // id only labels the request the control plane is about to rewrite.
1550
1557
  model: "brokered",
1551
1558
  surface,
1559
+ ...options.readOnly === void 0 ? {} : { readOnly: options.readOnly },
1552
1560
  ...options.recipeIds ? { recipeIds: options.recipeIds } : {},
1553
1561
  ...options.extraSkills ? { extraSkills: options.extraSkills } : {},
1554
1562
  ...options.maxSteps === void 0 ? {} : { maxSteps: options.maxSteps },
@@ -2573,7 +2581,16 @@ function createCodeRuntimeToolBroker(input, lease, role) {
2573
2581
  readerId: `code-session:${lease.task.taskId}`,
2574
2582
  readOnlyPrefixes: [".odla-references"]
2575
2583
  });
2576
- 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" }) };
2584
+ const reviewReads = /* @__PURE__ */ new Set([
2585
+ "sandbox.read",
2586
+ "sandbox.list",
2587
+ "sandbox.search",
2588
+ "sandbox.overview",
2589
+ "sandbox.where_is",
2590
+ "sandbox.who_imports",
2591
+ "sandbox.who_touches"
2592
+ ]);
2593
+ return role === "coding" ? broker : { execute: (context, request) => reviewReads.has(request.tool) ? broker.execute(context, request) : Promise.resolve({ requestId: request.requestId, ok: false, content: "review sessions are read-only" }) };
2577
2594
  }
2578
2595
 
2579
2596
  // src/code-runtime-goal.ts
@@ -2877,6 +2894,7 @@ var TheseusRuntimeEngine = class {
2877
2894
  acknowledged: false,
2878
2895
  startGate,
2879
2896
  role: metadata.role,
2897
+ readOnly: metadata.readOnly,
2880
2898
  title: metadata.title,
2881
2899
  maxTokensPerInteraction: metadata.maxTokensPerInteraction,
2882
2900
  baseCommitSha: metadata.baseCommitSha,
@@ -2933,6 +2951,7 @@ var TheseusRuntimeEngine = class {
2933
2951
  event: (event) => this.#event(command, event, active.conversationRefs).then(() => void 0, () => void 0),
2934
2952
  attempt: (prompt) => this.#runAttempt(command, {
2935
2953
  role: active.role,
2954
+ readOnly: active.readOnly,
2936
2955
  title: active.title,
2937
2956
  prompt,
2938
2957
  maxTokensPerInteraction: active.maxTokensPerInteraction,
@@ -2975,6 +2994,7 @@ var TheseusRuntimeEngine = class {
2975
2994
  await this.#takeOver(command, "prompt requires an active Code session");
2976
2995
  active.done = this.#runAttempt(command, {
2977
2996
  role: active.role,
2997
+ readOnly: active.readOnly,
2978
2998
  title: active.title,
2979
2999
  prompt,
2980
3000
  maxTokensPerInteraction: active.maxTokensPerInteraction,
@@ -3022,6 +3042,7 @@ var TheseusRuntimeEngine = class {
3022
3042
  workspaceDir: active.workspace.workspaceDir,
3023
3043
  prompt: metadata.prompt,
3024
3044
  signal: active.abort.signal,
3045
+ readOnly: metadata.readOnly,
3025
3046
  recipeIds: this.options.recipes.map((recipe2) => recipe2.id),
3026
3047
  ...extraSkills.length ? { extraSkills } : {}
3027
3048
  });
@@ -3133,4 +3154,4 @@ export {
3133
3154
  runGoal,
3134
3155
  TheseusRuntimeEngine
3135
3156
  };
3136
- //# sourceMappingURL=chunk-AEAISFY3.js.map
3157
+ //# sourceMappingURL=chunk-5MDYIJXC.js.map