@owlmeans/agent-common 0.1.18-rc.9 → 0.1.18

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 (65) hide show
  1. package/README.md +174 -13
  2. package/agent-meta/manifest.json +3 -3
  3. package/agent-meta/skills/agent-common/SKILL.md +69 -14
  4. package/build/consts.d.ts +118 -5
  5. package/build/consts.d.ts.map +1 -1
  6. package/build/consts.js +204 -4
  7. package/build/consts.js.map +1 -1
  8. package/build/consts.local.d.ts +9 -0
  9. package/build/consts.local.d.ts.map +1 -0
  10. package/build/consts.local.js +9 -0
  11. package/build/consts.local.js.map +1 -0
  12. package/build/errors.d.ts +60 -0
  13. package/build/errors.d.ts.map +1 -1
  14. package/build/errors.js +84 -0
  15. package/build/errors.js.map +1 -1
  16. package/build/helpers/conversation.d.ts +0 -9
  17. package/build/helpers/conversation.d.ts.map +1 -1
  18. package/build/helpers/conversation.js +0 -28
  19. package/build/helpers/conversation.js.map +1 -1
  20. package/build/helpers/truncate.d.ts +10 -0
  21. package/build/helpers/truncate.d.ts.map +1 -0
  22. package/build/helpers/truncate.js +29 -0
  23. package/build/helpers/truncate.js.map +1 -0
  24. package/build/index.d.ts +6 -1
  25. package/build/index.d.ts.map +1 -1
  26. package/build/index.js +4 -1
  27. package/build/index.js.map +1 -1
  28. package/build/models/pipeline-spec/types.d.ts +57 -0
  29. package/build/models/pipeline-spec/types.d.ts.map +1 -0
  30. package/build/models/pipeline-spec/types.js +2 -0
  31. package/build/models/pipeline-spec/types.js.map +1 -0
  32. package/build/models/pipeline-spec.d.ts +4 -0
  33. package/build/models/pipeline-spec.d.ts.map +1 -0
  34. package/build/models/pipeline-spec.js +171 -0
  35. package/build/models/pipeline-spec.js.map +1 -0
  36. package/build/pipeline.d.ts +10 -0
  37. package/build/pipeline.d.ts.map +1 -0
  38. package/build/pipeline.js +10 -0
  39. package/build/pipeline.js.map +1 -0
  40. package/build/results/types.d.ts +211 -0
  41. package/build/results/types.d.ts.map +1 -0
  42. package/build/results/types.js +2 -0
  43. package/build/results/types.js.map +1 -0
  44. package/build/results.d.ts +4 -0
  45. package/build/results.d.ts.map +1 -0
  46. package/build/results.js +218 -0
  47. package/build/results.js.map +1 -0
  48. package/build/types.d.ts +146 -24
  49. package/build/types.d.ts.map +1 -1
  50. package/package.json +8 -8
  51. package/src/consts.local.ts +15 -0
  52. package/src/consts.ts +218 -4
  53. package/src/errors.ts +96 -0
  54. package/src/helpers/conversation.ts +0 -32
  55. package/src/helpers/truncate.ts +31 -0
  56. package/src/index.ts +6 -1
  57. package/src/models/pipeline-spec/types.ts +58 -0
  58. package/src/models/pipeline-spec.ts +202 -0
  59. package/src/pipeline.ts +16 -0
  60. package/src/results/types.ts +221 -0
  61. package/src/results.ts +270 -0
  62. package/src/types.ts +153 -25
  63. package/tests/pipeline.spec.ts +164 -0
  64. package/tests/results.spec.ts +148 -0
  65. package/src/flows.ts +0 -118
package/README.md CHANGED
@@ -1,23 +1,160 @@
1
1
  # @owlmeans/agent-common
2
2
 
3
3
  Serializable contracts for OwlMeans agents and LLM pipelines: conversation identity, the run
4
- lifecycle flow, and the record shapes an application persists.
4
+ lifecycle flow, the pipeline declaration and run row, the cumulative-results records with their
5
+ deterministic renderers, and the record shapes an application persists. Runtime-free by design — no
6
+ LangChain, no LangGraph, no storage driver — so a backend, a reconciler, an operator console or a
7
+ browser bundle imports it to read what an agent wrote and to say where a pipeline run stands. It does
8
+ not run anything: executing agents and pipelines, binding stores and cutting result views is the
9
+ runtime, [`@owlmeans/agent`](../agent). The package's skill is `agent-common`.
5
10
 
6
- Runtime-free by design — no LangChain, no LangGraph, no storage driver. A backend or a browser
7
- bundle can import these shapes to read what an agent wrote without pulling the runtime. The
8
- runtime is [`@owlmeans/agent`](../agent).
11
+ ## Installation
9
12
 
