@telora/daemon 0.17.99 → 0.17.101

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/build-info.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "commitSha": "eb9daffb",
3
- "builtAt": "2026-06-16T21:14:50.991Z",
2
+ "commitSha": "189a4a0d",
3
+ "builtAt": "2026-06-17T00:14:34.198Z",
4
4
  "expectedMigrations": [
5
5
  "20250829113330_create_org_nodes_table.sql",
6
6
  "20250829113402_fix_function_security_search_path.sql",
@@ -645,6 +645,12 @@
645
645
  "20260616092424_discovery_requests_api_key_env.sql",
646
646
  "20260616105749_local_model_telora_managed_keys.sql",
647
647
  "20260616132414_agent_escalations_kind_merge_classes.sql",
648
- "20260616155133_lock_local_model_secret_write_rpcs.sql"
648
+ "20260616155133_lock_local_model_secret_write_rpcs.sql",
649
+ "20260616212949_drop_stale_redeem_connect_token_overload.sql",
650
+ "20260616221622_handle_new_user_drop_default_tracker.sql",
651
+ "20260616221712_drop_dead_default_tracker_rows.sql",
652
+ "20260616224152_get_product_sessions_overlapping.sql",
653
+ "20260616225633_add_issue_type_to_get_product_issue_transitions.sql",
654
+ "20260616233000_stable_order_get_product_issue_transitions.sql"
649
655
  ]
650
656
  }
@@ -1,15 +1,23 @@
1
1
  /**
2
- * LLM client for loop data updates.
2
+ * LLM client for loop data updates and PRD/loop differential evaluation.
3
3
  *
4
- * Calls the Anthropic API using the organization's LLM secret
5
- * (fetched via edge function RPC). One call per focus per cycle maximum.
4
+ * Runs ONE model call per focus per cycle by spawning the `claude` CLI in print
5
+ * mode -- the same pattern as `de-restatement.ts` / `negative-branch.ts` -- so it
6
+ * rides the operator's existing Claude Code auth and needs NO Anthropic API key,
7
+ * org LLM secret, or any other key beyond what the spawned agent teams already
8
+ * use. (Previously this did a raw fetch to api.anthropic.com with an x-api-key
9
+ * header; when no key was configured the call returned null and the differential
10
+ * loop / PRD steward froze -- exactly the gap this client now closes.)
6
11
  *
7
- * Capture: this client talks to the Anthropic API with a raw fetch, which
8
- * bypasses Claude Code's OTLP export -- so loop-layer token/cost spend was
9
- * historically invisible to agent_telemetry_metrics (the "blind spot"). We now
10
- * parse the response usage and buffer a telemetry metric row on the same writer
11
- * the OTLP receiver feeds, so loop spend lands in agent_telemetry_metrics too.
12
+ * Capture: a `--print` one-shot session produces NO OTLP rows (the OTLP exporter
13
+ * only fires for long-lived interactive sessions), so loop-layer token/cost spend
14
+ * would otherwise be invisible to agent_telemetry_metrics. We parse the usage
15
+ * block off the print-mode JSON (`--output-format json`) and buffer a telemetry
16
+ * metric row on the same writer the OTLP receiver feeds, so loop spend lands in
17
+ * agent_telemetry_metrics too -- the same capture path as the audit assessor
18
+ * (spawner/lifecycle.ts buildAuditMetricRow).
12
19
  */
20
+ import { type ChildProcess } from 'node:child_process';
13
21
  import { type TelemetryMetricRow } from './telemetry-writer.js';
14
22
  import type { LoopUpdatePrompt } from './loop-prompt-builder.js';
15
23
  /** Anthropic usage block (token counts). All fields optional/defensive. */
@@ -19,14 +27,45 @@ interface AnthropicUsage {
19
27
  cache_read_input_tokens?: number;
20
28
  cache_creation_input_tokens?: number;
21
29
  }
