@liy/agent-runner 0.2.7 → 0.3.2

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.
@@ -14964,7 +14964,7 @@ var QuerySchema = external_exports.object({
14964
14964
  limit: external_exports.number().int().positive().max(1e4).default(1e3),
14965
14965
  accessLevel: AccessLevelSchema.default("serving")
14966
14966
  }).superRefine((query, ctx) => {
14967
- const surfaces = [query.from.surface, ...query.joins.map((join2) => join2.surface)];
14967
+ const surfaces = [query.from.surface, ...query.joins.map((join3) => join3.surface)];
14968
14968
  const knownSurfaces = /* @__PURE__ */ new Set();
14969
14969
  for (const [index, surface] of surfaces.entries()) {
14970
14970
  if (knownSurfaces.has(surface)) {
@@ -14999,8 +14999,8 @@ var QuerySchema = external_exports.object({
14999
14999
  path: ["time", "bucket", "fn"]
15000
15000
  });
15001
15001
  }
15002
- for (const [index, join2] of query.joins.entries()) {
15003
- visitConditionFields(join2.on, (field) => {
15002
+ for (const [index, join3] of query.joins.entries()) {
15003
+ visitConditionFields(join3.on, (field) => {
15004
15004
  validateFieldRef(field, ["joins", index, "on"]);
15005
15005
  });
15006
15006
  }
@@ -15456,6 +15456,92 @@ async function forwardHarnessLines(stream, handler) {
15456
15456
 
15457
15457
  // src/harness-drivers/pi-rpc.ts
15458
15458
  import { spawn as nodeSpawn2 } from "node:child_process";
15459
+
15460
+ // src/debug/pi-rpc-trace.ts
15461
+ import { once } from "node:events";
15462
+ import { createWriteStream, mkdirSync } from "node:fs";
15463
+ import { dirname, join } from "node:path";
15464
+ var MAX_TRACE_LINE_BYTES = 16384;
15465
+ var MAX_TRACE_PREVIEW_CHARS = 8e3;
15466
+ function createPiRpcTrace(input) {
15467
+ const filePath = join(input.workspaceDir, "debug", "pi-rpc.jsonl");
15468
+ try {
15469
+ mkdirSync(dirname(filePath), { recursive: true });
15470
+ const stream = createWriteStream(filePath, {
15471
+ flags: "a",
15472
+ mode: 384
15473
+ });
15474
+ return createStreamTrace({
15475
+ filePath,
15476
+ stream,
15477
+ taskId: input.taskId,
15478
+ now: input.now ?? (() => /* @__PURE__ */ new Date())
15479
+ });
15480
+ } catch {
15481
+ return createNoopTrace();
15482
+ }
15483
+ }
15484
+ function createStreamTrace(input) {
15485
+ let closed = false;
15486
+ let failed = false;
15487
+ input.stream.on("error", () => {
15488
+ failed = true;
15489
+ });
15490
+ return {
15491
+ filePath: input.filePath,
15492
+ write(event) {
15493
+ if (closed || failed) {
15494
+ return;
15495
+ }
15496
+ input.stream.write(serializeTraceRecord({
15497
+ ts: input.now().toISOString(),
15498
+ taskId: input.taskId,
15499
+ ...event
15500
+ }));
15501
+ },
15502
+ async close() {
15503
+ if (closed) {
15504
+ return;
15505
+ }
15506
+ closed = true;
15507
+ if (failed) {
15508
+ return;
15509
+ }
15510
+ input.stream.end();
15511
+ await once(input.stream, "finish").then(() => void 0, () => void 0);
15512
+ }
15513
+ };
15514
+ }
15515
+ function createNoopTrace() {
15516
+ return {
15517
+ write() {
15518
+ },
15519
+ async close() {
15520
+ }
15521
+ };
15522
+ }
15523
+ function serializeTraceRecord(record2) {
15524
+ const line = `${JSON.stringify(record2)}
15525
+ `;
15526
+ if (Buffer.byteLength(line, "utf8") <= MAX_TRACE_LINE_BYTES) {
15527
+ return line;
15528
+ }
15529
+ return `${JSON.stringify({
15530
+ ...record2,
15531
+ truncated: true,
15532
+ payload: previewPayload(record2.payload)
15533
+ })}
15534
+ `;
15535
+ }
15536
+ function previewPayload(payload) {
15537
+ const text = typeof payload === "string" ? payload : JSON.stringify(payload) ?? "undefined";
15538
+ if (text.length <= MAX_TRACE_PREVIEW_CHARS) {
15539
+ return text;
15540
+ }
15541
+ return `${text.slice(0, MAX_TRACE_PREVIEW_CHARS)}...[truncated]`;
15542
+ }
15543
+
15544
+ // src/harness-drivers/pi-rpc.ts
15459
15545
  var driverOwnedPiFlags = /* @__PURE__ */ new Set([
15460
15546
  "--mode",
15461
15547
  "--provider",
@@ -15513,7 +15599,8 @@ function buildPiRpcArgs(harness) {
15513
15599
  }
15514
15600
  function startPiRpcHarness(input, spawnProcess) {
15515
15601
  const harness = input.harness;
15516
- const child = spawnProcess(harness.command, buildPiRpcArgs(harness), {
15602
+ const args = buildPiRpcArgs(harness);
15603
+ const child = spawnProcess(harness.command, args, {
15517
15604
  cwd: input.spec.workspaceDir,
15518
15605
  env: input.env,
15519
15606
  stdio: ["pipe", "pipe", "pipe"]
@@ -15521,6 +15608,19 @@ function startPiRpcHarness(input, spawnProcess) {
15521
15608
  const sanitizer = createHarnessOutputSanitizer(input.env, [
15522
15609
  ...input.harness.secretEnv ?? []
15523
15610
  ]);
15611
+ const trace = createPiRpcTrace({
15612
+ taskId: input.spec.taskId,
15613
+ workspaceDir: input.spec.workspaceDir
15614
+ });
15615
+ trace.write({
15616
+ kind: "process.started",
15617
+ stream: "process",
15618
+ payload: {
15619
+ command: harness.command,
15620
+ args,
15621
+ cwd: input.spec.workspaceDir
15622
+ }
15623
+ });
15524
15624
  let cleanupTermination = () => void 0;
15525
15625
  let agentEndReached = false;
15526
15626
  let resolveAgentEnd = () => void 0;
@@ -15537,6 +15637,7 @@ function startPiRpcHarness(input, spawnProcess) {
15537
15637
  input,
15538
15638
  line,
15539
15639
  sanitizer,
15640
+ trace,
15540
15641
  onAgentEnd() {
15541
15642
  agentEndReached = true;
15542
15643
  resolveAgentEnd("agent-end");
@@ -15547,20 +15648,36 @@ function startPiRpcHarness(input, spawnProcess) {
15547
15648
  });
15548
15649
  });
15549
15650
  const stderrDone = forwardJsonlByteStream(child.stderr, (line) => {
15550
- forwardPiStderrLine(input, line, sanitizer);
15651
+ forwardPiStderrLine(input, line, sanitizer, trace);
15551
15652
  });
15552
- writePiRpcCommand(child, {
15653
+ const promptCommand = {
15553
15654
  id: `mote-${input.spec.taskId}`,
15554
15655
  type: "prompt",
15555
15656
  message: input.prompt
15657
+ };
15658
+ writePiRpcCommand(child, promptCommand);
15659
+ trace.write({
15660
+ kind: "prompt.sent",
15661
+ stream: "stdin",
15662
+ payload: {
15663
+ id: promptCommand.id,
15664
+ type: promptCommand.type,
15665
+ messageLength: input.prompt.length
15666
+ }
15556
15667
  });
15557
15668
  const result = (async () => {
15558
15669
  let terminal;
15559
15670
  try {
15560
15671
  terminal = await Promise.race([closePromise, agentEndPromise]);
15561
15672
  } catch (error48) {
15673
+ trace.write({
15674
+ kind: "process.error",
15675
+ stream: "process",
15676
+ payload: formatTraceError(error48)
15677
+ });
15562
15678
  cleanupTermination();
15563
15679
  cleanupTermination = terminateChildProcess(child);
15680
+ await trace.close();
15564
15681
  throw error48;
15565
15682
  }
15566
15683
  if (terminal === "agent-end") {
@@ -15569,6 +15686,12 @@ function startPiRpcHarness(input, spawnProcess) {
15569
15686
  const closeResult = await closePromise;
15570
15687
  cleanupTermination();
15571
15688
  await Promise.all([stdoutDone, stderrDone]);
15689
+ trace.write({
15690
+ kind: "process.closed",
15691
+ stream: "process",
15692
+ payload: closeResult
15693
+ });
15694
+ await trace.close();
15572
15695
  return {
15573
15696
  exitCode: closeResult.exitCode,
15574
15697
  signal: closeResult.signal,
@@ -15577,6 +15700,12 @@ function startPiRpcHarness(input, spawnProcess) {
15577
15700
  }
15578
15701
  cleanupTermination();
15579
15702
  await Promise.all([stdoutDone, stderrDone]);
15703
+ trace.write({
15704
+ kind: "process.closed",
15705
+ stream: "process",
15706
+ payload: terminal
15707
+ });
15708
+ await trace.close();
15580
15709
  if (!agentEndReached && terminal.exitCode !== 0) {
15581
15710
  forwardPiHarnessStreamLine(
15582
15711
  input,
@@ -15604,20 +15733,44 @@ function handlePiRpcStdoutLine(input) {
15604
15733
  try {
15605
15734
  parsed = JSON.parse(trimmed);
15606
15735
  } catch {
15607
- forwardPiHarnessStreamLine(input.input, "stdout", input.sanitizer.redactText(trimmed));
15736
+ const message = input.sanitizer.redactText(trimmed);
15737
+ input.trace.write({
15738
+ kind: "stdout.text",
15739
+ stream: "stdout",
15740
+ payload: {
15741
+ message
15742
+ }
15743
+ });
15744
+ forwardPiHarnessStreamLine(input.input, "stdout", message);
15608
15745
  return;
15609
15746
  }
15747
+ const redacted = input.sanitizer.redactJson(parsed);
15610
15748
  if (isPiRpcResponse(parsed)) {
15749
+ input.trace.write({
15750
+ kind: "stdout.response",
15751
+ stream: "stdout",
15752
+ payload: redacted
15753
+ });
15611
15754
  if (parsed.command === "prompt" && parsed.success === false) {
15612
15755
  input.onPromptRejected(new Error(`Pi RPC prompt was rejected: ${formatPiRpcError(parsed, input.sanitizer.redactText)}`));
15613
15756
  }
15614
15757
  return;
15615
15758
  }
15616
15759
  if (isPiExtensionUiRequest(parsed)) {
15617
- forwardPiExtensionUiRequest(input.input, input.sanitizer.redactJson(parsed));
15760
+ input.trace.write({
15761
+ kind: "stdout.extension_ui_request",
15762
+ stream: "stdout",
15763
+ payload: redacted
15764
+ });
15765
+ forwardPiExtensionUiRequest(input.input, redacted);
15618
15766
  return;
15619
15767
  }
15620
- forwardPiEvent(input.input, input.sanitizer.redactJson(parsed));
15768
+ input.trace.write({
15769
+ kind: "stdout.event",
15770
+ stream: "stdout",
15771
+ payload: redacted
15772
+ });
15773
+ forwardPiEvent(input.input, redacted);
15621
15774
  if (parsed.type === "agent_end") {
15622
15775
  input.onAgentEnd();
15623
15776
  }
@@ -15652,8 +15805,16 @@ function forwardPiHarnessStreamLine(input, stream, message) {
15652
15805
  message: trimmed
15653
15806
  }));
15654
15807
  }
15655
- function forwardPiStderrLine(input, line, sanitizer) {
15656
- forwardPiHarnessStreamLine(input, "stderr", sanitizer.redactText(line));
15808
+ function forwardPiStderrLine(input, line, sanitizer, trace) {
15809
+ const message = sanitizer.redactText(line);
15810
+ trace.write({
15811
+ kind: "stderr.line",
15812
+ stream: "stderr",
15813
+ payload: {
15814
+ message
15815
+ }
15816
+ });
15817
+ forwardPiHarnessStreamLine(input, "stderr", message);
15657
15818
  }
15658
15819
  function writePiRpcCommand(child, command) {
15659
15820
  child.stdin.write(`${JSON.stringify(command)}
@@ -15692,6 +15853,17 @@ function formatPiRpcError(parsed, redactText) {
15692
15853
  }
15693
15854
  return "unknown error";
15694
15855
  }
15856
+ function formatTraceError(error48) {
15857
+ if (error48 instanceof Error) {
15858
+ return {
15859
+ name: error48.name,
15860
+ message: error48.message
15861
+ };
15862
+ }
15863
+ return {
15864
+ message: String(error48)
15865
+ };
15866
+ }
15695
15867
 
15696
15868
  // src/prompt.ts
15697
15869
  import { existsSync, readFileSync } from "node:fs";
@@ -15741,14 +15913,14 @@ function renderHarnessPromptTemplate(input) {
15741
15913
 
15742
15914
  // src/runtime.ts
15743
15915
  import { mkdir, readFile as readFile2, stat, writeFile } from "node:fs/promises";
15744
- import { dirname, join } from "node:path";
15916
+ import { dirname as dirname2, join as join2 } from "node:path";
15745
15917
  var uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
15746
15918
  function createTaskAgentWorkspacePaths(workspaceDir) {
15747
15919
  const normalized = workspaceDir.replace(/\/+$/g, "");
15748
15920
  return {
15749
15921
  workspaceDir: normalized,
15750
- stateDir: join(normalized, "state"),
15751
- artifactsDir: join(normalized, "artifacts")
15922
+ stateDir: join2(normalized, "state"),
15923
+ artifactsDir: join2(normalized, "artifacts")
15752
15924
  };
15753
15925
  }
15754
15926
  async function ensureTaskAgentWorkspace(paths) {
@@ -15758,10 +15930,10 @@ async function ensureTaskAgentWorkspace(paths) {
15758
15930
  ]);
15759
15931
  }
15760
15932
  async function writeTaskCompletion(input) {
15761
- await writeJsonFile(join(input.paths.stateDir, "completion.json"), input.completion);
15933
+ await writeJsonFile(join2(input.paths.stateDir, "completion.json"), input.completion);
15762
15934
  }
15763
15935
  async function readTaskCompletion(paths) {
15764
- const raw = await readFile2(join(paths.stateDir, "completion.json"), "utf8");
15936
+ const raw = await readFile2(join2(paths.stateDir, "completion.json"), "utf8");
15765
15937
  const parsed = JSON.parse(raw);
15766
15938
  if (parsed.status !== "completed" && parsed.status !== "partial" && parsed.status !== "failed" && parsed.status !== "cancelled") {
15767
15939
  throw new Error("completion status must be completed, partial, failed, or cancelled");
@@ -15779,13 +15951,13 @@ async function readTaskCompletion(paths) {
15779
15951
  }
15780
15952
  async function validateTaskArtifactFiles(input) {
15781
15953
  for (const artifactId of input.completion.artifactIds) {
15782
- const artifactPath = join(createArtifactDir(input.paths, artifactId), "artifact.json");
15954
+ const artifactPath = join2(createArtifactDir(input.paths, artifactId), "artifact.json");
15783
15955
  const artifact = taskArtifactDraftSchema.parse(JSON.parse(await readFile2(artifactPath, "utf8")));
15784
15956
  if (artifact.artifactId !== artifactId) {
15785
15957
  throw new Error(`artifact id mismatch for ${artifactId}`);
15786
15958
  }
15787
15959
  if ("dataset" in artifact) {
15788
- const dataPath = join(createArtifactDir(input.paths, artifactId), "data.csv");
15960
+ const dataPath = join2(createArtifactDir(input.paths, artifactId), "data.csv");
15789
15961
  const dataStat = await stat(dataPath);
15790
15962
  if (dataStat.size <= 0) {
15791
15963
  throw new Error(`dataset artifact ${artifactId} data.csv must be non-empty`);
@@ -15800,10 +15972,10 @@ function assertTaskArtifactId(artifactId) {
15800
15972
  }
15801
15973
  function createArtifactDir(paths, artifactId) {
15802
15974
  assertTaskArtifactId(artifactId);
15803
- return join(paths.artifactsDir, artifactId);
15975
+ return join2(paths.artifactsDir, artifactId);
15804
15976
  }
15805
15977
  async function writeJsonFile(path, value) {
15806
- await mkdir(dirname(path), { recursive: true });
15978
+ await mkdir(dirname2(path), { recursive: true });
15807
15979
  await writeFile(path, `${JSON.stringify(value, null, 2)}
15808
15980
  `);
15809
15981
  }