10
- ## What is here
13
+ ```bash
14
+ bun add @owlmeans/agent-common@^0.1.18
15
+ ```
16
+
17
+ ## Concepts
18
+
19
+ - **Conversation** — `ConversationRef` (`{ conversationId, scope }`): the thread a run belongs to and
20
+ the wider subject its memory is filed under. `conversationFor` derives both from an `LlmPurpose`
21
+ dedication (`<kind>:<id>`).
22
+ - **Run lifecycle** — `agentRunFlow`, an `@owlmeans/flow` declaration with steps `Received` →
23
+ `Prepared` → `Working` → `Finalizing` → `Finished`, plus a terminal `Failed`. The steps say how far
24
+ a run got; nothing resumes one.
25
+ - **Pipeline** — `PipelineSpec`, a declaration of named steps joined by `after` edges. It is the
26
+ resumable unit; `makePipelineSpecModel(spec)` validates and orders it.
27
+ - **Pipeline run** — `PipelineRun`, the one authority on where a run stands: status, `completed` /
28
+ `pending` steps, `state` as JSON **text** with `stateChars`, and `heartbeatAt`.
29
+ - **Cumulative results** — `CumulativeResultFact`s a step produced, collected into a
30
+ `CumulativeResultEntry` per step, rendered full or names-only so later steps reuse the
31
+ authoritative names.
32
+ - **Port** — a store name (`AGENT_CONVERSATION_STORE`, …) a consumer binds its own storage under. An
33
+ unbound port is not an error; the plugin that needs it degrades to a no-op.
34
+
35
+ ## Usage
36
+
37
+ ### Derive a conversation and cap text
38
+
39
+ ```typescript
40
+ import { DEFAULT_SUMMARY_CHARS, conversationFor, truncateAt } from '@owlmeans/agent-common'
41
+
42
+ const ref = conversationFor({ type: 'coder', dedication: `project:${projectId}` })
43
+ // { conversationId: 'project:<id>', scope: '<id>' } — an empty dedication becomes 'anonymous'
44
+
45
+ const summary = truncateAt(modelAnswer, DEFAULT_SUMMARY_CHARS) // cuts on a paragraph/line/sentence/word, marks with '…'
46
+ ```
47
+
48
+ ### Drive the run lifecycle
49
+
50
+ ```typescript
51
+ import { makeFlowModel } from '@owlmeans/flow'
52
+ import { AgentRunStep, AgentRunTransition, agentRunFlow } from '@owlmeans/agent-common'
53
+
54
+ const model = await makeFlowModel(agentRunFlow)
55
+ model.transit(model.next().transition, true) // Received → Prepared: one automatic edge per step
56
+ model.transit(AgentRunTransition.Work, true)
57
+
58
+ model.step().step === AgentRunStep.Working
59
+ ```
60
+
61
+ ### Declare and validate a pipeline
62
+
63
+ ```typescript
64
+ import { makePipelineSpecModel, PipelineSpecError } from '@owlmeans/agent-common'
65
+ import type { PipelineSpec } from '@owlmeans/agent-common'
66
+
67
+ export const scaffoldPipeline: PipelineSpec = {
68
+ alias: 'scaffold',
69
+ version: 2, // bump on every added, removed or renamed step
70
+ steps: [
71
+ { step: 'plan', title: 'Plan the change' },
72
+ { step: 'types', after: ['plan'] },
73
+ { step: 'api', after: ['types'] },
74
+ { step: 'web', after: ['types'] },
75
+ { step: 'wipe-preview', after: ['api', 'web'], nonIdempotent: true },
76
+ ],
77
+ }
78
+
79
+ const spec = makePipelineSpecModel(scaffoldPipeline)
80
+ spec.validate() // throws PipelineSpecError naming every fault at once
81
+ spec.orderSteps() // ['plan', 'types', 'api', 'web', 'wipe-preview']
82
+ spec.descendants('types') // what a resume from 'types' re-runs, 'types' included
83
+ spec.ancestry('wipe-preview') // [{ step: 'plan', depth: 3 }, { step: 'types', depth: 2 }, …]
84
+ ```
85
+
86
+ ### Render a step's results
87
+
88
+ ```typescript
89
+ import { CumulativeFactKind, CumulativeResultSource, cumulativeResultsHelper } from '@owlmeans/agent-common'
90
+
91
+ const { full, compact } = cumulativeResultsHelper.renderResultEntry({
92
+ label: 'types',
93
+ source: CumulativeResultSource.Extracted,
94
+ facts: [
95
+ { kind: CumulativeFactKind.Type, name: 'User', signature: '{ id: string; email: string }', specifier: '@app/common' },
96
+ { kind: CumulativeFactKind.Endpoint, name: 'user.create', ref: 'User', attrs: { method: 'POST', path: '/api/users' } },
97
+ ],
98
+ })
99
+
100
+ const spec = cumulativeResultsHelper.mergeResultsSpecs(pipelineResults, deploymentOverlay)
101
+ ```
102
+
103
+ ## API
104
+
105
+ ### Functions and helpers
11
106
 
12
107
  | Export | Purpose |
13
108
  |---|---|
14
109
  | `conversationFor(purpose, override?)` | Derives a `ConversationRef` from an `LlmPurpose` dedication — the thread identity an agent run belongs to |
15
110
  | `truncateAt(text, max)` | Boundary-aware truncation; every character cap in the family lands here |
16
- | `agentRunFlow` / `AgentRunStep` / `AgentRunTransition` | The `@owlmeans/flow` lifecycle a run is driven through |
17
- | `ConversationEvent` | One finished run, compacted: `summary` (what happened) + `advice` (what to do next) |
18
- | `AgentRunState` | The data plane of a run — serialized flow plus the execution snapshot |
19
- | `MemoryNode` / `MemoryEvent` | Agent-authored memory: a subsystem graph node, and an entry in a bounded sequence |
111
+ | `makePipelineSpecModel(spec)` | `PipelineSpecModel`: `validate`, `orderSteps`, `descendants`, `ancestry`, `ancestors`, `stepOf`, `record` |
112
+ | `validatePipelineSpec`, `orderPipelineSteps`, `pipelineDescendants`, `pipelineStep` | Deprecated wrappers over `makePipelineSpecModel` |
113
+ | `cumulativeResultsHelper` (`createCumulativeResultsHelper()`) | `factKey`, `sortFacts`, `renderResultFact`, `renderResultEntry`, `renderResultSummary`, `compareResultOrder`, `rootRunOf`, `resultLabel`, `mergeResultsSpecs` |
114
+
115
+ ### Records and types
116
+
117
+ | Export | Purpose |
118
+ |---|---|
119
+ | `agentRunFlow` / `agentFlows` / `AgentRunStep` / `AgentRunTransition` | The `@owlmeans/flow` lifecycle a run is driven through |
120
+ | `ConversationEvent` (+ `ConversationEventInput`) | One finished run, compacted: `summary` (what happened) + `advice` (what to do next) |
121
+ | `MemoryNode` / `MemoryEvent` (+ `MemoryEventInput`) | Agent-authored memory: a subsystem graph node, and an entry in a bounded sequence |
20
122
  | `AgentRunMessage` | What a transport carries; execution state travels by reference |
