mtech-ai-local-runner 0.1.24 → 0.1.25

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/README.md CHANGED
@@ -10,6 +10,16 @@ The package stores safe runner configuration locally and keeps OAuth refresh cre
10
10
 
11
11
  Public npm installation requires no npm account or publishing OTP. Setup requires Gateway OAuth login, and local Claude Code must already be authenticated (`claude auth status`).
12
12
 
13
+ ## 0.1.25: scoped reads and blocked diagnostics
14
+
15
+ Codex receives explicit file-scoped ai_local read/search guidance; launch and
16
+ Gateway reporting remain host duties. Valid blocked reports now retain bounded
17
+ report counts and identity comparisons in events and terminal results. They
18
+ remain blocked, and multiple reports still fail closed. Fake-data integration
19
+ checks generated settings with the actual scoped server; native model-visible
20
+ tool exposure still needs a separately approved actual attempt. Foreground
21
+ installation does not run Codex or update the daemon.
22
+
13
23
  ## 0.1.24: bounded report identity diagnostics
14
24
 
15
25
  Failed report validation records pair counts for same/different wire item IDs
@@ -1,6 +1,6 @@
1
1
  import { compilePrompt as compileBrief } from "../prompt-compiler.js";
2
2
  export function compileCodexPrompt(taskPackage, label) {
3
- return `${compileBrief(taskPackage, { workItemLabel: label, progressReporting: "native_messages" })}\n\nUse only the ai_local job tools for repository reads, edits and approved tests. Native filesystem, commands, web, images and delegation are unavailable or denied. A denied tool is a scope boundary, never a reason to try another path. If required work cannot proceed, return the structured blocked report.`;
3
+ return `${compileBrief(taskPackage, { workItemLabel: label, progressReporting: "native_messages" })}\n\nUse only the ai_local job tools for repository reads, edits and approved tests. For reading, use server ai_local's local_read({path: "docs/example.md"}) or local_search({path: "docs/example.md", query: "text"}) with checkout-relative paths. In a read-only task, use only read/search tools; the Runner enforces the approved paths and operations. A denied native cwd is intentional: it is a private control directory, not the source checkout. Native filesystem, commands, web, images and delegation are unavailable or denied. A denied tool is a scope boundary, never a reason to try another path. Do not repeat host orchestration: claim, shadow, fingerprints, binding, administrator checks, launches, Gateway usage and Job reporting belong to the Runner/host, even when described in the objective. Perform only the assigned repository work and report evidence you actually observed. Do not claim that no model call occurred. If the required tool is unavailable, emit one final structured blocked report naming the missing tool and unfinished repository work; do not request or attempt a new launch.`;
4
4
  }