30
+ /** Parsed outcome of a single model invocation (default or test-seam). */
31
+ export interface LoopModelResult {
32
+ /** The model's text response, or null when none was produced. */
33
+ text: string | null;
34
+ /** Token usage for telemetry capture; absent when the result omitted it. */
35
+ usage?: AnthropicUsage;
36
+ /** Resolved model id (drives the telemetry model tag + cost fallback). */
37
+ model?: string;
38
+ /** Cost reported directly by Claude Code, if any (preferred over the estimate). */
39
+ costUsd?: number | null;
40
+ }
41
+ interface SpawnOpts {
42
+ stdio: ['pipe', 'pipe', 'pipe'];
43
+ }
44
+ export interface LoopLLMOptions {
45
+ /** Path to the `claude` CLI binary (default: 'claude'). */
46
+ claudeBin?: string;
47
+ /** Timeout in ms; defaults to 2 minutes. */
48
+ timeoutMs?: number;
49
+ /** Override spawn for tests. Defaults to node:child_process spawn. */
50
+ spawnFn?: (cmd: string, args: string[], opts: SpawnOpts) => ChildProcess;
51
+ /**
52
+ * Override the entire model invocation for tests -- bypasses spawning the
53
+ * CLI. Receives the system prompt and user message, returns the parsed model
54
+ * result. When omitted, the default spawns the `claude` CLI in print mode.
55
+ */
56
+ invokeModel?: (systemPrompt: string, userMessage: string) => Promise<LoopModelResult>;
57
+ }
22
58
  /**
23
- * Estimate cost in USD for a single Anthropic call from its usage block.
59
+ * Estimate cost in USD for a single call from its usage block.
24
60
  * Returns 0 when the model family is unrecognized.
25
61
  */
26
62
  export declare function estimateLoopCostUsd(model: string, usage: AnthropicUsage): number;
27
63
  /**
28
64
  * Build a telemetry metric row from a loop LLM call's usage. Exported for
29
65
  * testing the capture-path mapping in isolation.
66
+ *
67
+ * `costUsd`, when finite, is used verbatim (Claude Code's reported
68
+ * total_cost_usd); otherwise cost is estimated from the model + usage.
30
69
  */