123
+ | `PipelineSpec`, `PipelineStepSpec`, `PipelineState` | The declaration and the scalar state passed between steps |
124
+ | `PipelineRun`, `PipelineRunInquiry`, `PipelineProgress` | The persisted run row, the question a `Waiting` run stopped on, runner progress |
125
+ | `PipelineSpecModel`, `PipelineStepDepth` | The spec model and an ancestor with its edge distance |
126
+ | `CumulativeResultFact`, `CumulativeResultEntry`, `RenderableResultEntry`, `RenderedResultEntry`, `ResultRenderCaps` | Cumulative-results records and rendering |
127
+ | `CumulativeResultsSpec`, `StepResultsSpec`, `ResultSummarySpec`, `ResultFactQuery`, `CumulativeResultsHelper` | The JSON-safe declaration, a facts query, the helper interface |
128
+
129
+ ### Constants and enums
130
+
131
+ | Export | Value / members |
132
+ |---|---|
133
+ | `AGENTS_SERVICE` | `'agents'` — plural, so it never collides with an app's own `agent` service |
134
+ | `AGENT_CONVERSATION_STORE`, `AGENT_MEMORY_GRAPH_STORE`, `AGENT_MEMORY_EVENTS_STORE`, `AGENT_PIPELINE_RUN_STORE`, `AGENT_CHECKPOINT_STORE`, `AGENT_CUMULATIVE_RESULT_STORE` | Port names |
135
+ | `AGENT_RUN_FLOW`, `SCOPE_SEP`, `INQUIRY_ANSWERS_KEY`, `RESULTS_EVERY_STEP` | `'agent-run'`, `':'`, `'answers'`, `'*'` |
136
+ | `DEFAULT_SUMMARY_CHARS` 1200 · `DEFAULT_ADVICE_CHARS` 400 · `DEFAULT_EVENT_WINDOW` 3 · `DEFAULT_MEMORY_NODE_CHARS` 2000 · `DEFAULT_MEMORY_EVENTS_LIMIT` 50 | Run and memory caps |
137
+ | `DEFAULT_MAX_STATE_CHARS` 256 000 · `DEFAULT_STEP_ATTEMPTS` 1 · `DEFAULT_STEP_TIMEOUT` 1 800 000 ms | Pipeline defaults |
138
+ | `DEFAULT_RESULTS_MAX_CHARS` 12 000 · `DEFAULT_RESULT_ENTRY_CHARS` 4 000 · `DEFAULT_RESULT_COMPACT_CHARS` 400 · `DEFAULT_RESULTS_WINDOW` 2 · `DEFAULT_RESULT_SUMMARY_CHARS` 600 | Cumulative-results caps |
139
+ | `AgentRunStatus` | `Ok`, `Failed` |
140
+ | `PipelineRunStatus` | `Running`, `Done`, `Failed`, `Aborted`, `Waiting` |
141
+ | `CumulativeResultSource` | `Extracted`, `Rebuilt`, `Seeded`, `Summarized` |
142
+ | `CumulativeFactKind` | `Type`, `Symbol`, `Endpoint`, `Resource`, `File` |
143
+ | `ResultViewMode` | `Full`, `Compact`, `Omitted` |
144
+
145
+ ### Errors
146
+
147
+ All extend `AgentCommonError` (a `ResilientError`) and are registered for marshalling.
148
+
149
+ | Error | Thrown when |
150
+ |---|---|
151
+ | `AgentRunStateError` | a run is asked to advance along a transition its step does not offer |
152
+ | `PipelineSpecError` | a declaration is not runnable — every fault in one message |
153
+ | `PipelineVersionError` | a resume targets a run started under another spec `version` |
154
+ | `PipelineUnknownStepError` | a step name the spec does not declare |
155
+ | `PipelineNotIdempotentError` | a resume would re-enter a completed `nonIdempotent` step without `force` |
156
+ | `PipelineStateTooLargeError` | a step's state exceeds the run row's cap |
157
+ | `PipelineNotResumableError` | a step asks a question with no one to answer and no run store to park in |
21
158
 
22
159
  ## Conventions worth knowing
23
160
 
@@ -27,8 +164,8 @@ at its own adapter boundary.
27
164
 
28
165
  **Flow steps are lifecycle stages, not conversational turns.** `FlowPayload` holds flat scalars
29
166
  only and a ReAct loop's turn count is unbounded, so the loop lives inside the `Working` step and
30
- only its counter travels in the payload. What the steps buy is the ability to say where an
31
- interrupted run resumes.
167
+ only its counter travels in the payload. What the steps buy is the ability to say how far a run got
168
+ when it ended. Resumable work is a pipeline.
32
169
 
33
170
  **Each working step has exactly one non-explicit outgoing transition**, so `FlowModel.next()` always
