@theoremjs/agents 0.3.4-next.476.g46e6627 → 0.3.4-next.480.ge8c8d47

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
@@ -136,7 +136,7 @@ const support = defineProfile({
136
136
  system: "You help customers with their account. Cite the docs you used.",
137
137
  },
138
138
  models: {
139
- main: router.model("openRouter", "openrouter/free"),
139
+ main: router.model("openRouterOpenAi", "openrouter/free"),
140
140
  },
141
141
  defaultModel: "main",
142
142
  tools: { allow: ["search_tickets"] },
@@ -173,9 +173,9 @@ Use the `type` field to choose what the agent does. The type sets the shape of t
173
173
 
174
174
  | Type | Runner | Takes | Returns | First-party protocols |
175
175
  | :--- | :--- | :--- | :--- | :--- |
176
- | `text` | `runTurn` | text, attachments, voice notes, slots, history | text, thoughts, validated JSON, tool calls | `geminiInteractions`, `openRouter`, `openAi` |
176
+ | `text` | `runTurn` | text, attachments, voice notes, slots, history | text, thoughts, validated JSON, tool calls | `geminiInteractions`, `openRouterOpenAi`, `openAi` |
177
177
  | `image` | `runTurn` | prompt + reference images | images, optionally with interleaved text | `geminiInteractions`, `openRouterImages` |
178
- | `speech` | `runTurn` | text | audio (WAV, or MP3 on OpenRouter) | `geminiInteractions`, `openRouter`, `openAi` |
178
+ | `speech` | `runTurn` | text | audio (WAV, or MP3 on OpenRouter) | `geminiInteractions`, `openRouterOpenAi`, `openAi` |
179
179
  | `live` | `runSession` | realtime mic audio, camera frames, typed text | streamed audio, transcripts, tool calls | `geminiLive` |
180
180
  | `host` | `invokeTool`, `invokeToolStep`, `runTool`, `runToolStep` | tool calls from your own code, one at a time or as a step; the `run` pair gives how each call ended | guarded tool results | none; it never calls a model |
181
181
  | `decision` | `runDecision` | non-null JSON state plus declared questions | typed choices, probabilities, scores, or `noul` | `systemOne` |
@@ -294,7 +294,7 @@ The binding under `models` names the protocol, the registered provider ID, and t
294
294
  | Provider | ID | Protocols |
295
295
  | :--- | :--- | :--- |
296
296
  | `geminiProvider` | `gemini` | `geminiInteractions` (text, image, speech), `geminiLive` (live) |
297
- | `openRouterProvider` | `openrouter` | `openRouter` (text, speech), `openRouterImages` (image), `systemOne` (decision) |
297
+ | `openRouterProvider` | `openrouter` | `openRouterOpenAi` (text, speech), `openRouterImages` (image), `openRouterDecisions` (decision) |
298
298
  | `typesafeProvider` | `typesafe` | `systemOne` (decision) |
299
299
  | `localProvider` | `local` | `openAi` (text, speech), for a server such as Ollama |
300
300
 
@@ -468,7 +468,7 @@ Named exports from the root barrel (same symbols hosts get from `@theoremjs/agen
468
468
  | Observability | `memorySink`, `noopSink`, `readTraceparent`, `writeTrace`, `buildRecord`, `traceRecordSchema`, `contentOf`, `inlineContent`, `toOtlpJson`, `startTrace`, `traceContent`, `traceBytes`, `traceJson`, `registerTraceDestination`, `requireTraceDestination`, `getTraceDestination`, `listTraceDestinationIds`, `clearTraceDestinations`, `isTraceSink`, `resolveTraceWriter`, `resolveObservabilityPolicy`, `traceSpanMeta`, `traceAttributeMeta`, `traceEventMeta`, `traceEventAttributeMeta`, `TRACE_ATTRIBUTE_GROUPS`, `TRACE_STATUS`, `TRACE_FIELDS`, `TRACE_SPAN_TYPES`, `TraceSpanMeta`, `TraceSpanType`, `TraceAttributeMeta`, `TraceEventMeta`, `TraceOptionMeta`, `TraceAttributeGroup`, `TraceValueFormat`, `TraceRecord`, `TraceSink`, `TraceWriteContext`, `TraceSpan`, `TraceSpanEvent`, `TraceSpanKind`, `TraceSpanLink`, `TraceSpanStatus`, `TraceAttributes`, `TraceAttributeValue`, `TraceContent`, `TraceBytes`, `TraceJson`, `TraceTree`, `SpanHandle`, `SpanOptions`, `SpanLinkInput`, `TraceClock`, `ProfileObservabilitySpec`, `ResolvedObservabilityPolicy`, `ResolvedTraceInclude`, `ResolvedTraceScrub`, `TraceIncludeSpec`, `TraceScrubSpec`, `ScrubSwitch`, `ResolvedScrubSwitch`, `OtlpTraceRequest`, `OtlpSpan`, `OtlpKeyValue`, `OtlpAnyValue` (file sink: `@theoremjs/agents/observability/jsonl` → `jsonlSink`, `JsonlSinkOptions`) |
469
469
  | Providers | `registerProvider`, `getProvider`, `listProviders`, `listProtocols`, `createProviderRegistry`, `defineProvider`, `Provider`, `ProviderDefinition`, `Registration`, `RegisteredProvider`, `ProviderRegistry`, `geminiProvider`, `openRouterProvider`, `typesafeProvider`, `localProvider` |
470
470
  | Provider sign-in | `bearer`, `header`, `query`, `Authorize`, `Signer`, `Outgoing`, `Serve`, `endpointUrlSchema` |
471
- | Protocols | `defineProtocol`, `extendProtocol`, `carriesTo`, `modelOptions`, `geminiInteractions`, `geminiLive`, `geminiEmbedding`, `openAi`, `openRouter`, `openRouterImages`, `openRouterEmbedding`, `ollamaEmbedding`, `systemOne`, `Protocol`, `ProtocolDefinition`, `ProtocolExtension`, `ExtensionBodyAt`, `ExtensionReader`, `ModelProfileType` |
471
+ | Protocols | `defineProtocol`, `extendProtocol`, `carriesTo`, `modelOptions`, `geminiInteractions`, `geminiLive`, `geminiEmbedding`, `openAi`, `openRouterOpenAi`, `openRouterImages`, `openRouterDecisions`, `openRouterEmbedding`, `ollamaEmbedding`, `systemOne`, `Protocol`, `ProtocolDefinition`, `ProtocolExtension`, `ExtensionBodyAt`, `ExtensionReader`, `ModelProfileType` |
472
472
  | Protocol operations | `ProtocolContext`, `ProtocolOperations`, `ProtocolRequest`, `ProtocolSession`, `ProtocolSocket`, `ProtocolEvent`, `ProtocolContentEvent`, `SendInit`, `UpstreamFailure`, `Continuation`, `DecisionCall`, `EmbeddingCall`, `LiveToolResult`, `callProtocol`, `ProtocolCall`, `CallSetup` |
473
473
  | Model bindings | `ModelBinding`, `DecisionModelBinding`, `modelBindingSchema`, `decisionModelBindingSchema`, `commonModelSettingsSchema`, `keySlotSchema`, `checkBinding`, `keySlotsOf`, `RuntimeAbilities` |
474
474
  | Provider data | `JsonValue`, `JsonObject`, `jsonValueSchema`, `jsonObjectSchema`, `PriceTable`, `ModelPrice`, `Rates` |
@@ -512,7 +512,7 @@ Four properties are invariant. Where a test or a lint checks one, the table name
512
512
  | P3 | No buried policy — behavioral defaults are declared profile-schema fields | `PROFILE_FIELDS` / schema |
513
513
  | P4 | Inert extras — optional entrypoints removable without behavior change | publish-bundle gate excludes `studio/` |
514
514
 
515
- Provider definition and registration validate without opening transport (`src/kernel/protocols/provider.ts`). A protocol never holds a key, a key slot, or a base URL. The kernel signs each request with the registered provider's sign-in.
515
+ Provider definition and registration validate without opening transport (`src/kernel/protocols/provider.ts`). A protocol never holds a key, a key slot, or a base URL. The kernel signs each request with the registered provider's sign-in. A protocol that extends another, as `openRouterDecisions` extends `systemOne`, has its own id, and a binding names the one its provider serves.
516
516
 
517
517
  Domain rules, delivery policy, product copy, database access, and session memory belong in your application, not in Theorem.
518
518
 
@@ -23,7 +23,7 @@ function registerFuzzCanaryProfile() {
23
23
  identity: { handle: 'fuzz-canary', system: 'Canary fuzz profile.' },
24
24
  models: {
25
25
  'fuzz-model': {
26
- protocol: 'openRouter',
26
+ protocol: 'openRouterOpenAi',
27
27
  provider: 'openrouter',
28
28
  apiId: 'fuzz-model',
29
29
  keySlot: 'fuzz',
@@ -3,7 +3,7 @@ import { getProfile, registerStructured, runDecision, runTurn, } from '../../ker
3
3
  import { mimeAllowed, profileAccept } from '../../kernel/registry/catalog.js';
4
4
  import { isRecord } from '../../kernel/util/record.js';
5
5
  import { memorySink } from '../../observability/trace.js';
6
- import { formatTraceparent } from '../../observability/trace-span.js';
6
+ import { formatTraceparent, recordRoot } from '../../observability/trace-span.js';
7
7
  import { fillRubric } from '../rubrics/types.js';
8
8
  import { buildTrial } from '../trial.js';
9
9
  import { resolveMedia, trialMedia } from './media.js';
@@ -70,9 +70,7 @@ function judgeKind(grader, rubric, profileId) {
70
70
  return 'text';
71
71
  }
72
72
  function traceparentsOf(records) {
73
- const spans = records[0]?.spans ?? [];
74
- const ids = new Set(spans.map((span) => span.spanId));
75
- const root = spans.find((span) => span.parentSpanId === undefined || !ids.has(span.parentSpanId));
73
+ const root = records[0] && recordRoot(records[0]);
76
74
  return root ? [formatTraceparent(root.traceId, root.spanId)] : [];
77
75
  }
78
76
  function judgeStamp(trial, grader) {
@@ -2,7 +2,7 @@ import type { RunDecisionOptions } from '../kernel/engine/decision.js';
2
2
  import type { ProviderHostOptions } from '../kernel/protocols/runtime.js';
3
3
  import type { TraceRecord } from '../observability/trace-record.js';
4
4
  import type { TraceSink } from '../observability/trace-sink.js';
5
- import type { TraceClock } from '../observability/trace-span.js';
5
+ import { type TraceClock } from '../observability/trace-span.js';
6
6
  import type { LoadedSuite } from './suite.js';
7
7
  import type { EvalCase, EvalMediaResolver, EvalPassRule, EvalResult } from './types.js';
8
8
  import { type CaseVerdict, type TrialOutcome } from './verdict.js';
@@ -4,6 +4,7 @@ import { isModelProfile } from '../kernel/registry/resolve.js';
4
4
  import { isRecord } from '../kernel/util/record.js';
5
5
  import { resolveObservabilityPolicy } from '../observability/resolve-policy.js';
6
6
  import { memorySink, writeTrace } from '../observability/trace.js';
7
+ import { recordRoot } from '../observability/trace-span.js';
7
8
  import { attachmentData } from './attachments.js';
8
9
  import { modelCalls, spanDurationMs } from './graders/shared.js';
9
10
  import { buildRunRecord, startTrialRecord } from './record.js';
@@ -63,11 +64,6 @@ function erroredResults(graders, evalCase, error) {
63
64
  errorType: error,
64
65
  }));
65
66
  }
66
- /** The record's root: the span no other span in it parents (a judge call's root has the trial span above it). */
67
- function recordRoot(record) {
68
- const ids = new Set(record.spans.map((span) => span.spanId));
69
- return record.spans.find((span) => span.parentSpanId === undefined || !ids.has(span.parentSpanId));
70
- }
71
67
  function recordCost(record) {
72
68
  const attributes = recordRoot(record)?.attributes;
73
69
  const cost = attributes?.['theorem.usage.cost_usd'];
@@ -17,7 +17,7 @@ function registerFuzzProfile() {
17
17
  identity: { handle: 'fuzz', system: 'Fuzz profile.' },
18
18
  models: {
19
19
  'fuzz-model': {
20
- protocol: 'openRouter',
20
+ protocol: 'openRouterOpenAi',
21
21
  provider: 'openrouter',
22
22
  apiId: 'fuzz-model',
23
23
  keySlot: 'fuzz',
@@ -18,5 +18,5 @@ export { buildRecord, contentOf, inlineContent } from './trace-record.js';
18
18
  export { traceRecordSchema } from './trace-schema.js';
19
19
  export type { TraceSink, TraceWriteContext } from './trace-sink.js';
20
20
  export type { SpanHandle, SpanLinkInput, SpanOptions, TraceAttributes, TraceAttributeValue, TraceBytes, TraceClock, TraceContent, TraceJson, TraceSpan, TraceSpanEvent, TraceSpanKind, TraceSpanLink, TraceSpanStatus, TraceTree, } from './trace-span.js';
21
- export { readTraceparent, startTrace, traceBytes, traceContent, traceJson, } from './trace-span.js';
21
+ export { readTraceparent, recordRoot, startTrace, traceBytes, traceContent, traceJson, } from './trace-span.js';
22
22
  export type { ProfileObservabilitySpec, ResolvedObservabilityPolicy, ResolvedScrubSwitch, ResolvedTraceInclude, ResolvedTraceScrub, ScrubSwitch, TraceIncludeSpec, TraceScrubSpec, } from './types.js';
@@ -13,4 +13,4 @@ export { memorySink, noopSink, writeTrace, } from './trace.js';
13
13
  export { TRACE_ATTRIBUTE_GROUPS, TRACE_FIELDS, TRACE_SPAN_TYPES, TRACE_STATUS, traceAttributeMeta, traceCatalogRows, traceEventAttributeMeta, traceEventMeta, traceSpanMeta, } from './trace-catalog.js';
14
14
  export { buildRecord, contentOf, inlineContent } from './trace-record.js';
15
15
  export { traceRecordSchema } from './trace-schema.js';
16
- export { readTraceparent, startTrace, traceBytes, traceContent, traceJson, } from './trace-span.js';
16
+ export { readTraceparent, recordRoot, startTrace, traceBytes, traceContent, traceJson, } from './trace-span.js';
@@ -1,4 +1,4 @@
1
- import type { TraceAttributes, TraceAttributeValue, TraceSpan, TraceSpanEvent, TraceSpanKind, TraceSpanLink, TraceSpanStatus } from './trace-schema.js';
1
+ import type { TraceAttributes, TraceAttributeValue, TraceRecord, TraceSpan, TraceSpanEvent, TraceSpanKind, TraceSpanLink, TraceSpanStatus } from './trace-schema.js';
2
2
  /** In-memory text awaiting scrub + hash at record build. */
3
3
  interface TraceContent {
4
4
  [key: string]: TraceAttributeValue;
@@ -94,5 +94,10 @@ declare function startTrace(name: string, options?: SpanOptions & {
94
94
  traceparent?: string;
95
95
  clock?: TraceClock;
96
96
  }): TraceTree;
97
+ /**
98
+ * The record's root: the span no other span in it parents. It may hang under a span that lives
99
+ * elsewhere: a host's own span over the turn, or an eval's trial span over a judge call.
100
+ */
101
+ declare function recordRoot(record: TraceRecord): TraceSpan | undefined;
97
102
  export type { SpanHandle, SpanLinkInput, SpanOptions, TraceAttributes, TraceAttributeValue, TraceBytes, TraceClock, TraceContent, TraceJson, TraceSpan, TraceSpanEvent, TraceSpanKind, TraceSpanLink, TraceSpanStatus, TraceTree, };
98
- export { formatTraceparent, isTraceBytes, isTraceContent, isTraceJson, parseTraceparent, readTraceparent, startTrace, traceBytes, traceContent, traceJson, };
103
+ export { formatTraceparent, isTraceBytes, isTraceContent, isTraceJson, parseTraceparent, readTraceparent, recordRoot, startTrace, traceBytes, traceContent, traceJson, };
@@ -198,4 +198,12 @@ function startTrace(name, options = {}) {
198
198
  },
199
199
  };
200
200
  }
201
- export { formatTraceparent, isTraceBytes, isTraceContent, isTraceJson, parseTraceparent, readTraceparent, startTrace, traceBytes, traceContent, traceJson, };
201
+ /**
202
+ * The record's root: the span no other span in it parents. It may hang under a span that lives
203
+ * elsewhere: a host's own span over the turn, or an eval's trial span over a judge call.
204
+ */
205
+ function recordRoot(record) {
206
+ const ids = new Set(record.spans.map((span) => span.spanId));
207
+ return record.spans.find((span) => span.parentSpanId === undefined || !ids.has(span.parentSpanId));
208
+ }
209
+ export { formatTraceparent, isTraceBytes, isTraceContent, isTraceJson, parseTraceparent, readTraceparent, recordRoot, startTrace, traceBytes, traceContent, traceJson, };
@@ -24,9 +24,10 @@ export { geminiProvider } from './gemini/provider.js';
24
24
  export { ollamaEmbedding } from './local/embedding-protocol.js';
25
25
  export { localProvider } from './local/provider.js';
26
26
  export { openAi } from './open-ai/protocol.js';
27
+ export { openRouterDecisions } from './openrouter/decisions-protocol.js';
27
28
  export { openRouterEmbedding } from './openrouter/embedding-protocol.js';
28
29
  export { openRouterImages } from './openrouter/images-protocol.js';
29
- export { openRouter } from './openrouter/protocol.js';
30
+ export { openRouterOpenAi } from './openrouter/protocol.js';
30
31
  export { openRouterProvider } from './openrouter/provider.js';
31
32
  export { systemOne } from './system-one/protocol.js';
32
33
  export { typesafeProvider } from './typesafe/provider.js';
@@ -15,9 +15,10 @@ export { geminiProvider } from './gemini/provider.js';
15
15
  export { ollamaEmbedding } from './local/embedding-protocol.js';
16
16
  export { localProvider } from './local/provider.js';
17
17
  export { openAi } from './open-ai/protocol.js';
18
+ export { openRouterDecisions } from './openrouter/decisions-protocol.js';
18
19
  export { openRouterEmbedding } from './openrouter/embedding-protocol.js';
19
20
  export { openRouterImages } from './openrouter/images-protocol.js';
20
- export { openRouter } from './openrouter/protocol.js';
21
+ export { openRouterOpenAi } from './openrouter/protocol.js';
21
22
  export { openRouterProvider } from './openrouter/provider.js';
22
23
  export { systemOne } from './system-one/protocol.js';
23
24
  export { typesafeProvider } from './typesafe/provider.js';
@@ -0,0 +1,4 @@
1
+ import { type Protocol } from '../../kernel/protocols/mod.js';
2
+ import { type SystemOneOptions } from '../system-one/protocol.js';
3
+ /** OpenRouter's decision API: System One's questions and answers, at OpenRouter's own endpoint. */
4
+ export declare const openRouterDecisions: Protocol<SystemOneOptions>;
@@ -0,0 +1,9 @@
1
+ import { extendProtocol } from '../../kernel/protocols/mod.js';
2
+ import { systemOne } from '../system-one/protocol.js';
3
+ /** OpenRouter's decision API: System One's questions and answers, at OpenRouter's own endpoint. */
4
+ export const openRouterDecisions = extendProtocol(systemOne, {
5
+ id: 'openRouterDecisions',
6
+ name: 'OpenRouter Decisions',
7
+ description: "OpenRouter's decision API: questions about a state, answered in one call.", // labels-exempt: builder field description, read by the studio and docs
8
+ endpoints: { decision: '/alpha/decisions' },
9
+ });
@@ -1,8 +1,8 @@
1
1
  import { type Protocol } from '../../kernel/protocols/mod.js';
2
2
  import type { CacheSpec } from '../../kernel/types.js';
3
- /** What an `openRouter` binding sets in `options`. */
3
+ /** What an `openRouterOpenAi` binding sets in `options`. */
4
4
  export interface OpenRouterOptions {
5
5
  cache?: CacheSpec;
6
6
  }
7
7
  /** Chat Completions with OpenRouter's caching, routing, web search, citations, and reasoning. */
8
- export declare const openRouter: Protocol<OpenRouterOptions>;
8
+ export declare const openRouterOpenAi: Protocol<OpenRouterOptions>;
@@ -93,8 +93,8 @@ function thinking(row) {
93
93
  .join('');
94
94
  }
95
95
  /** Chat Completions with OpenRouter's caching, routing, web search, citations, and reasoning. */
96
- export const openRouter = extendProtocol(openAi, {
97
- id: 'openRouter',
96
+ export const openRouterOpenAi = extendProtocol(openAi, {
97
+ id: 'openRouterOpenAi',
98
98
  name: 'OpenRouter Chat Completions',
99
99
  description: "Chat Completions with OpenRouter's caching, routing, web search, citations and reasoning.", // labels-exempt: builder field description, read by the studio and docs
100
100
  options: z.strictObject({ cache: cache.optional() }),
@@ -1,9 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  import { bearer, defineProvider, endpointUrlSchema, } from '../../kernel/protocols/provider.js';
3
- import { systemOne } from '../system-one/protocol.js';
3
+ import { openRouterDecisions } from './decisions-protocol.js';
4
4
  import { openRouterEmbedding } from './embedding-protocol.js';
5
5
  import { openRouterImages } from './images-protocol.js';
6
- import { openRouter } from './protocol.js';
6
+ import { openRouterOpenAi } from './protocol.js';
7
7
  const connection = z.strictObject({
8
8
  baseUrl: endpointUrlSchema
9
9
  .optional()
@@ -41,10 +41,10 @@ export const openRouterProvider = defineProvider({
41
41
  headers['X-Title'] = at.siteName;
42
42
  const decisionUrl = at.decisionUrl ?? 'https://openrouter.ai/api/alpha/decisions';
43
43
  return [
44
- { protocol: openRouter, baseUrl, headers },
44
+ { protocol: openRouterOpenAi, baseUrl, headers },
45
45
  { protocol: openRouterEmbedding, baseUrl, headers },
46
46
  { protocol: openRouterImages, baseUrl, headers },
47
- { protocol: systemOne, baseUrl: decisionUrl, url: () => decisionUrl, headers },
47
+ { protocol: openRouterDecisions, baseUrl: decisionUrl, url: () => decisionUrl, headers },
48
48
  ];
49
49
  },
50
50
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theoremjs/agents",
3
- "version": "0.3.4-next.476.g46e6627",
3
+ "version": "0.3.4-next.480.ge8c8d47",
4
4
  "description": "A flat TypeScript agent kernel for typed profiles, deterministic turn execution, registered tools, provider adapters, guardrails, and host-injected traces.",
5
5
  "keywords": [
6
6
  "agent",