5
5
  export const CODEX_REPORT_SCHEMA = {
6
6
  type: "object", additionalProperties: false, required: ["status", "report", "evidence", "pending_work"],
@@ -75,6 +75,11 @@ export class CodexStreamParser {
75
75
  : this.candidates > 1 ? this.reportFailure("CODEX_COMPLETION_REPORT_MULTIPLE")
76
76
  : this.report && ["completed", "blocked"].includes(this.report.eventType) ? this.report
77
77
  : this.reportFailure("CODEX_COMPLETION_REPORT_NOT_FINAL");
78
+ if (terminal.eventType === "blocked")
79
+ terminal.payload = { ...terminal.payload, completion_report: {
80
+ version: "codex-completion-report-v1", code: "CODEX_COMPLETION_REPORT_BLOCKED", agent_message_count: this.messages,
81
+ valid_report_count: this.candidates, invalid_message_count: this.messages - this.candidates, identity: this.reportIdentity(),
82
+ } };
78
83
  const usage = record(event.usage);
79
84
  const observed = {};
80
85
  for (const field of ["input_tokens", "cached_input_tokens", "output_tokens"]) {
@@ -3,6 +3,7 @@ const MAX_EVIDENCE_ITEMS = 20;
3
3
  const MAX_EVIDENCE_CHARS = 500;
4
4
  const MAX_REPORT_ENVELOPE_CHARS = 16_000;
5
5
  const REPORT_FAILURE_CODES = ["CODEX_COMPLETION_REPORT_MISSING", "CODEX_COMPLETION_REPORT_INVALID", "CODEX_COMPLETION_REPORT_MULTIPLE", "CODEX_COMPLETION_REPORT_NOT_FINAL", "CODEX_TURN_INCOMPLETE"];
6
+ const REPORT_DIAGNOSTIC_CODES = [...REPORT_FAILURE_CODES, "CODEX_COMPLETION_REPORT_BLOCKED"];
6
7
  /** Pair counts only; no item IDs, text, stable digests or arbitrary keys. */
7
8
  function reportIdentityDiagnostic(value, valid) {
8
9
  if (!value || typeof value !== "object" || Array.isArray(value))
@@ -27,14 +28,15 @@ export function completionReportDiagnostic(value) {
27
28
  return undefined;
28
29
  const d = value, code = d.code;
29
30
  const messages = d.agent_message_count, valid = d.valid_report_count, invalid = d.invalid_message_count;
30
- if (d.version !== "codex-completion-report-v1" || typeof code !== "string" || !REPORT_FAILURE_CODES.includes(code)
31
+ if (d.version !== "codex-completion-report-v1" || typeof code !== "string" || !REPORT_DIAGNOSTIC_CODES.includes(code)
31
32
  || typeof messages !== "number" || !Number.isSafeInteger(messages) || messages < 0
32
33
  || typeof valid !== "number" || !Number.isSafeInteger(valid) || valid < 0 || valid > messages
33
34
  || typeof invalid !== "number" || !Number.isSafeInteger(invalid) || invalid !== messages - valid
34
35
  || code === "CODEX_COMPLETION_REPORT_MISSING" && messages !== 0
35
36
  || code === "CODEX_COMPLETION_REPORT_INVALID" && (messages === 0 || valid !== 0)
36
37
  || code === "CODEX_COMPLETION_REPORT_MULTIPLE" && valid < 2
37
- || code === "CODEX_COMPLETION_REPORT_NOT_FINAL" && (valid !== 1 || invalid === 0))
38
+ || code === "CODEX_COMPLETION_REPORT_NOT_FINAL" && (valid !== 1 || invalid === 0)
39
+ || code === "CODEX_COMPLETION_REPORT_BLOCKED" && valid !== 1)
38
40
  return undefined;
39
41
  const identity = reportIdentityDiagnostic(d.identity, valid);
40
42
  return { version: "codex-completion-report-v1", code, agent_message_count: messages, valid_report_count: valid, invalid_message_count: invalid,
@@ -269,7 +269,9 @@ export class ExecutionCoordinator {
269
269
  clearInterval(heartbeatTimer);
270
270
  }
271
271
  const status = terminal.eventType === "completed" ? "completed" : terminal.eventType === "cancelled" ? "cancelled" : terminal.eventType === "blocked" || terminal.eventType === "scope_conflict" ? "blocked" : "failed";
272
- const reportDiagnostic = status === "failed" ? completionReportDiagnostic(terminal.payload?.completion_report) : undefined;
272
+ const diagnostic = status === "failed" || terminal.eventType === "blocked" ? completionReportDiagnostic(terminal.payload?.completion_report) : undefined;
273
+ const reportDiagnostic = diagnostic && (terminal.eventType === "blocked"
274
+ ? diagnostic.code === "CODEX_COMPLETION_REPORT_BLOCKED" : diagnostic.code !== "CODEX_COMPLETION_REPORT_BLOCKED") ? diagnostic : undefined;
273
275
  await this.deps.gateway.complete({ jobId: job.id, generation: job.generation, leaseToken: job.leaseToken, status, result: { binding_id: binding.bindingId, event_type: terminal.eventType, summary: terminal.summary, ...(failureDiagnostic ? { execution_failure: { ...failureDiagnostic } } : {}), ...(reportDiagnostic ? { completion_report: reportDiagnostic } : {}), ...(adapter.securityReceipt?.() ? { security_receipt: adapter.securityReceipt() } : {}) } });
274
276
  await this.deps.state.clear();
275
277
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mtech-ai-local-runner",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "bin": {