34
171
  has an unambiguous answer and a driver can advance a run without knowing the vocabulary. `Fail` is
@@ -36,7 +173,31 @@ marked explicit precisely so it never becomes that automatic answer.
36
173
 
37
174
  **Port names are exported, ports are not bound here.** `AGENT_CONVERSATION_STORE` and friends are
38
175
  the keys a consumer registers its own storage under. An unbound port is not an error — the plugin
39
- that needs it degrades to a no-op.
176
+ that needs it degrades to a no-op. A pipeline without `AGENT_PIPELINE_RUN_STORE` still runs but
177
+ cannot be resumed.
178
+
179
+ **A rendered result entry is deterministic.** Facts sort by kind (file facts last), name and
180
+ location; nothing that varies (timestamp, run id, revision) is rendered, and over its cap an entry
181
+ drops whole facts and says how many.
182
+
183
+ ## Common pitfalls
184
+
185
+ - A pipeline state is scalars and keys; a document in it fails the step with
186
+ `PipelineStateTooLargeError` rather than being truncated — store artifacts elsewhere and pass keys.
187
+ - Forgetting to bump `version` after renaming a step lets a resume skip work silently; a bumped
188
+ version makes the resume refuse instead.
189
+ - `nonIdempotent: true` with `attempts > 1` is a validation fault.
190
+ - `ancestry`/`ancestors` exclude the named step, `descendants` include it.
191
+ - Caps are applied by truncation after the model answers; restating them in a prompt is not a cap.
192
+ - A `Waiting` run's `heartbeatAt` does not move — do not treat it as stale.
193
+
194
+ ## Related packages
195
+
196
+ - [`@owlmeans/agent`](../agent) — the runtime that executes runs and pipelines and writes these records
197
+ - [`@owlmeans/llm-common`](../llm-common) — `LlmPurpose` and `Inquiry`
198
+ - [`@owlmeans/flow`](../flow) — the flow model the run lifecycle is declared against
199
+ - [`@owlmeans/resource`](../resource) — `ResourceRecord`, the base of every persisted record
200
+ - [`@owlmeans/error`](../error) — `ResilientError`, the base of the error family
40
201
 
41
202
  <!-- owlmeans:agent-guidance:start -->
42
203
  ## Agent guidance
@@ -46,7 +207,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
46
207
  your project's skill store (`.agents/skills/`):
47
208
 
48
209
  ```sh
49
- npx @owlmeans/agent-skills
210
+ npx @owlmeans/agent-skills@^0.1.18
50
211
  ```
51
212
 
52
213
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/agent-common",
4
- "version": "0.1.18-rc.8",
5
- "generatedAt": "2026-08-27T21:16:47.137Z",
4
+ "version": "0.1.18",
5
+ "generatedAt": "2026-10-28T00:31:34.712Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agent-common
3
- description: How to use @owlmeans/agent-common — runtime-free contracts for OwlMeans agents: conversation identity, the run-lifecycle flow, and the record shapes an application persists (conversation events, run state, memory nodes and events). Auto-invoked when importing agent record types, conversationFor, truncateAt, or the agent run flow.
3
+ description: "How to use @owlmeans/agent-common — runtime-free contracts for OwlMeans agents: conversation identity, the run-lifecycle flow, the PIPELINE declaration (PipelineSpec, PipelineRun, validatePipelineSpec, orderPipelineSteps, pipelineAncestors), the CUMULATIVE PIPELINE RESULTS contracts (facts, entries, declarations, deterministic renderers) and the record shapes an application persists. Auto-invoked when importing agent record types, a pipeline spec or run type, a cumulative-results type or renderer, conversationFor, truncateAt, or the agent run flow."
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/agent-common
9
9
 
10
10
  **Layer:** Cross-cutting domain
11
- **Install:** `"@owlmeans/agent-common": "^0.1.18-rc.8"` in `dependencies`
11
+ **Install:** `"@owlmeans/agent-common": "^0.1.18"` in `dependencies`
12
12
 
13
13
  Serializable contracts for the agent family. No LangChain, no LangGraph, no storage driver — a
14
14
  backend or a browser bundle imports these to read what an agent wrote without pulling the runtime.
@@ -18,18 +18,27 @@ The runtime is `@owlmeans/agent`.
18
18
 
19
19
  | Export | Description |
20
20
  |---|---|
21
- | `conversationFor(purpose, override?)` | Derives a `ConversationRef` from an `LlmPurpose` dedication. |
21
+ | `ConversationRef` | `{ conversationId, scope }` — the thread a run belongs to, and the wider subject it is about. Two fields, because memory is filed per subject while threads may be finer-grained. |
22
+ | `conversationFor(purpose, override?)` · `SCOPE_SEP` | Derives a `ConversationRef` from an `LlmPurpose` dedication (`<kind>:<id>`, split on `SCOPE_SEP`); either half is overridable. |
22
23
  | `truncateAt(text, max)` | Boundary-aware truncation. Every character cap in the family lands here. |
23
24
  | `agentRunFlow`, `AgentRunStep`, `AgentRunTransition`, `AGENT_RUN_FLOW` | The `@owlmeans/flow` lifecycle a run is driven through. |
24
25
  | `agentFlows` | Every flow this package declares, for a provider to serve. |
25
26
  | `ConversationEvent`, `ConversationEventInput` | One finished run, compacted: `summary` + `advice`. |
26
- | `AgentRunState` | Serialized flow plus the execution snapshot — the data plane of a run. |
27
27
  | `MemoryNode`, `MemoryEvent` (+ `MemoryEventInput`) | Agent-authored memory records. |
