( options: SubagentRunOptions, )
| 412 | } |
| 413 | |
| 414 | private async runOnce( |
| 415 | options: SubagentRunOptions, |
| 416 | ): Promise<SubagentRunResult> { |
| 417 | const startTime = Date.now(); |
| 418 | let recordedAccounting = false; |
| 419 | const recordAccounting = ( |
| 420 | result: SubagentRunResult, |
| 421 | messages: unknown[] = [], |
| 422 | ) => { |
| 423 | if (!options.accountingSessionId || recordedAccounting) return; |
| 424 | recordedAccounting = true; |
| 425 | recordChildInvocation({ |
| 426 | db: openDatabase(), |
| 427 | parentSessionId: options.accountingSessionId, |
| 428 | harness: "pi", |
| 429 | subagent: |
| 430 | options.accountingSubagent ?? inferAccountingSubagent(options.agent), |
| 431 | task: options.accountingTask ?? null, |
| 432 | startedAt: startTime, |
| 433 | status: result.ok |
| 434 | ? "completed" |
| 435 | : result.reason === "abort" |
| 436 | ? "aborted" |
| 437 | : "failed", |
| 438 | messages, |
| 439 | providerId: |
| 440 | typeof options.model === "string" |
| 441 | ? options.model.split("/")[0] |
| 442 | : null, |
| 443 | modelId: |
| 444 | typeof options.model === "string" |
| 445 | ? options.model.split("/").slice(1).join("/") |
| 446 | : null, |
| 447 | error: result.ok ? null : result.error, |
| 448 | parentInvocationId: options.accountingParentInvocationId ?? null, |
| 449 | }); |
| 450 | }; |
| 451 | if (options.signal?.aborted) { |
| 452 | const result: SubagentRunResult = { |
| 453 | ok: false, |
| 454 | reason: "abort", |
| 455 | error: "pi subagent aborted by caller", |
| 456 | durationMs: Date.now() - startTime, |
| 457 | }; |
| 458 | // Same best-effort contract as settle(): accounting must never throw |
| 459 | // out of the return path (a DB write failure here would propagate to |
| 460 | // the caller as a spurious spawn error). Telemetry is best-effort. |
| 461 | try { |
| 462 | recordAccounting(result); |
| 463 | } catch (err) { |
| 464 | sessionLog( |
| 465 | options.accountingSessionId ?? "subagent", |
| 466 | `subagent accounting failed (continuing): ${err instanceof Error ? err.message : String(err)}`, |
| 467 | ); |
| 468 | } |
| 469 | return result; |
| 470 | } |
| 471 | const failBeforeSpawn = ( |
no test coverage detected