@owlmeans/agent-common 0.1.18-rc.48 → 0.1.18-rc.49
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 +174 -13
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/agent-common/SKILL.md +1 -1
- package/package.json +1 -1
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
|
|
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
|
-
|
|
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
|
-
|
|
13
|
+
```bash
|
|
14
|
+
bun add @owlmeans/agent-common@^0.1.18-rc.49
|
|
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
|
-
| `
|
|
17
|
-
| `
|
|
18
|
-
| `
|
|
19
|
-
|
|
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
|
|
31
|
-
|
|
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@^0.1.18-rc.
|
|
210
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.52
|
|
50
211
|
```
|
|
51
212
|
|
|
52
213
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/agent-common",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-10-
|
|
4
|
+
"version": "0.1.18-rc.49",
|
|
5
|
+
"generatedAt": "2026-10-08T21:27:54.286Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -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.
|
|
11
|
+
**Install:** `"@owlmeans/agent-common": "^0.1.18-rc.49"` 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.
|