28
- | `AgentRunMessage` | What a transport carries; execution state travels by reference. |
28
+ | `AgentRunMessage` | What a transport carries — a POINTER (`runId`, `conversationId`, optional `pipeline`/`step`), never state. |
29
+ | `PipelineStepSpec`, `PipelineSpec` | The declaration: named steps, `after: string[]` edges, `optional`, `nonIdempotent`, `attempts`, `timeout`. |
30
+ | `PipelineRun`, `PipelineRunStatus`, `PipelineProgress` | The persisted run row — `state` is JSON **text** plus `stateChars`; `completed`/`pending`/`warnings`; `heartbeatAt`. |
31
+ | `validatePipelineSpec`, `orderPipelineSteps`, `pipelineDescendants`, `pipelineAncestors`, `pipelineAncestry`, `pipelineStep` | Pure spec helpers — no runtime, no graph engine. |
32
+ | `CumulativeResultFact`, `CumulativeResultEntry`, `CumulativeResultSource`, `CumulativeFactKind`, `ResultViewMode`, `ResultFactQuery` | CUMULATIVE PIPELINE RESULTS records: one authoritative fact, one step's entry in a ledger. |
33
+ | `CumulativeResultsSpec`, `StepResultsSpec`, `ResultSummarySpec`, `mergeResultsSpecs`, `RESULTS_EVERY_STEP` | The JSON-safe declaration — per step: extractors by name, `full`/`omit` consumers, `window`, caps, `refresh`, an optional `summary`. |
34
+ | `renderResultEntry`, `renderResultFact`, `renderResultSummary`, `sortFacts`, `factKey`, `compareResultOrder`, `resultLabel`, `rootRunOf` | Deterministic renderers and ledger helpers. |
29
35
  | `AGENTS_SERVICE` | The service alias — **`agents`**, plural. |
30
36
  | `AGENT_*_STORE` | Port names a consumer binds its storage under. |
31
37
  | `AgentRunStatus` | `ok` / `failed`, written on a conversation event. |
32
- | `AgentCommonError`, `AgentRunStateError` | The error family. |
38
+ | `AgentCommonError`, `AgentRunStateError`, `PipelineSpecError`, `PipelineVersionError`, `PipelineUnknownStepError`, `PipelineNotIdempotentError`, `PipelineStateTooLargeError` | The error family. |
39
+ | `DEFAULT_SUMMARY_CHARS` (1200) · `DEFAULT_ADVICE_CHARS` (400) · `DEFAULT_EVENT_WINDOW` (3) · `DEFAULT_MEMORY_NODE_CHARS` (2000) · `DEFAULT_MEMORY_EVENTS_LIMIT` (50) | The caps the runtime's plugins default to. Override them per plugin; read them here rather than restating a number. |
40
+ | `DEFAULT_MAX_STATE_CHARS` (256_000) · `DEFAULT_STEP_ATTEMPTS` (1) · `DEFAULT_STEP_TIMEOUT` (30 min) | Pipeline defaults. The state cap is a TRIPWIRE, not a budget. |
41
+ | `DEFAULT_RESULTS_MAX_CHARS` (12_000) · `DEFAULT_RESULT_ENTRY_CHARS` (4_000) · `DEFAULT_RESULT_COMPACT_CHARS` (400) · `DEFAULT_RESULTS_WINDOW` (2) · `DEFAULT_RESULT_SUMMARY_CHARS` (600) · `AGENT_CUMULATIVE_RESULT_STORE` | Cumulative-results caps — they bound what a step is TOLD, never what it may produce — and the store's port name. |
33
42
 
34
43
  ## Rules
35
44
 
@@ -41,26 +50,72 @@ at its own adapter boundary — that is the adapter's job, not the contract's.
41
50
  `agent`: a consuming application very often already has a service of its own called that, and a
42
51
  context accessor collision is silent — the second registration simply wins.
43
52
 
44
- **Flow steps are lifecycle stages, not conversational turns.** `FlowPayload` holds flat scalars only
45
- and a ReAct loop's turn count is unbounded, so the loop lives inside the `Working` step and only its
46
- counter travels in the payload. What the steps buy is knowing where an interrupted run resumes:
47
- `Working` from the last checkpoint, or `Finalizing` when the loop finished but the compaction never
48
- committed.
53
+ **Flow steps are lifecycle stages, not conversational turns, and nothing RESUMES one.** `FlowPayload`
54
+ holds flat scalars only and a ReAct loop's turn count is unbounded, so the loop lives inside the
55
+ `Working` step and only its counter travels in the payload. What the steps buy is the ability to say
56
+ how far a run got when it ended, which is what a plugin reads on `onFinish`. Resumable work is a
57
+ PIPELINE — named steps, a state of scalars, side effects guarded per step. A ReAct run is not one:
58
+ its state is an unbounded message list whose tool results are already applied to the world.
59
+
60
+ **A `PipelineSpec` is a DECLARATION and this package holds no engine.** The steps' bodies, the graph,
61
+ the checkpointer and the stores all live in `@owlmeans/agent`; what is here is what a browser bundle,
62
+ a reconciler or an operator console must read to say where a run stands without importing LangGraph.
63
+ That is also why `PipelineRun.state` is JSON **text** with a `stateChars` beside it rather than a
64
+ subdocument: a run row crosses a `$jsonSchema`, and a state whose keys are dotted paths does not.
65
+
66
+ **`validatePipelineSpec` names EVERY fault at once** — unknown `after` targets, cycles, duplicate
67
+ step names, `attempts > 1` on a `nonIdempotent` step. A spec is authored once and fixed once, and
68
+ reporting faults one per build turns a five-minute edit into five builds.
69
+
70
+ **A resume across a `version` change is REFUSED, never adapted.** `completed` names steps by string,
71
+ so a spec that has since renamed, removed or reordered one would let a resumed run skip work it never
72
+ did — silently, because an unknown name in `completed` matches nothing.
49
73
 
