@stage-labs/metro 0.1.0-beta.321 → 0.1.0-beta.322

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.
Files changed (52) hide show
  1. package/dist/claude-env.js +2 -2
  2. package/dist/cli.js +1 -1
  3. package/package.json +1 -1
  4. package/runtime/node_modules/@metro-labs/core/src/runner-activity.ts +12 -12
  5. package/runtime/node_modules/@metro-labs/daemon/package.json +1 -0
  6. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +1 -1
  7. package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +2 -2
  8. package/runtime/node_modules/@metro-labs/daemon/src/gateway/box-gateway.ts +32 -0
  9. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effective.ts +2 -8
  10. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +6 -6
  11. package/runtime/node_modules/@metro-labs/daemon/src/gateway/org-models.ts +2 -2
  12. package/runtime/node_modules/@metro-labs/daemon/src/gateway/relay.ts +108 -0
  13. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/config.ts +2 -2
  14. package/runtime/node_modules/@metro-labs/daemon/src/routes/http.ts +1 -2
  15. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +2 -2
  16. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +1 -2
  17. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +14 -1
  18. package/runtime/node_modules/@metro-labs/http/src/connector-tools.ts +10 -1
  19. package/runtime/node_modules/@metro-labs/http/src/mcp-server-tools.ts +21 -7
  20. package/runtime/node_modules/@metro-labs/inference/package.json +42 -0
  21. package/runtime/node_modules/@metro-labs/inference/src/attempts.ts +120 -0
  22. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/codex.ts +1 -1
  23. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/delivered.ts +7 -1
  24. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/effort.ts +2 -2
  25. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/failures.ts +11 -1
  26. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/fallback.ts +5 -4
  27. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/forward.ts +1 -1
  28. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/gateway.ts +47 -37
  29. package/runtime/node_modules/@metro-labs/inference/src/measure.ts +42 -0
  30. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/model-config.ts +9 -9
  31. package/runtime/node_modules/@metro-labs/inference/src/named.ts +36 -0
  32. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/routeway.ts +2 -1
  33. package/runtime/node_modules/@metro-labs/inference/src/served.ts +18 -0
  34. package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/usage.ts +34 -9
  35. package/runtime/runtime.json +1 -1
  36. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/runner-activity.ts +12 -12
  37. package/runtime/sdk-runner/runner.json +1 -1
  38. package/runtime/sdk-runner/src/app.ts +1 -1
  39. package/runtime/sdk-runner/src/runner.ts +1 -1
  40. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +0 -18
  41. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/bedrock.ts +0 -0
  42. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/cache-ttl.ts +0 -0
  43. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/codex-stream.ts +0 -0
  44. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/codex-translate.ts +0 -0
  45. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/codex-version.ts +0 -0
  46. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/eventstream.ts +0 -0
  47. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/frames.ts +0 -0
  48. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/openrouter.ts +0 -0
  49. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/subscription.ts +0 -0
  50. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/text.ts +0 -0
  51. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/tool-search.ts +0 -0
  52. /package/runtime/node_modules/@metro-labs/{daemon/src/gateway → inference/src}/usage-refresh.ts +0 -0
@@ -1,3 +1,4 @@
1
+ import { currentAttempt } from './attempts.js';
1
2
  type Key = string;
2
3
 
3
4
  export interface UsageWindow {
@@ -92,28 +93,49 @@ export function tallyTokens(key: Key, counted: Counted, now = new Date()): void
92
93
  });
93
94
  }
94
95
 
95
- const TOKEN_FIELD = /"(input_tokens|output_tokens|cache_read_input_tokens|cache_creation_input_tokens)"\s*:\s*(\d+)/g;
96
+ const TOKEN_FIELD = /"(input_tokens|output_tokens|cache_read_input_tokens|cache_creation_input_tokens|ephemeral_5m_input_tokens|ephemeral_1h_input_tokens|cost)"\s*:\s*(\d+(?:\.\d+)?)/g;
97
+
98
+ const FIELDS: Record<string, keyof Seen> = {
99
+ input_tokens: 'input',
100
+ output_tokens: 'output',
101
+ cache_read_input_tokens: 'read',
102
+ cache_creation_input_tokens: 'creation',
103
+ ephemeral_5m_input_tokens: 'write5m',
104
+ ephemeral_1h_input_tokens: 'write1h',
105
+ cost: 'cost',
106
+ };
107
+
108
+ interface Seen {
109
+ input: number;
110
+ output: number;
111
+ read: number;
112
+ creation: number;
113
+ write5m: number;
114
+ write1h: number;
115
+ cost: number;
116
+ }
96
117
 