31
70
  export declare function buildLoopMetricRow(params: {
32
71
  organizationId: string;
@@ -37,17 +76,22 @@ export declare function buildLoopMetricRow(params: {
37
76
  periodEnd: string;
38
77
  /** Loop phase that issued the call (e.g. 'audit'); null when not phase-scoped. */
39
78
  phase?: string | null;
79
+ /** Cost reported by Claude Code; preferred over the pricing-table estimate. */
80
+ costUsd?: number | null;
40
81
  }): TelemetryMetricRow;
41
82
  /**
42
- * Call the Anthropic API for a loop data update.
83
+ * Run a loop data update / differential evaluation through the operator's
84
+ * Claude Code auth (print-mode `claude` spawn). No API key beyond Claude Code
85
+ * auth is required.
43
86
  *
44
- * @param organizationId - Organization owning the LLM secret
87
+ * @param organizationId - Organization the evaluation belongs to (telemetry attribution)
45
88
  * @param prompt - System + user prompt assembled by the prompt builder
46
89
  * @param focusId - Focus the evaluation belongs to (for telemetry attribution)
47
90
  * @param phase - Loop/execution phase that issued this call (e.g. 'loop_evaluate').
48
91
  * Stamped onto the buffered telemetry row so spend is attributable by phase.
49
- * @returns Raw text response, or null if the call failed
92
+ * @param opts - Test seams (invokeModel / spawnFn / claudeBin / timeoutMs).
93
+ * @returns Raw text response, or null if the call failed / produced no text
50
94
  */
51
- export declare function callLoopLLM(organizationId: string, prompt: LoopUpdatePrompt, focusId?: string | null, phase?: string | null): Promise<string | null>;
95
+ export declare function callLoopLLM(organizationId: string, prompt: LoopUpdatePrompt, focusId?: string | null, phase?: string | null, opts?: LoopLLMOptions): Promise<string | null>;
52
96
  export {};
53
97
  //# sourceMappingURL=loop-llm-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop-llm-client.d.ts","sourceRoot":"","sources":["../src/loop-llm-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAgBjE,2EAA2E;AAC3E,UAAU,cAAc;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAsDD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAchF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GAAG,kBAAkB,CAyBrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,KAAK,GAAE,MAAM,GAAG,IAAW,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA8DxB"}
1
+ {"version":3,"file":"loop-llm-client.d.ts","sourceRoot":"","sources":["../src/loop-llm-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAMjE,2EAA2E;AAC3E,UAAU,cAAc;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAiBD,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,UAAU,SAAS;IACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,KAAK,YAAY,CAAC;IACzE;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;CACvF;AAkCD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAchF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GAAG,kBAAkB,CA4BrB;AAsGD;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,KAAK,GAAE,MAAM,GAAG,IAAW,EAC3B,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkCxB"}
@@ -1,52 +1,46 @@
1
1
  /**
2
- * LLM client for loop data updates.
2
+ * LLM client for loop data updates and PRD/loop differential evaluation.
3
3
  *
4
- * Calls the Anthropic API using the organization's LLM secret
5
- * (fetched via edge function RPC). One call per focus per cycle maximum.
4
+ * Runs ONE model call per focus per cycle by spawning the `claude` CLI in print
5
+ * mode -- the same pattern as `de-restatement.ts` / `negative-branch.ts` -- so it
6
+ * rides the operator's existing Claude Code auth and needs NO Anthropic API key,
7
+ * org LLM secret, or any other key beyond what the spawned agent teams already
8
+ * use. (Previously this did a raw fetch to api.anthropic.com with an x-api-key
9
+ * header; when no key was configured the call returned null and the differential
10
+ * loop / PRD steward froze -- exactly the gap this client now closes.)
6
11
  *
7
- * Capture: this client talks to the Anthropic API with a raw fetch, which
8
- * bypasses Claude Code's OTLP export -- so loop-layer token/cost spend was
9
- * historically invisible to agent_telemetry_metrics (the "blind spot"). We now
10
- * parse the response usage and buffer a telemetry metric row on the same writer
11
- * the OTLP receiver feeds, so loop spend lands in agent_telemetry_metrics too.
12
+ * Capture: a `--print` one-shot session produces NO OTLP rows (the OTLP exporter
13
+ * only fires for long-lived interactive sessions), so loop-layer token/cost spend
14
+ * would otherwise be invisible to agent_telemetry_metrics. We parse the usage
15
+ * block off the print-mode JSON (`--output-format json`) and buffer a telemetry
16
+ * metric row on the same writer the OTLP receiver feeds, so loop spend lands in
17
+ * agent_telemetry_metrics too -- the same capture path as the audit assessor
18
+ * (spawner/lifecycle.ts buildAuditMetricRow).
12
19
  */
13
- import { callApi } from './queries/shared.js';
20
+ import { spawn } from 'node:child_process';
14
21
  import { bufferMetric } from './telemetry-writer.js';
15
22
  // ---------------------------------------------------------------------------
16
- // API key retrieval
23
+ // Model / pricing
17
24
  // ---------------------------------------------------------------------------
18
25
  /**
19
- * Fetch the organization's Anthropic API key via the edge function.
20
- * Falls back to ANTHROPIC_API_KEY env var if not configured in the org.
26
+ * Default model tag for loop evaluations. Print mode runs on the operator's
27
+ * configured Claude Code model; we recover the real id from the JSON result's
28
+ * top-level `model` field (preferred) or the first `modelUsage` key, and fall
29
+ * back to this tag only when neither is present (it then affects just the
30
+ * telemetry model column and the cost-estimate fallback -- the real cost comes
31
+ * from total_cost_usd).
21
32
  */
22
- async function getApiKey(_organizationId) {
23
- try {
24
- const result = await callApi('llm_secret_get', {
25
- provider: 'anthropic',
26
- });
27
- if (result.apiKey)
28
- return result.apiKey;
29
- }
30
- catch {
31
- // Fall through to env var
32
- }
33
- return process.env.ANTHROPIC_API_KEY ?? null;
34
- }
35
- // ---------------------------------------------------------------------------
36
- // LLM call
37
- // ---------------------------------------------------------------------------
38
- /** Default model for loop evaluations. */
39
33
  const DEFAULT_MODEL = 'claude-sonnet-4-6';
40
- /** Max tokens for the loop update response. */
41
- const MAX_TOKENS = 4096;
34
+ const DEFAULT_TIMEOUT_MS = 2 * 60 * 1000;
42
35
  /**
43
- * Per-model-family pricing in USD per 1M tokens. Anthropic does not return a
44
- * cost on the messages response, so loop-layer cost is computed here from the
45
- * usage block. Matched by substring on the model id (sonnet / opus / haiku);
46
- * unknown families fall through to zero cost (tokens are still recorded).
36
+ * Per-model-family pricing in USD per 1M tokens. Used only as a FALLBACK when
37
+ * the print-mode JSON does not carry total_cost_usd; Claude Code normally
38
+ * reports the real cost, which is preferred. Matched by substring on the model
39
+ * id (sonnet / opus / haiku); unknown families fall through to zero cost
40
+ * (tokens are still recorded).
47
41
  *
48
42
  * NOTE: update these rates when Anthropic pricing changes -- a stale table
49
- * understates loop spend the same way the stale model pin did.
43
+ * understates loop spend.
50
44
  */
51
45
  const MODEL_PRICING = {
52
46
  sonnet: { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.30 },
@@ -54,7 +48,7 @@ const MODEL_PRICING = {
54
48
  haiku: { input: 1, output: 5, cacheWrite: 1.25, cacheRead: 0.10 },
55
49
  };
56
50
  /**
57
- * Estimate cost in USD for a single Anthropic call from its usage block.
51
+ * Estimate cost in USD for a single call from its usage block.
58
52
  * Returns 0 when the model family is unrecognized.
59
53
  */
60
54
  export function estimateLoopCostUsd(model, usage) {
@@ -74,12 +68,18 @@ export function estimateLoopCostUsd(model, usage) {
74
68
  /**
75
69
  * Build a telemetry metric row from a loop LLM call's usage. Exported for
76
70
  * testing the capture-path mapping in isolation.
71
+ *
72
+ * `costUsd`, when finite, is used verbatim (Claude Code's reported
73
+ * total_cost_usd); otherwise cost is estimated from the model + usage.
77
74
  */
78
75
  export function buildLoopMetricRow(params) {
79
76
  const { organizationId, focusId, model, usage, periodStart, periodEnd } = params;
80
77
  const start = Date.parse(periodStart);
81
78
  const end = Date.parse(periodEnd);
82
79
  const activeMs = Number.isFinite(start) && Number.isFinite(end) && end >= start ? end - start : 0;
80
+ const cost = params.costUsd !== undefined && params.costUsd !== null && Number.isFinite(params.costUsd)
81
+ ? params.costUsd
82
+ : estimateLoopCostUsd(model, usage);
83
83
  return {
84
84
  organization_id: organizationId,
85
85
  focus_id: focusId,
@@ -89,7 +89,7 @@ export function buildLoopMetricRow(params) {
89
89
  output_tokens: usage.output_tokens ?? 0,
90
90
  cache_read_tokens: usage.cache_read_input_tokens ?? 0,
91
91
  cache_creation_tokens: usage.cache_creation_input_tokens ?? 0,
92
- cost_usd: estimateLoopCostUsd(model, usage),
92
+ cost_usd: cost,
93
93
  active_time_ms: activeMs,
94
94
  tool_call_count: 0,
95
95
  tool_error_count: 0,
@@ -101,73 +101,143 @@ export function buildLoopMetricRow(params) {
101
101
  period_end: periodEnd,
102
102
  };
103
103
  }
104
+ // ---------------------------------------------------------------------------
105
+ // Default model invocation: spawn the `claude` CLI in print mode
106
+ // ---------------------------------------------------------------------------
104
107
  /**
105
- * Call the Anthropic API for a loop data update.
106
- *
107
- * @param organizationId - Organization owning the LLM secret
108
- * @param prompt - System + user prompt assembled by the prompt builder
109
- * @param focusId - Focus the evaluation belongs to (for telemetry attribution)
110
- * @param phase - Loop/execution phase that issued this call (e.g. 'loop_evaluate').
111
- * Stamped onto the buffered telemetry row so spend is attributable by phase.
112
- * @returns Raw text response, or null if the call failed
108
+ * Parse a `claude --print --output-format json` stdout payload into a
109
+ * LoopModelResult. Returns text:null on unparseable / empty output so the
110
+ * caller degrades gracefully (the loop skips a cycle rather than crashing).
113
111
  */
114
- export async function callLoopLLM(organizationId, prompt, focusId = null, phase = null) {
115
- const apiKey = await getApiKey(organizationId);
116
- if (!apiKey) {
117
- console.log('[Loop] No Anthropic API key available -- skipping LLM evaluation');
118
- return null;
112
+ function parsePrintJson(stdout) {
113
+ const trimmed = stdout.trim();
114
+ if (trimmed === '')
115
+ return { text: null };
116
+ let parsed;
117
+ try {
118
+ parsed = JSON.parse(trimmed);
119
119
  }
120
- const messages = [
121
- { role: 'user', content: prompt.user },
120
+ catch {
121
+ return { text: null };
122
+ }
123
+ // Prefer the explicit top-level model id; fall back to the first modelUsage
124
+ // key. Only when neither is present does the caller apply DEFAULT_MODEL -- so
125
+ // the telemetry tag reflects the real model whenever the CLI reports it.
126
+ const model = typeof parsed.model === 'string' && parsed.model !== ''
127
+ ? parsed.model
128
+ : parsed.modelUsage && typeof parsed.modelUsage === 'object'
129
+ ? Object.keys(parsed.modelUsage)[0]
130
+ : undefined;
131
+ return {
132
+ text: typeof parsed.result === 'string' ? parsed.result : null,
133
+ usage: parsed.usage,
134
+ model,
135
+ costUsd: typeof parsed.total_cost_usd === 'number' ? parsed.total_cost_usd : null,
136
+ };
137
+ }
138
+ /**
139
+ * Default model invocation: spawn the `claude` CLI in print mode with JSON
140
+ * output and return the parsed result. Rides Claude Code auth -- no key wiring.
141
+ */
142
+ function invokeClaudeCli(systemPrompt, userMessage, opts) {
143
+ const claudeBin = opts.claudeBin ?? 'claude';
144
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
145
+ const spawnFn = opts.spawnFn ?? ((cmd, args, sopts) => spawn(cmd, args, sopts));
146
+ const args = [
147
+ '--print',
148
+ '--output-format', 'json',
149
+ '--no-session-persistence',
150
+ '--system-prompt', systemPrompt,
122
151
  ];
123
- const periodStart = new Date().toISOString();
124
- try {
125
- const response = await fetch('https://api.anthropic.com/v1/messages', {
126
- method: 'POST',
127
- headers: {
128
- 'Content-Type': 'application/json',
129
- 'x-api-key': apiKey,
130
- 'anthropic-version': '2023-06-01',
131
- },
132
- body: JSON.stringify({
133
- model: DEFAULT_MODEL,
134
- max_tokens: MAX_TOKENS,
135
- system: prompt.system,
136
- messages,
137
- }),
138
- });
139
- if (!response.ok) {
140
- const errorBody = await response.text().catch(() => 'unknown error');
141
- console.log(`[Loop] Anthropic API error (${response.status}): ${errorBody.slice(0, 200)}`);
142
- return null;
152
+ return new Promise((resolve, reject) => {
153
+ let child;
154
+ try {
155
+ child = spawnFn(claudeBin, args, { stdio: ['pipe', 'pipe', 'pipe'] });
156
+ }
157
+ catch (err) {
158
+ reject(new Error(`loop-llm spawn failed: ${err.message}`));
159
+ return;
143
160
  }
144
- const result = await response.json();
145
- // Capture token/cost on the same writer the OTLP receiver feeds. This call
146
- // bypasses Claude Code's OTLP export, so without this the loop-layer spend
147
- // would never reach agent_telemetry_metrics. Best-effort: a capture failure
148
- // must not break the loop evaluation.
149
- if (result.usage) {
161
+ let stdout = '';
162
+ let stderr = '';
163
+ child.stdout?.on('data', (chunk) => { stdout += chunk.toString('utf8'); });
164
+ child.stderr?.on('data', (chunk) => { stderr += chunk.toString('utf8'); });
165
+ const timer = setTimeout(() => {
150
166
  try {
151
- bufferMetric(buildLoopMetricRow({
152
- organizationId,
153
- focusId,
154
- model: result.model ?? DEFAULT_MODEL,
155
- usage: result.usage,
156
- periodStart,
157
- periodEnd: new Date().toISOString(),
158
- phase,
159
- }));
167
+ child.kill('SIGKILL');
160
168
  }
161
- catch (err) {
162
- console.log(`[Loop] Telemetry capture failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
169
+ catch { /* ignore */ }
170
+ }, timeoutMs);
171
+ child.on('error', (err) => {
172
+ clearTimeout(timer);
173
+ reject(new Error(`loop-llm spawn error: ${err.message}`));
174
+ });
175
+ child.on('close', (code) => {
176
+ clearTimeout(timer);
177
+ if (code !== 0) {
178
+ reject(new Error(`loop-llm exited ${code}: ${stderr.slice(-2000)}`));
179
+ return;
163
180
  }
181
+ resolve(parsePrintJson(stdout));
182
+ });
183
+ try {
184
+ child.stdin?.write(userMessage);
185
+ child.stdin?.end();
186
+ }
187
+ catch (err) {
188
+ clearTimeout(timer);
189
+ reject(new Error(`loop-llm stdin write failed: ${err.message}`));
164
190
  }
165
- const textBlock = result.content?.find(c => c.type === 'text');
166
- return textBlock?.text ?? null;
191
+ });
192
+ }
193
+ // ---------------------------------------------------------------------------
194
+ // LLM call
195
+ // ---------------------------------------------------------------------------
196
+ /**
197
+ * Run a loop data update / differential evaluation through the operator's
198
+ * Claude Code auth (print-mode `claude` spawn). No API key beyond Claude Code
199
+ * auth is required.
200
+ *
201
+ * @param organizationId - Organization the evaluation belongs to (telemetry attribution)
202
+ * @param prompt - System + user prompt assembled by the prompt builder
203
+ * @param focusId - Focus the evaluation belongs to (for telemetry attribution)
204
+ * @param phase - Loop/execution phase that issued this call (e.g. 'loop_evaluate').
205
+ * Stamped onto the buffered telemetry row so spend is attributable by phase.
206
+ * @param opts - Test seams (invokeModel / spawnFn / claudeBin / timeoutMs).
207
+ * @returns Raw text response, or null if the call failed / produced no text
208
+ */
209
+ export async function callLoopLLM(organizationId, prompt, focusId = null, phase = null, opts = {}) {
210
+ const invoke = opts.invokeModel ?? ((sys, msg) => invokeClaudeCli(sys, msg, opts));
211
+ const periodStart = new Date().toISOString();
212
+ let result;
213
+ try {
214
+ result = await invoke(prompt.system, prompt.user);
167
215
  }
168
216
  catch (err) {
169
- console.log(`[Loop] Anthropic API call failed: ${err instanceof Error ? err.message : String(err)}`);
217
+ console.log(`[Loop] Claude Code evaluation failed: ${err instanceof Error ? err.message : String(err)}`);
170
218
  return null;
171
219
  }
220
+ // Capture token/cost on the same writer the OTLP receiver feeds. A --print
221
+ // one-shot session produces NO OTLP rows, so without this the loop-layer
222
+ // spend would never reach agent_telemetry_metrics. Best-effort: a capture
223
+ // failure must not break the loop evaluation.
224
+ if (result.usage) {
225
+ try {
226
+ bufferMetric(buildLoopMetricRow({
227
+ organizationId,
228
+ focusId,
229
+ model: result.model ?? DEFAULT_MODEL,
230
+ usage: result.usage,
231
+ periodStart,
232
+ periodEnd: new Date().toISOString(),
233
+ phase,
234
+ costUsd: result.costUsd,
235
+ }));
236
+ }
237
+ catch (err) {
238
+ console.log(`[Loop] Telemetry capture failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
239
+ }
240
+ }
241
+ return result.text;
172
242
  }
173
243
  //# sourceMappingURL=loop-llm-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop-llm-client.js","sourceRoot":"","sources":["../src/loop-llm-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop-llm-client.js","sourceRoot":"","sources":["../src/loop-llm-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telora/daemon",
3
- "version": "0.17.99",
3
+ "version": "0.17.101",
4
4
  "description": "Agent orchestration daemon for Telora - spawns and manages Claude Code instances",
5
5
  "type": "module",
6
6
  "bin": {