50
74
  **Each working step keeps exactly one non-explicit outgoing transition.** That is what lets
51
75
  `FlowModel.next()` give a driver an unambiguous answer without knowing the vocabulary. `Fail` is
52
76
  marked `explicit` precisely so it can never become that automatic answer. Adding a second automatic
53
77
  edge to any step breaks `next()` for that step.
54
78
 
79
+ **Every cap is enforced by truncation after the model answers, never by asking for it.** A cap in a
80
+ prompt is a request; a cap in code is a cap. That is why the defaults live here as numbers rather
81
+ than as prompt text.
82
+
55
83
  **A conversation id degrades to a named default, never to an empty string.** An empty key would
56
84
  silently collapse every run of every subject into one thread.
57
85
 
86
+ **`pipelineAncestors` mirrors `pipelineDescendants` but excludes the named step.** A re-run re-enters
87
+ the step it names; nothing is its own predecessor. `pipelineAncestry` adds each ancestor's DEPTH —
88
+ the fewest `after` edges between them — which is what a results window counts, so a direct
89
+ predecessor is depth 1 however far apart the two sit in the topological order.
90
+
91
+ **A rendered entry is deterministic and carries nothing that varies.** Facts sort by kind (file
92
+ facts last — a location is what a budget spares first), name and location with a code-unit compare;
93
+ no timestamp, run id or revision is ever rendered. Over its cap an entry drops WHOLE facts and says
94
+ how many ("they exist: check the files"), never half a signature. An empty non-partial entry renders
95
+ to `''` and costs a view nothing; a summary is always labelled "not verified".
96
+
97
+ **An entry's `order` is a PATH, not a number.** It is the step's topological index behind the index
98
+ path of every step it was composed under; where one key prefixes another the longer sorts FIRST, so
99
+ a composed run's entries precede the composing step's own. Two pipelines' indexes are not comparable,
100
+ which is why a single sequence number cannot order a ledger.
101
+
102
+ **Declarations merge like skills.** `mergeResultsSpecs` lets later declarations win field by field
103
+ but ACCUMULATES extractors, `full` and `omit` lists; `'*'` absorbs names.
104
+
58
105
  **Port names are exported; ports are not bound here.** An unbound port is not an error — the plugin
59
- that needs it degrades to a no-op, the way `ExecutionService.checkpoint` does with no plugin
60
- registered.
106
+ that needs it degrades to a no-op. `AGENT_PIPELINE_RUN_STORE` is the one exception in spirit: a
107
+ pipeline with no run store still runs, but it is not resumable, because the ROW is what a resume
108
+ reads. `AGENT_CHECKPOINT_STORE` may be absent with no loss of correctness at all.
61
109
 
62
110
  ## Testing
63
111
 
64
112
  Category A (unit, no env, no network). This package's own `tests/flow.spec.ts` covers the flow
65
113
  round-trip — which is also the standing check that `@owlmeans/flow` still works server-side, since
66
- every other consumer of that package is client-side.
114
+ every other consumer of that package is client-side. `tests/results.spec.ts` pins the exact bytes an
115
+ entry renders to; a change there changes what every consuming step is told.
116
+
117
+ ## Related
118
+
119
+ - [[agent]] — the runtime that writes these records
120
+ - [[llm-common]] — `LlmPurpose` and `ExecutionState`, which a run's execution is built from
121
+ - [[flow]] — the flow model the run lifecycle is declared against
package/build/consts.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { ShallowFlow } from '@owlmeans/flow';
1
2
  /**
2
3
  * The agent service alias.
3
4
  *
@@ -15,9 +16,50 @@ export declare const AGENTS_SERVICE = "agents";
15
16
  * the same way `ExecutionService.checkpoint` does with no plugin registered.
16
17
  */
17
18
  export declare const AGENT_CONVERSATION_STORE = "agent-conversation-store";
18
- export declare const AGENT_RUN_STATE_STORE = "agent-run-state-store";
19
19
  export declare const AGENT_MEMORY_GRAPH_STORE = "agent-memory-graph-store";
20
20
  export declare const AGENT_MEMORY_EVENTS_STORE = "agent-memory-events-store";