97
118
  export class UsageScanner {
98
119
  private carry = '';
99
- private readonly max = { input: 0, output: 0, read: 0, creation: 0 };
120
+ private readonly max: Seen = { input: 0, output: 0, read: 0, creation: 0, write5m: 0, write1h: 0, cost: 0 };
100
121
  private touched = false;
122
+ private costed = false;
101
123
 
102
124
  constructor(private readonly key: Key) {}
103
125
 
104
126
  private scan(text: string): void {
105
127
  for (const hit of text.matchAll(TOKEN_FIELD)) {
128
+ const field = FIELDS[hit[1] ?? ''];
106
129
  const value = Number(hit[2]);
107
- if (!Number.isFinite(value)) continue;
108
- this.touched = true;
109
- if (hit[1] === 'input_tokens') this.max.input = Math.max(this.max.input, value);
110
- else if (hit[1] === 'output_tokens') this.max.output = Math.max(this.max.output, value);
111
- else if (hit[1] === 'cache_read_input_tokens') this.max.read = Math.max(this.max.read, value);
112
- else this.max.creation = Math.max(this.max.creation, value);
130
+ if (field === undefined || !Number.isFinite(value)) continue;
131
+ if (field === 'cost') this.costed = true;
132
+ else this.touched = true;
133
+ this.max[field] = Math.max(this.max[field], value);
113
134
  }
114
135
  }
115
136
 
116
137
  feed(text: string): void {
138
+ currentAttempt()?.firstByte();
117
139
  const joined = this.carry + text;
118
140
  const cut = joined.lastIndexOf('\n');
119
141
  if (cut === -1) {
@@ -128,7 +150,10 @@ export class UsageScanner {
128
150
  if (this.carry !== '') this.scan(this.carry);
129
151
  this.carry = '';
130
152
  if (!this.touched) return;
131
- tallyTokens(this.key, { input: this.max.input, output: this.max.output, cached: this.max.read + this.max.creation }, now);
153
+ const { input, output, read, creation, write5m, write1h, cost } = this.max;
154
+ const split = write5m + write1h;
155
+ currentAttempt()?.counted({ input, output, cacheRead: read, cacheWrite5m: split > 0 ? write5m : creation, cacheWrite1h: write1h }, this.costed ? cost : null);
156
+ tallyTokens(this.key, { input, output, cached: read + creation }, now);
132
157
  this.touched = false;
133
158
  }
134
159
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.1.0-beta.321"
2
+ "version": "0.1.0-beta.322"
3
3
  }
@@ -8,17 +8,17 @@ export type RunnerTaskState = (typeof TASK_STATES)[number];
8
8
  export type RunnerEventKind = (typeof EVENTS)[number];
9
9
 
10
10
  const FAILURE = {
11
- authentication: 'The provider refused authentication. Check the Model page.',
12
- billing: 'The provider refused billing. Check the Model page.',
13
- rate_limit: 'The provider rate limit was reached. Retry later or check the Model page.',
14
- provider_unavailable: 'The provider is unavailable. Retry later or check the Model page.',
15
- invalid_request: 'The provider rejected the request. Check Conversations and the Model page.',
11
+ authentication: 'The provider refused authentication. Check the Gateway page.',
12
+ billing: 'The provider refused billing. Check the Gateway page.',
13
+ rate_limit: 'The provider rate limit was reached. Retry later or check the Gateway page.',
14
+ provider_unavailable: 'The provider is unavailable. Retry later or check the Gateway page.',
15
+ invalid_request: 'The provider rejected the request. Check Conversations and the Gateway page.',
16
16
  output_limit: 'The model reached its output token limit. Check Conversations.',
17
- provider_error: 'SDK turn failed (provider_error). Check Conversations and the Model page.',
18
- error_during_execution: 'SDK turn failed (error_during_execution). Check Conversations and the Model page.',
19
- error_max_turns: 'SDK turn failed (error_max_turns). Check Conversations and the Model page.',
20
- error_max_budget_usd: 'SDK turn failed (error_max_budget_usd). Check Conversations and the Model page.',
21
- error_max_structured_output_retries: 'SDK turn failed (error_max_structured_output_retries). Check Conversations and the Model page.',
17
+ provider_error: 'SDK turn failed (provider_error). Check Conversations and the Gateway page.',
18
+ error_during_execution: 'SDK turn failed (error_during_execution). Check Conversations and the Gateway page.',
19
+ error_max_turns: 'SDK turn failed (error_max_turns). Check Conversations and the Gateway page.',
20
+ error_max_budget_usd: 'SDK turn failed (error_max_budget_usd). Check Conversations and the Gateway page.',
21
+ error_max_structured_output_retries: 'SDK turn failed (error_max_structured_output_retries). Check Conversations and the Gateway page.',
22
22
  read_token_limit: 'Read exceeded its token limit. Read a smaller range with offset and limit, or search the file.',
23
23
  tool_error: 'A tool failed. See its result in Conversations.',
24
24
  task_error: 'A background task failed. See Conversations and Terminal.',
@@ -27,12 +27,12 @@ const FAILURE = {
27
27
  saved_state: 'The saved Agent SDK state cannot be read. Restore it before starting.',
28
28
  executable: 'The SDK executable could not start. Prepare the SDK runtime again.',
29
29
  module: 'The SDK runtime could not load a required module. Prepare the SDK runtime again.',
30
- configuration: 'The SDK launch configuration is missing or invalid. Check Harness and the Model page before starting.',
30
+ configuration: 'The SDK launch configuration is missing or invalid. Check Harness and the Gateway page before starting.',
31
31
  process_exit: 'The SDK process exited unexpectedly. Check its reported exit code or signal before retrying.',
32
32
  connection: 'The SDK connection failed. Check the server and provider connection.',
33
33
  session_ended: 'The Agent SDK session ended unexpectedly.',
34
34
  interrupted: 'The SDK stopped before finishing a chat request. Check Conversations before retrying; actions may already have run.',
35
- session_error: 'The Agent SDK session failed. Check Terminal and the Model page.',
35
+ session_error: 'The Agent SDK session failed. Check Terminal and the Gateway page.',
36
36
  } as const;
37
37
  export type RunnerFailureCode = keyof typeof FAILURE;
38
38
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.0-beta.321",
2
+ "version": "0.1.0-beta.322",
3
3
  "dependencies": {
4
4
  "@anthropic-ai/claude-agent-sdk": "0.3.287",
5
5
  "@modelcontextprotocol/sdk": "^1.29.0",
@@ -40,7 +40,7 @@ async function connected(cfg: RunnerConfig, hooks: AppHooks, release: () => Prom
40
40
  callState: (state) => { runner.calls.reconcile(state.route); },
41
41
  toolsChanged: () => { tools?.changed(); },
42
42
  model: (model) => {
43
- log.info({ model }, 'sdk-runner: the Model page picked a model');
43
+ log.info({ model }, 'sdk-runner: the Gateway page picked a model');
44
44
  runner.switchModel(model).catch((err: unknown) => {
45
45
  log.warn({ err: errMsg(err) }, 'sdk-runner: could not switch the model');
46
46
  });
@@ -243,7 +243,7 @@ export class Runner {
243
243
  debugFailure('model switch', err);
244
244
  const failure = new SessionError(this.diagnostics.failure(err));
245
245
  this.parts.activity?.fail(failure);
246
- log.warn({ reason: failure.failure.code, diagnostic: failure.failure.diagnostic, summary: failureSummary(failure) }, 'sdk-runner: the session could not take the model the Model page picked');
246
+ log.warn({ reason: failure.failure.code, diagnostic: failure.failure.diagnostic, summary: failureSummary(failure) }, 'sdk-runner: the session could not take the model the Gateway page picked');
247
247
  });
248
248
  }
249
249
 
@@ -1,18 +0,0 @@
1
- export interface Served {
2
- connection: string;
3
- provider: string;
4
- model: string;
5
- at: string;
6
- }
7
-
8
- let last: Served | null = null;
9
-
10
- export const noteServed = (served: Served): void => {
11
- last = served;
12
- };
13
-
14
- export const lastServed = (): Served | null => last;
15
-
16
- export const forgetServed = (): void => {
17
- last = null;
18
- };