@owlmeans/llm-common 0.1.14

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 ADDED
@@ -0,0 +1,106 @@
1
+ # @owlmeans/llm-common
2
+
3
+ Serializable contracts for LLM inference and execution. Runtime-free — it holds the enums,
4
+ policy shapes and record formats that both an inference runtime (`@owlmeans/llm`) and a
5
+ persistence/queue consumer need to name the same things.
6
+
7
+ ## Overview
8
+
9
+ - Provider identifiers, effort tiers, execution levels and structured-output modes
10
+ - The inheritable `ModelPolicy` and its JSON-safe `ModelConfigPatch` / `ModelConfigOverride`
11
+ - `ExecutionState` / `TaskExecutionState` — what an execution looks like once its
12
+ collaborators (models, file access, live handles) are stripped off
13
+ - Spectator record contracts and the `NullCapture` diagnostic
14
+ - No `@langchain/*` runtime dependency: safe to import from a browser bundle, a queue
15
+ worker, or a package that must not pull an inference SDK
16
+
17
+ Split rationale: the dependency direction is one-way. A consumer's own contracts package
18
+ extends these; `@owlmeans/llm` implements against them.
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ bun add @owlmeans/llm-common
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ Naming a role and a policy without depending on any inference runtime:
29
+
30
+ ```typescript
31
+ import { ExecutionEffort, ModelProvider } from '@owlmeans/llm-common'
32
+ import type { ModelPolicy } from '@owlmeans/llm-common'
33
+
34
+ export enum MyRole {
35
+ Analyst = 'analyst',
36
+ Coder = 'coder',
37
+ }
38
+
39
+ export const DEFAULT_POLICY: ModelPolicy = {
40
+ effort: ExecutionEffort.Standard,
41
+ modelOverrides: { [MyRole.Coder]: { maxTokens: 16000 } },
42
+ }
43
+ ```
44
+
45
+ Extending the serializable state with domain context:
46
+
47
+ ```typescript
48
+ import type { ExecutionState, LlmPurpose } from '@owlmeans/llm-common'
49
+
50
+ export interface MyPurpose extends LlmPurpose {
51
+ agent?: string
52
+ }
53
+
54
+ export interface MyExecutionState extends ExecutionState {
55
+ purpose: MyPurpose
56
+ projectId?: string
57
+ }
58
+ ```
59
+
60
+ ## API
61
+
62
+ ### Constants
63
+
64
+ | Export | Description |
65
+ |--------|-------------|
66
+ | `ModelProvider` | `OpenAI` · `Anthropic` · `Compatible` — each maps to an `LlmPlugin` type in `@owlmeans/llm`. |
67
+ | `ExecutionLevel` | `Project` → `Task` → `Helper`; an execution is refined downward only. |
68
+ | `ExecutionEffort` | `Economy` · `Standard` · `High` · `Max` — the one "how hard should this run" axis. |
69
+ | `StructuredMode` | `Native` (provider JSON-schema mode) vs `Tool` (forced tool call). |
70
+ | `SpectatorContentType` | `Text` · `Json` · `ToolCall`. |
71
+ | `SPECTATOR_GENERAL` | Default entry kind for consumers that do not classify calls. |
72
+
73
+ ### Types
74
+
75
+ | Export | Description |
76
+ |--------|-------------|
77
+ | `ModelRole` | Open `string`. Declare your own enum; its values stay assignable. |
78
+ | `ModelConfigPatch` | JSON-safe subset of a runtime model config — never credentials. |
79
+ | `ModelConfigOverride` | `string` (a config alias) or a `ModelConfigPatch`. |
80
+ | `ModelPolicy` | `{ effort, roleOverrides?, modelOverrides? }` — inherited by every refinement. |
81
+ | `ExecutionState` | `{ level, purpose, policy }` — the persistable core. |
82
+ | `TaskExecutionState` | Adds `phase` / `completed` / `cursor` / `data` for checkpoint & resume. |
83
+ | `LlmPurpose` | `{ type?, dedication? }` — observability metadata carried on every call. |
84
+ | `NullCapture`, `NullKind` | Full diagnostics of a call that returned nothing usable. |
85
+ | `SpectatorArgument`, `SpectatorEntry`, `SpectatorEntryLogged`, `SpectatorEntryMessage` | The record format an observability sink stores. |
86
+
87
+ ## Related
88
+
89
+ - `@owlmeans/llm` — the runtime: model, provider plugins, model factory, execution service
90
+
91
+ <!-- owlmeans:agent-guidance:start -->
92
+ ## Agent guidance
93
+
94
+ This package ships embedded Claude Code skills and GitHub Copilot instructions under
95
+ `agent-meta/`. After installing your `@owlmeans/*` packages, run the OwlMeans
96
+ agent-skills installer to place them into your project's native locations
97
+ (`.claude/skills/` and `.github/instructions/`):
98
+
99
+ ```sh
100
+ npx @owlmeans/agent-skills
101
+ ```
102
+
103
+ The embedded files are version-matched to this package release. Do not edit them
104
+ directly — they are regenerated on each publish. To contribute guidance edits,
105
+ open a PR against the source monorepo.
106
+ <!-- owlmeans:agent-guidance:end -->
@@ -0,0 +1,53 @@
1
+ ---
2
+ description: "How to use @owlmeans/llm-common — runtime-free serializable contracts for LLM inference and execution, and how to extend them for a domain."
3
+ applyTo: "**/*.ts, **/*.tsx"
4
+ ---
5
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
6
+
7
+ # @owlmeans/llm-common
8
+
9
+ **Layer:** Core
10
+ **Install:** `"@owlmeans/llm-common": "^0.1.14"` in `dependencies`
11
+
12
+ The contracts half of the LLM stack. **No `@langchain/*` runtime dependency** — importable
13
+ from a browser bundle or a queue worker. Dependency direction is one-way: a domain contracts
14
+ package extends these; `@owlmeans/llm` implements against them.
15
+
16
+ ## Key Exports
17
+
18
+ | Export | Description |
19
+ |--------|-------------|
20
+ | `ModelProvider` | `OpenAI` · `Anthropic` · `Compatible` — each is an `LlmPlugin.type`. |
21
+ | `ExecutionLevel` / `ExecutionEffort` | `Project`→`Task`→`Helper`; `Economy`/`Standard`/`High`/`Max`. |
22
+ | `StructuredMode` | `Native` vs `Tool` structured output. |
23
+ | `ModelRole` | Open `string` — declare your own enum. |
24
+ | `ModelConfigPatch` / `ModelConfigOverride` / `ModelPolicy` | JSON-safe model selection. |
25
+ | `ExecutionState` / `TaskExecutionState` | The persistable execution core + resumable fields. |
26
+ | `LlmPurpose` | `{ type?, dedication? }` observability metadata. |
27
+ | `NullCapture`, `NullKind` | Diagnostics of a call that returned nothing usable. |
28
+ | `SpectatorArgument` / `SpectatorEntry` / `SpectatorEntryLogged` / `SpectatorEntryMessage`, `SpectatorContentType` | Observability records. |
29
+
30
+ ## Rules
31
+
32
+ - Extend, never fork: `interface MyPurpose extends LlmPurpose`,
33
+ `interface MyExecutionState extends ExecutionState`.
34
+ - For a domain task state, take the base fields from your own `ExecutionState` and mix in
35
+ only the resumable half: `Omit<TaskExecutionState, keyof ExecutionState>`.
36
+ - `ModelRole` and `SpectatorEntry.kind` are open strings so a consumer's enum stays
37
+ assignable — narrow them on your own interfaces.
38
+ - Nothing that fails `JSON.stringify` belongs here: no model instances, credentials, file
39
+ handles or callbacks. `ModelConfig` (with `secret`/`headers`/`fallback`) lives in
40
+ `@owlmeans/llm`.
41
+
42
+ ## Usage
43
+
44
+ ```typescript
45
+ import { ExecutionEffort } from '@owlmeans/llm-common'
46
+ import type { ModelPolicy } from '@owlmeans/llm-common'
47
+
48
+ export const DEFAULT_POLICY: ModelPolicy = { effort: ExecutionEffort.Standard }
49
+ ```
50
+
51
+ ## Depends On
52
+
53
+ Nothing at runtime (`@langchain/core` is a dev dependency, for one type).
@@ -0,0 +1,23 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "package": "@owlmeans/llm-common",
4
+ "version": "0.1.14",
5
+ "generatedAt": "2026-08-05T16:56:53.384Z",
6
+ "canonicalRepo": "https://github.com/owlmeans/common",
7
+ "entries": [
8
+ {
9
+ "kind": "skill",
10
+ "name": "llm-common",
11
+ "category": "package-specific",
12
+ "file": "skills/llm-common/SKILL.md",
13
+ "canonicalPath": ".claude/skills/llm-common/SKILL.md"
14
+ },
15
+ {
16
+ "kind": "instruction",
17
+ "name": "llm-common",
18
+ "category": "package-specific",
19
+ "file": "instructions/llm-common.instructions.md",
20
+ "canonicalPath": ".github/instructions/llm-common.instructions.md"
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: llm-common
3
+ description: How to use @owlmeans/llm-common — runtime-free serializable contracts for LLM inference and execution (ModelProvider, ExecutionEffort/Level, ModelPolicy, ExecutionState, spectator records, NullCapture). Auto-invoked when importing those contracts or extending them for a domain.
4
+ user-invocable: false
5
+ ---
6
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
7
+
8
+ # @owlmeans/llm-common
9
+
10
+ **Layer:** Core
11
+ **Install:** `"@owlmeans/llm-common": "^0.1.14"` in `dependencies`
12
+
13
+ The contracts half of the LLM stack. **No `@langchain/*` runtime dependency** — importable
14
+ from a browser bundle, a queue worker, or any package that must not pull an inference SDK.
15
+ The dependency direction is one-way: a domain contracts package extends these;
16
+ `@owlmeans/llm` implements against them.
17
+
18
+ ## Key Exports
19
+
20
+ | Export | Description |
21
+ |--------|-------------|
22
+ | `ModelProvider` | `OpenAI` · `Anthropic` · `Compatible`. Each value is an `LlmPlugin.type` in `@owlmeans/llm`. |
23
+ | `ExecutionLevel` | `Project` → `Task` → `Helper`. Refinement is downward only. |
24
+ | `ExecutionEffort` | `Economy` · `Standard` · `High` · `Max` — the single "how hard should this run" axis. |
25
+ | `StructuredMode` | `Native` (provider JSON-schema mode) vs `Tool` (forced tool call). |
26
+ | `SpectatorContentType`, `SPECTATOR_GENERAL` | Observability record enums/defaults. |
27
+ | `ModelRole` | Open `string` — declare your own enum, its values stay assignable. |
28
+ | `ModelConfigPatch` / `ModelConfigOverride` | The JSON-safe config subset; never credentials. |
29
+ | `ModelPolicy` | `{ effort, roleOverrides?, modelOverrides? }` — inherited by every refinement. |
30
+ | `ExecutionState` / `TaskExecutionState` | The persistable core (`level`/`purpose`/`policy`, plus `phase`/`completed`/`cursor`/`data`). |
31
+ | `LlmPurpose` | `{ type?, dedication? }` — metadata carried on every model call. |
32
+ | `NullCapture`, `NullKind` | Full diagnostics of a call that returned nothing usable. |
33
+ | `SpectatorArgument`, `SpectatorEntry`, `SpectatorEntryLogged`, `SpectatorEntryMessage` | What an observability sink stores. |
34
+
35
+ ## Extension rules
36
+
37
+ Open types are open **on purpose** — extend, do not fork:
38
+
39
+ ```typescript
40
+ // Your roles: an enum whose values satisfy the open `ModelRole` string.
41
+ export enum MyRole { Analyst = 'analyst', Coder = 'coder' }
42
+
43
+ // Your purpose and state: extend, never redeclare.
44
+ export interface MyPurpose extends LlmPurpose { agent?: string }
45
+ export interface MyExecutionState extends ExecutionState {
46
+ purpose: MyPurpose
47
+ projectId?: string
48
+ }
49
+
50
+ // A task state adds domain fields to the RESUMABLE half only — the base fields
51
+ // come from your own ExecutionState, so omit them from the llm task state.
52
+ export interface MyTaskState
53
+ extends MyExecutionState, Omit<LlmTaskExecutionState, keyof LlmExecutionState> {
54
+ story?: Story
55
+ }
56
+ ```
57
+
58
+ `SpectatorEntry.kind` is an open `string` for the same reason: declare your own kind enum
59
+ and narrow it on your own entry interface.
60
+
61
+ ## What must NOT go here
62
+
63
+ Anything that cannot survive `JSON.stringify` or that needs an inference SDK: model
64
+ instances, credentials, file handles, callbacks, `ModelConfig` (it carries `secret` /
65
+ `headers` / `fallback` — that lives in `@owlmeans/llm`).
66
+
67
+ ## Depends On
68
+
69
+ Nothing at runtime. `@langchain/core` is a **dev** dependency, for the `UsageMetadata` type
70
+ on a spectator message only.
71
+
72
+ ## Related
73
+
74
+ - [[llm]] — the runtime that implements these contracts
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Inference provider family a {@link ModelConfigPatch}/config targets. Each value is
3
+ * the `type` of an `LlmPlugin` registered in `@owlmeans/llm`; a downstream package
4
+ * can register additional plugins under its own type string.
5
+ */
6
+ export declare enum ModelProvider {
7
+ /** Proprietary OpenAI endpoint (Responses API for the `gpt-5*` / `codex-*` families). */
8
+ OpenAI = "openai",
9
+ /** Anthropic messages API. */
10
+ Anthropic = "anthropic",
11
+ /** Any OpenAI-compatible endpoint — OpenRouter, HuggingFace router, Together, vLLM, … */
12
+ Compatible = "compatible"
13
+ }
14
+ /**
15
+ * Refinement level of an execution. An execution is refined downward only:
16
+ * root → task → helper, each step producing a new frozen object.
17
+ */
18
+ export declare enum ExecutionLevel {
19
+ Project = "project",
20
+ Task = "task",
21
+ Helper = "helper"
22
+ }
23
+ /**
24
+ * Orthogonal capability tier carried by a {@link ModelPolicy} — the single,
25
+ * inheritable "how hard should this run" axis. Maps to a JSON-safe model config
26
+ * patch through the effort table in `@owlmeans/llm`.
27
+ */
28
+ export declare enum ExecutionEffort {
29
+ Economy = "economy",
30
+ Standard = "standard",
31
+ High = "high",
32
+ Max = "max"
33
+ }
34
+ /**
35
+ * How a model is asked to produce a schema-conforming object.
36
+ *
37
+ * - `Native` — the provider's own JSON-schema mode
38
+ * (`response_format: { type: 'json_schema' }`).
39
+ * - `Tool` — the forced-`tool_choice` tool-calling hack: a synthetic function whose
40
+ * parameters ARE the schema, with the tool choice pinned to it.
41
+ *
42
+ * The decision is per provider plugin, overridable per model config.
43
+ */
44
+ export declare enum StructuredMode {
45
+ Native = "native",
46
+ Tool = "tool"
47
+ }
48
+ /** Content shape of a single logged spectator message. */
49
+ export declare enum SpectatorContentType {
50
+ Text = "text",
51
+ Json = "json",
52
+ ToolCall = "tool_call"
53
+ }
54
+ /** Default spectator entry kind for consumers that do not classify their calls. */
55
+ export declare const SPECTATOR_GENERAL = "general";
56
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,oBAAY,aAAa;IACvB,yFAAyF;IACzF,MAAM,WAAW;IACjB,8BAA8B;IAC9B,SAAS,cAAc;IACvB,yFAAyF;IACzF,UAAU,eAAe;CAC1B;AAED;;;GAGG;AACH,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED;;;;GAIG;AACH,oBAAY,eAAe;IACzB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,GAAG,QAAQ;CACZ;AAED;;;;;;;;;GASG;AACH,oBAAY,cAAc;IACxB,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED,0DAA0D;AAC1D,oBAAY,oBAAoB;IAC9B,IAAI,SAAS;IACb,IAAI,SAAS;IACb,QAAQ,cAAc;CACvB;AAED,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,YAAY,CAAA"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Inference provider family a {@link ModelConfigPatch}/config targets. Each value is
3
+ * the `type` of an `LlmPlugin` registered in `@owlmeans/llm`; a downstream package
4
+ * can register additional plugins under its own type string.
5
+ */
6
+ export var ModelProvider;
7
+ (function (ModelProvider) {
8
+ /** Proprietary OpenAI endpoint (Responses API for the `gpt-5*` / `codex-*` families). */
9
+ ModelProvider["OpenAI"] = "openai";
10
+ /** Anthropic messages API. */
11
+ ModelProvider["Anthropic"] = "anthropic";
12
+ /** Any OpenAI-compatible endpoint — OpenRouter, HuggingFace router, Together, vLLM, … */
13
+ ModelProvider["Compatible"] = "compatible";
14
+ })(ModelProvider || (ModelProvider = {}));
15
+ /**
16
+ * Refinement level of an execution. An execution is refined downward only:
17
+ * root → task → helper, each step producing a new frozen object.
18
+ */
19
+ export var ExecutionLevel;
20
+ (function (ExecutionLevel) {
21
+ ExecutionLevel["Project"] = "project";
22
+ ExecutionLevel["Task"] = "task";
23
+ ExecutionLevel["Helper"] = "helper";
24
+ })(ExecutionLevel || (ExecutionLevel = {}));
25
+ /**
26
+ * Orthogonal capability tier carried by a {@link ModelPolicy} — the single,
27
+ * inheritable "how hard should this run" axis. Maps to a JSON-safe model config
28
+ * patch through the effort table in `@owlmeans/llm`.
29
+ */
30
+ export var ExecutionEffort;
31
+ (function (ExecutionEffort) {
32
+ ExecutionEffort["Economy"] = "economy";
33
+ ExecutionEffort["Standard"] = "standard";
34
+ ExecutionEffort["High"] = "high";
35
+ ExecutionEffort["Max"] = "max";
36
+ })(ExecutionEffort || (ExecutionEffort = {}));
37
+ /**
38
+ * How a model is asked to produce a schema-conforming object.
39
+ *
40
+ * - `Native` — the provider's own JSON-schema mode
41
+ * (`response_format: { type: 'json_schema' }`).
42
+ * - `Tool` — the forced-`tool_choice` tool-calling hack: a synthetic function whose
43
+ * parameters ARE the schema, with the tool choice pinned to it.
44
+ *
45
+ * The decision is per provider plugin, overridable per model config.
46
+ */
47
+ export var StructuredMode;
48
+ (function (StructuredMode) {
49
+ StructuredMode["Native"] = "native";
50
+ StructuredMode["Tool"] = "tool";
51
+ })(StructuredMode || (StructuredMode = {}));
52
+ /** Content shape of a single logged spectator message. */
53
+ export var SpectatorContentType;
54
+ (function (SpectatorContentType) {
55
+ SpectatorContentType["Text"] = "text";
56
+ SpectatorContentType["Json"] = "json";
57
+ SpectatorContentType["ToolCall"] = "tool_call";
58
+ })(SpectatorContentType || (SpectatorContentType = {}));
59
+ /** Default spectator entry kind for consumers that do not classify their calls. */
60
+ export const SPECTATOR_GENERAL = 'general';
61
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA;;;;GAIG;AACH,MAAM,CAAN,IAAY,aAOX;AAPD,WAAY,aAAa;IACvB,yFAAyF;IACzF,kCAAiB,CAAA;IACjB,8BAA8B;IAC9B,wCAAuB,CAAA;IACvB,yFAAyF;IACzF,0CAAyB,CAAA;AAC3B,CAAC,EAPW,aAAa,KAAb,aAAa,QAOxB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,qCAAmB,CAAA;IACnB,+BAAa,CAAA;IACb,mCAAiB,CAAA;AACnB,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,sCAAmB,CAAA;IACnB,wCAAqB,CAAA;IACrB,gCAAa,CAAA;IACb,8BAAW,CAAA;AACb,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B;AAED;;;;;;;;;GASG;AACH,MAAM,CAAN,IAAY,cAGX;AAHD,WAAY,cAAc;IACxB,mCAAiB,CAAA;IACjB,+BAAa,CAAA;AACf,CAAC,EAHW,cAAc,KAAd,cAAc,QAGzB;AAED,0DAA0D;AAC1D,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,qCAAa,CAAA;IACb,8CAAsB,CAAA;AACxB,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './consts.js';
2
+ export type * from './types.js';
3
+ export type * from './spectator/types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,sBAAsB,CAAA"}
package/build/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './consts.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA"}
@@ -0,0 +1,37 @@
1
+ import type { UsageMetadata } from '@langchain/core/messages';
2
+ import type { SpectatorContentType } from '../consts.js';
3
+ import type { LlmPurpose } from '../types.js';
4
+ /** What a caller hands to the spectator sink for a single completed model call. */
5
+ export interface SpectatorArgument {
6
+ action: string;
7
+ retries: number;
8
+ tries?: number;
9
+ messages: SpectatorEntryMessage[];
10
+ startedAt?: number;
11
+ }
12
+ /** A stored spectator record — the argument plus the resolved call context. */
13
+ export interface SpectatorEntry extends SpectatorArgument {
14
+ /**
15
+ * Consumer-defined classification of the call. Open `string` so a consumer can
16
+ * declare its own enum (e.g. `coder` / `fixer` / `general`) and stay assignable.
17
+ */
18
+ kind: string;
19
+ model: string;
20
+ purpose: LlmPurpose;
21
+ timestamp: number;
22
+ }
23
+ /** A spectator record that has been persisted and has an identity. */
24
+ export interface SpectatorEntryLogged extends SpectatorEntry {
25
+ id: string;
26
+ }
27
+ /** One message (prompt or completion) inside a spectator entry. */
28
+ export interface SpectatorEntryMessage {
29
+ type: string;
30
+ callType: string;
31
+ content: string;
32
+ name?: string;
33
+ contentType: SpectatorContentType;
34
+ usage?: UsageMetadata;
35
+ raw?: string;
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/spectator/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,qBAAqB,EAAE,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,UAAU,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,sEAAsE;AACtE,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,EAAE,EAAE,MAAM,CAAA;CACX;AAED,mEAAmE;AACnE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,oBAAoB,CAAA;IACjC,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/spectator/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,118 @@
1
+ import type { ExecutionEffort, ExecutionLevel } from './consts.js';
2
+ /**
3
+ * Free-form observability metadata attached to every model call — forwarded to the
4
+ * inference provider as run metadata and recorded on every spectator entry. Kept
5
+ * intentionally small; a consumer extends it with its own domain fields.
6
+ */
7
+ export interface LlmPurpose {
8
+ /** Coarse classification of the caller (e.g. `'coder'`, `'analyst'`). */
9
+ type?: string;
10
+ /** Narrow, per-call refinement — set by `ExecutionService.forHelper`. */
11
+ dedication?: string;
12
+ }
13
+ /**
14
+ * Serializable role name used to select a model. Deliberately an open `string`:
15
+ * a consumer declares its own role enum (whose values are strings) and it stays
16
+ * assignable here.
17
+ */
18
+ export type ModelRole = string;
19
+ /**
20
+ * JSON-safe subset of the runtime `ModelConfig` (`@owlmeans/llm`). Mirrors only the
21
+ * serializable, tier-relevant fields — never `provider` / `secret` / `headers` /
22
+ * `fallback`. Lives here so an execution state can be persisted and replayed.
23
+ */
24
+ export interface ModelConfigPatch {
25
+ preset?: string;
26
+ model?: string;
27
+ temperature?: number;
28
+ maxTokens?: number;
29
+ maxTokensCap?: number;
30
+ topP?: number;
31
+ disableThinking?: boolean;
32
+ }
33
+ /** A JSON-safe model override: a config alias, or a partial config patch. */
34
+ export type ModelConfigOverride = string | ModelConfigPatch;
35
+ /**
36
+ * A single, inheritable model-selection policy carried by every execution.
37
+ * Resolution precedence (see `ExecutionService.model`):
38
+ * roleOverride → modelOverride → effort tier → `LlmService.getModel`.
39
+ */
40
+ export interface ModelPolicy {
41
+ /** Orthogonal capability tier. */
42
+ effort: ExecutionEffort;
43
+ /** "Use role X wherever role Y is requested" — remap an entire sub-flow's roles. */
44
+ roleOverrides?: Partial<Record<ModelRole, ModelRole>>;
45
+ /** "Pin a role to a specific model/config" — alias or partial config override. */
46
+ modelOverrides?: Partial<Record<ModelRole, ModelConfigOverride>>;
47
+ }
48
+ /**
49
+ * Serializable execution state — no functions, no file access, no model instances.
50
+ * The runtime `Execution` (`@owlmeans/llm`) = this state + attached collaborators.
51
+ * A consumer extends this interface with its own domain fields; everything declared
52
+ * on the extension is carried into the snapshot automatically.
53
+ */
54
+ export interface ExecutionState {
55
+ level: ExecutionLevel;
56
+ purpose: LlmPurpose;
57
+ policy: ModelPolicy;
58
+ }
59
+ /** Resumable state of a task-level execution. */
60
+ export interface TaskExecutionState extends ExecutionState {
61
+ /** Abstract workflow position for checkpoint/resume. */
62
+ phase?: string;
63
+ completed?: string[];
64
+ cursor?: string;
65
+ data?: Record<string, unknown>;
66
+ }
67
+ /** Which model call produced a null/unusable result — carried by {@link NullCapture}. */
68
+ export type NullKind = 'ask' | 'talk' | 'invoke' | 'request';
69
+ /**
70
+ * Full diagnostic capture of a model call that returned nothing usable. Emitted by the
71
+ * model to the spectator's `captureNull` sink so a stalled/empty provider response can
72
+ * be replayed and diagnosed after the fact (finish reason, token accounting, whether a
73
+ * tool call was attempted, the exact request that produced it).
74
+ */
75
+ export interface NullCapture {
76
+ meta: {
77
+ kind: NullKind;
78
+ action: string;
79
+ purpose?: LlmPurpose;
80
+ attempt: number;
81
+ id: string;
82
+ timestamp: number;
83
+ elapsedMs: number;
84
+ };
85
+ model: {
86
+ id?: string;
87
+ provider?: string;
88
+ baseUrl?: string;
89
+ maxTokens?: number;
90
+ reasoning?: unknown;
91
+ temperature?: number;
92
+ topP?: number;
93
+ };
94
+ request: {
95
+ messages: unknown[];
96
+ schema?: {
97
+ toolName: string;
98
+ innerSchema: unknown;
99
+ };
100
+ useCache: boolean;
101
+ };
102
+ response: {
103
+ content: unknown;
104
+ additional_kwargs?: unknown;
105
+ response_metadata?: unknown;
106
+ usage_metadata?: unknown;
107
+ tool_calls?: unknown;
108
+ } | null;
109
+ diagnostics: {
110
+ finishReason?: string;
111
+ inputTokens?: number;
112
+ outputTokens?: number;
113
+ reasoningTokens?: number;
114
+ contentEmpty: boolean;
115
+ hadToolCall: boolean;
116
+ };
117
+ }
118
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@owlmeans/llm-common",
3
+ "version": "0.1.14",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "scripts": {
7
+ "build": "tsc -b",
8
+ "dev": "sleep 171 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
9
+ "watch": "tsc -b -w --preserveWatchOutput --pretty"
10
+ },
11
+ "main": "build/index.js",
12
+ "module": "build/index.js",
13
+ "types": "build/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": "./build/index.js",
17
+ "require": "./build/index.js",
18
+ "default": "./build/index.js",
19
+ "module": "./build/index.js",
20
+ "types": "./build/index.d.ts"
21
+ }
22
+ },
23
+ "devDependencies": {
24
+ "@langchain/core": "^1.1.39",
25
+ "@owlmeans/dep-config": "workspace:*",
26
+ "nodemon": "^3.1.14",
27
+ "typescript": "^6.0.3"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ }
32
+ }
package/src/consts.ts ADDED
@@ -0,0 +1,61 @@
1
+
2
+ /**
3
+ * Inference provider family a {@link ModelConfigPatch}/config targets. Each value is
4
+ * the `type` of an `LlmPlugin` registered in `@owlmeans/llm`; a downstream package
5
+ * can register additional plugins under its own type string.
6
+ */
7
+ export enum ModelProvider {
8
+ /** Proprietary OpenAI endpoint (Responses API for the `gpt-5*` / `codex-*` families). */
9
+ OpenAI = 'openai',
10
+ /** Anthropic messages API. */
11
+ Anthropic = 'anthropic',
12
+ /** Any OpenAI-compatible endpoint — OpenRouter, HuggingFace router, Together, vLLM, … */
13
+ Compatible = 'compatible',
14
+ }
15
+
16
+ /**
17
+ * Refinement level of an execution. An execution is refined downward only:
18
+ * root → task → helper, each step producing a new frozen object.
19
+ */
20
+ export enum ExecutionLevel {
21
+ Project = 'project',
22
+ Task = 'task',
23
+ Helper = 'helper',
24
+ }
25
+
26
+ /**
27
+ * Orthogonal capability tier carried by a {@link ModelPolicy} — the single,
28
+ * inheritable "how hard should this run" axis. Maps to a JSON-safe model config
29
+ * patch through the effort table in `@owlmeans/llm`.
30
+ */
31
+ export enum ExecutionEffort {
32
+ Economy = 'economy',
33
+ Standard = 'standard',
34
+ High = 'high',
35
+ Max = 'max',
36
+ }
37
+
38
+ /**
39
+ * How a model is asked to produce a schema-conforming object.
40
+ *
41
+ * - `Native` — the provider's own JSON-schema mode
42
+ * (`response_format: { type: 'json_schema' }`).
43
+ * - `Tool` — the forced-`tool_choice` tool-calling hack: a synthetic function whose
44
+ * parameters ARE the schema, with the tool choice pinned to it.
45
+ *
46
+ * The decision is per provider plugin, overridable per model config.
47
+ */
48
+ export enum StructuredMode {
49
+ Native = 'native',
50
+ Tool = 'tool',
51
+ }
52
+
53
+ /** Content shape of a single logged spectator message. */
54
+ export enum SpectatorContentType {
55
+ Text = 'text',
56
+ Json = 'json',
57
+ ToolCall = 'tool_call',
58
+ }
59
+
60
+ /** Default spectator entry kind for consumers that do not classify their calls. */
61
+ export const SPECTATOR_GENERAL = 'general'
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+
2
+ export * from './consts.js'
3
+ export type * from './types.js'
4
+ export type * from './spectator/types.js'
@@ -0,0 +1,40 @@
1
+ import type { UsageMetadata } from '@langchain/core/messages'
2
+ import type { SpectatorContentType } from '../consts.js'
3
+ import type { LlmPurpose } from '../types.js'
4
+
5
+ /** What a caller hands to the spectator sink for a single completed model call. */
6
+ export interface SpectatorArgument {
7
+ action: string
8
+ retries: number
9
+ tries?: number
10
+ messages: SpectatorEntryMessage[]
11
+ startedAt?: number
12
+ }
13
+
14
+ /** A stored spectator record — the argument plus the resolved call context. */
15
+ export interface SpectatorEntry extends SpectatorArgument {
16
+ /**
17
+ * Consumer-defined classification of the call. Open `string` so a consumer can
18
+ * declare its own enum (e.g. `coder` / `fixer` / `general`) and stay assignable.
19
+ */
20
+ kind: string
21
+ model: string
22
+ purpose: LlmPurpose
23
+ timestamp: number
24
+ }
25
+
26
+ /** A spectator record that has been persisted and has an identity. */
27
+ export interface SpectatorEntryLogged extends SpectatorEntry {
28
+ id: string
29
+ }
30
+
31
+ /** One message (prompt or completion) inside a spectator entry. */
32
+ export interface SpectatorEntryMessage {
33
+ type: string
34
+ callType: string
35
+ content: string
36
+ name?: string
37
+ contentType: SpectatorContentType
38
+ usage?: UsageMetadata
39
+ raw?: string
40
+ }
package/src/types.ts ADDED
@@ -0,0 +1,123 @@
1
+ import type { ExecutionEffort, ExecutionLevel } from './consts.js'
2
+
3
+ /**
4
+ * Free-form observability metadata attached to every model call — forwarded to the
5
+ * inference provider as run metadata and recorded on every spectator entry. Kept
6
+ * intentionally small; a consumer extends it with its own domain fields.
7
+ */
8
+ export interface LlmPurpose {
9
+ /** Coarse classification of the caller (e.g. `'coder'`, `'analyst'`). */
10
+ type?: string
11
+ /** Narrow, per-call refinement — set by `ExecutionService.forHelper`. */
12
+ dedication?: string
13
+ }
14
+
15
+ /**
16
+ * Serializable role name used to select a model. Deliberately an open `string`:
17
+ * a consumer declares its own role enum (whose values are strings) and it stays
18
+ * assignable here.
19
+ */
20
+ export type ModelRole = string
21
+
22
+ /**
23
+ * JSON-safe subset of the runtime `ModelConfig` (`@owlmeans/llm`). Mirrors only the
24
+ * serializable, tier-relevant fields — never `provider` / `secret` / `headers` /
25
+ * `fallback`. Lives here so an execution state can be persisted and replayed.
26
+ */
27
+ export interface ModelConfigPatch {
28
+ preset?: string
29
+ model?: string
30
+ temperature?: number
31
+ maxTokens?: number
32
+ maxTokensCap?: number
33
+ topP?: number
34
+ disableThinking?: boolean
35
+ }
36
+
37
+ /** A JSON-safe model override: a config alias, or a partial config patch. */
38
+ export type ModelConfigOverride = string | ModelConfigPatch
39
+
40
+ /**
41
+ * A single, inheritable model-selection policy carried by every execution.
42
+ * Resolution precedence (see `ExecutionService.model`):
43
+ * roleOverride → modelOverride → effort tier → `LlmService.getModel`.
44
+ */
45
+ export interface ModelPolicy {
46
+ /** Orthogonal capability tier. */
47
+ effort: ExecutionEffort
48
+ /** "Use role X wherever role Y is requested" — remap an entire sub-flow's roles. */
49
+ roleOverrides?: Partial<Record<ModelRole, ModelRole>>
50
+ /** "Pin a role to a specific model/config" — alias or partial config override. */
51
+ modelOverrides?: Partial<Record<ModelRole, ModelConfigOverride>>
52
+ }
53
+
54
+ /**
55
+ * Serializable execution state — no functions, no file access, no model instances.
56
+ * The runtime `Execution` (`@owlmeans/llm`) = this state + attached collaborators.
57
+ * A consumer extends this interface with its own domain fields; everything declared
58
+ * on the extension is carried into the snapshot automatically.
59
+ */
60
+ export interface ExecutionState {
61
+ level: ExecutionLevel
62
+ purpose: LlmPurpose
63
+ policy: ModelPolicy
64
+ }
65
+
66
+ /** Resumable state of a task-level execution. */
67
+ export interface TaskExecutionState extends ExecutionState {
68
+ /** Abstract workflow position for checkpoint/resume. */
69
+ phase?: string
70
+ completed?: string[]
71
+ cursor?: string
72
+ data?: Record<string, unknown>
73
+ }
74
+
75
+ /** Which model call produced a null/unusable result — carried by {@link NullCapture}. */
76
+ export type NullKind = 'ask' | 'talk' | 'invoke' | 'request'
77
+
78
+ /**
79
+ * Full diagnostic capture of a model call that returned nothing usable. Emitted by the
80
+ * model to the spectator's `captureNull` sink so a stalled/empty provider response can
81
+ * be replayed and diagnosed after the fact (finish reason, token accounting, whether a
82
+ * tool call was attempted, the exact request that produced it).
83
+ */
84
+ export interface NullCapture {
85
+ meta: {
86
+ kind: NullKind
87
+ action: string
88
+ purpose?: LlmPurpose
89
+ attempt: number
90
+ id: string
91
+ timestamp: number
92
+ elapsedMs: number
93
+ }
94
+ model: {
95
+ id?: string
96
+ provider?: string
97
+ baseUrl?: string
98
+ maxTokens?: number
99
+ reasoning?: unknown
100
+ temperature?: number
101
+ topP?: number
102
+ }
103
+ request: {
104
+ messages: unknown[]
105
+ schema?: { toolName: string; innerSchema: unknown }
106
+ useCache: boolean
107
+ }
108
+ response: {
109
+ content: unknown
110
+ additional_kwargs?: unknown
111
+ response_metadata?: unknown
112
+ usage_metadata?: unknown
113
+ tool_calls?: unknown
114
+ } | null
115
+ diagnostics: {
116
+ finishReason?: string
117
+ inputTokens?: number
118
+ outputTokens?: number
119
+ reasoningTokens?: number
120
+ contentEmpty: boolean
121
+ hadToolCall: boolean
122
+ }
123
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": ["@owlmeans/dep-config/tsconfig.base.json"],
3
+ "compilerOptions": {
4
+ "rootDir": "./src",
5
+ "outDir": "./build/",
6
+ "moduleResolution": "Bundler"
7
+ },
8
+ "include": [
9
+ "src/**/*"
10
+ ],
11
+ "exclude": [
12
+ "./dist/**/*",
13
+ "./build/**/*"
14
+ ]
15
+ }