21
+ export declare const AGENT_PIPELINE_RUN_STORE = "agent-pipeline-run-store";
22
+ export declare const AGENT_CHECKPOINT_STORE = "agent-checkpoint-store";
23
+ export declare const AGENT_CUMULATIVE_RESULT_STORE = "agent-cumulative-result-store";
24
+ /**
25
+ * Caps and defaults for cumulative pipeline results.
26
+ *
27
+ * Every one of them bounds what a later step is TOLD, never what a step may produce: a fact that
28
+ * does not fit is left out of one view, and it is still on its entry for the next view and for any
29
+ * code that queries it. `DEFAULT_RESULTS_WINDOW` is a distance in the step graph — a consumer that
30
+ * many edges or fewer after a producer gets the producer's full entry; anything further back gets
31
+ * its names only, unless the producer names the consumer outright.
32
+ */
33
+ export declare const DEFAULT_RESULTS_MAX_CHARS = 12000;
34
+ export declare const DEFAULT_RESULT_ENTRY_CHARS = 4000;
35
+ export declare const DEFAULT_RESULT_COMPACT_CHARS = 400;
36
+ export declare const DEFAULT_RESULTS_WINDOW = 2;
37
+ export declare const DEFAULT_RESULT_SUMMARY_CHARS = 600;
38
+ /** The consumer wildcard: every later step of the pipeline — and of anything it is composed into. */
39
+ export declare const RESULTS_EVERY_STEP = "*";
40
+ /**
41
+ * Caps and defaults for a pipeline run.
42
+ *
43
+ * `DEFAULT_MAX_STATE_CHARS` is generous by the standard of what a state may legally hold — scalars
44
+ * and keys — and deliberately so: it is a TRIPWIRE, not a budget. A state approaching it is a state
45
+ * carrying an artifact, and the step fails so that fact is discovered on the first run rather than
46
+ * surviving as a row nobody can read back.
47
+ *
48
+ * `DEFAULT_STEP_ATTEMPTS` is 1 because retry budgets in this family multiply: an outer retry around
49
+ * a model's own inner retry is their product, not their sum.
50
+ */
51
+ export declare const DEFAULT_MAX_STATE_CHARS = 256000;
52
+ export declare const DEFAULT_STEP_ATTEMPTS = 1;
53
+ export declare const DEFAULT_STEP_TIMEOUT = 1800000;
54
+ /**
55
+ * Where a pipeline's answers live in its state.
56
+ *
57
+ * One key, named here rather than per pipeline, because an answer has to survive every hop it can
58
+ * take: a resume merges answers into it, a composing step forwards it to its child, and a reader
59
+ * looks a question up by id. Scalars and keys, like everything else a state holds — the answer's
60
+ * decision travels here and its prose belongs wherever that pipeline keeps its documents.
61
+ */
62
+ export declare const INQUIRY_ANSWERS_KEY = "answers";
21
63
  /** The lifecycle flow every agent run is driven through. */
22
64
  export declare const AGENT_RUN_FLOW = "agent-run";
23
65
  /**
@@ -26,8 +68,12 @@ export declare const AGENT_RUN_FLOW = "agent-run";
26
68
  * These are recoverable LIFECYCLE stages, not conversational turns. A ReAct loop's turn count is
27
69
  * unbounded and its messages are not scalars, while `FlowPayload` holds flat scalars only — so the
28
70
  * loop lives inside `Working` and only its counter travels in the payload. What the steps buy is
29
- * the ability to say where a crashed run has to resume: at `Working` from the last checkpoint, or
30
- * at `Finalizing` when the loop finished but the compaction never committed.
71
+ * the ability to say how far a run got when it ended, which is what a plugin reads on `onFinish`.
72
+ *
73
+ * Nothing RESUMES one of these. A ReAct run is not a resumable unit: its state is an unbounded
74
+ * message list whose tool results are side effects already applied to the world, so re-entering it
75
+ * would re-apply them. Resumable work is a PIPELINE — see `pipeline.ts` — whose steps are named,
76
+ * whose state is scalars, and whose side effects are guarded per step.
31
77
  */
32
78
  export declare enum AgentRunStep {
33
79
  Received = "received",
@@ -43,8 +89,7 @@ export declare enum AgentRunTransition {
43
89
  Work = "work",
44
90
  Finalize = "finalize",
45
91
  Finish = "finish",
46
- Fail = "fail",
47
- Resume = "resume"
92
+ Fail = "fail"
48
93
  }
49
94
  /** How a run ended. Written on the conversation event so a reader can weigh the advice. */
50
95
  export declare enum AgentRunStatus {
@@ -64,4 +109,72 @@ export declare const DEFAULT_MEMORY_NODE_CHARS = 2000;
64
109
  export declare const DEFAULT_MEMORY_EVENTS_LIMIT = 50;
65
110
  /** Separator between a dedication's kind and its target — `project:<id>`. */
66
111
  export declare const SCOPE_SEP = ":";
112
+ /** How a run ended, or that it has not. */
113
+ export declare enum PipelineRunStatus {
114
+ Running = "running",
115
+ Done = "done",
116
+ Failed = "failed",
117
+ /** Stopped on purpose with work left — a budget expired, or the caller asked. Resumable. */
118
+ Aborted = "aborted",
119
+ /**
120
+ * Stopped on purpose, waiting for an answer to {@link PipelineRun.inquiry}.
121
+ *
122
+ * Resumable, and NOT stale: a waiting run has no process behind it and its `heartbeatAt` will not
123
+ * move again until somebody answers. A reconciler that reads staleness alone would take this for
124
+ * a crashed run and repair what is merely waiting.
125
+ */
126
+ Waiting = "waiting"
127
+ }
128
+ /** Where the facts of an entry came from. */
129
+ export declare enum CumulativeResultSource {
130
+ /** Read by code from what the step left behind, when the step finished. */
131
+ Extracted = "extracted",
132
+ /**
133
+ * Read by code from the step's DURABLE inputs, after the fact — on a resume that found no stored
134
+ * entry, or for a step whose guard skipped it. The same facts an extraction would have found.
135
+ */
136
+ Rebuilt = "rebuilt",
137
+ /** Supplied before any step of the run ran — the caller already knew them. */
138
+ Seeded = "seeded",
139
+ /** No facts at all; only a model's summary, which nothing has checked. */
140
+ Summarized = "summarized"
141
+ }
142
+ /** How one entry appears in a view cut for a given step. */
143
+ export declare enum ResultViewMode {
144
+ Full = "full",
145
+ /** Names only, grouped by kind. */
146
+ Compact = "compact",
147
+ /** Not in the prompt. Still answered by a programmatic facts query. */
148
+ Omitted = "omitted"
149
+ }
150
+ /**
151
+ * Kinds an extractor is encouraged to use. `CumulativeResultFact.kind` is an open string — declare
152
+ * your own — but two extractors naming the same thing differently split one fact into two.
153
+ */
154
+ export declare enum CumulativeFactKind {
155
+ Type = "type",
156
+ Symbol = "symbol",
157
+ Endpoint = "endpoint",
158
+ Resource = "resource",
159
+ File = "file"
160
+ }
161
+ /**
162
+ * The lifecycle of one agent run.
163
+ *
164
+ * Read it as "how far did this run get", not "what did it say". Everything conversational happens
165
+ * inside `Working`; the steps exist so a plugin reading `onFinish` can say where a run ended.
166
+ * `Fail` is reachable from every working step and is TERMINAL — see the note on that step.
167
+ *
168
+ * `service` is left as the flow name on every step. A flow step normally binds to a service or an
169
+ * entrypoint, but an agent run is driven by whoever holds the model — there is no second party to
170
+ * hand control to, and inventing one would put a name in the serialized state that nothing
171
+ * resolves.
172
+ *
173
+ * Each working step keeps exactly ONE non-explicit outgoing transition, so `FlowModel.next()`
174
+ * always has an unambiguous answer: that is what lets a driver advance the run without knowing the
175
+ * vocabulary. `Fail` is marked explicit precisely so it never becomes that automatic answer.
176
+ */
177
+ export declare const agentRunFlow: ShallowFlow;
178
+ /** Every flow this package declares, for a provider to serve. */
179
+ export declare const agentFlows: ShallowFlow[];
67
180
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,WAAW,CAAA;AAEtC;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,qBAAqB,0BAA0B,CAAA;AAC5D,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,yBAAyB,8BAA8B,CAAA;AAEpE,4DAA4D;AAC5D,eAAO,MAAM,cAAc,cAAc,CAAA;AAEzC;;;;;;;;GAQG;AACH,oBAAY,YAAY;IACtB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,QAAQ,aAAa;IACrB,MAAM,WAAW;CAClB;AAED,iDAAiD;AACjD,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,2FAA2F;AAC3F,oBAAY,cAAc;IACxB,EAAE,OAAO;IACT,MAAM,WAAW;CAClB;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAA;AACzC,eAAO,MAAM,oBAAoB,MAAM,CAAA;AACvC,eAAO,MAAM,oBAAoB,IAAI,CAAA;AACrC,eAAO,MAAM,yBAAyB,OAAO,CAAA;AAC7C,eAAO,MAAM,2BAA2B,KAAK,CAAA;AAE7C,6EAA6E;AAC7E,eAAO,MAAM,SAAS,MAAM,CAAA"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,WAAW,CAAA;AAEtC;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,yBAAyB,8BAA8B,CAAA;AACpE,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAClE,eAAO,MAAM,sBAAsB,2BAA2B,CAAA;AAC9D,eAAO,MAAM,6BAA6B,kCAAkC,CAAA;AAE5E;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAA;AAC/C,eAAO,MAAM,0BAA0B,OAAQ,CAAA;AAC/C,eAAO,MAAM,4BAA4B,MAAM,CAAA;AAC/C,eAAO,MAAM,sBAAsB,IAAI,CAAA;AACvC,eAAO,MAAM,4BAA4B,MAAM,CAAA;AAE/C,qGAAqG;AACrG,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,SAAU,CAAA;AAC9C,eAAO,MAAM,qBAAqB,IAAI,CAAA;AACtC,eAAO,MAAM,oBAAoB,UAAY,CAAA;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,YAAY,CAAA;AAE5C,4DAA4D;AAC5D,eAAO,MAAM,cAAc,cAAc,CAAA;AAEzC;;;;;;;;;;;;GAYG;AACH,oBAAY,YAAY;IACtB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,QAAQ,aAAa;IACrB,MAAM,WAAW;CAClB;AAED,iDAAiD;AACjD,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED,2FAA2F;AAC3F,oBAAY,cAAc;IACxB,EAAE,OAAO;IACT,MAAM,WAAW;CAClB;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAA;AACzC,eAAO,MAAM,oBAAoB,MAAM,CAAA;AACvC,eAAO,MAAM,oBAAoB,IAAI,CAAA;AACrC,eAAO,MAAM,yBAAyB,OAAO,CAAA;AAC7C,eAAO,MAAM,2BAA2B,KAAK,CAAA;AAE7C,6EAA6E;AAC7E,eAAO,MAAM,SAAS,MAAM,CAAA;AAE5B,2CAA2C;AAC3C,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,4FAA4F;IAC5F,OAAO,YAAY;IACnB;;;;;;OAMG;IACH,OAAO,YAAY;CACpB;AAED,6CAA6C;AAC7C,oBAAY,sBAAsB;IAChC,2EAA2E;IAC3E,SAAS,cAAc;IACvB;;;OAGG;IACH,OAAO,YAAY;IACnB,8EAA8E;IAC9E,MAAM,WAAW;IACjB,0EAA0E;IAC1E,UAAU,eAAe;CAC1B;AAED,4DAA4D;AAC5D,oBAAY,cAAc;IACxB,IAAI,SAAS;IACb,mCAAmC;IACnC,OAAO,YAAY;IACnB,uEAAuE;IACvE,OAAO,YAAY;CACpB;AAED;;;GAGG;AACH,oBAAY,kBAAkB;IAC5B,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,IAAI,SAAS;CACd;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,EAAE,WA0F1B,CAAA;AAED,iEAAiE;AACjE,eAAO,MAAM,UAAU,EAAE,WAAW,EAAmB,CAAA"}