@kontourai/flow-agents 0.2.0 → 0.4.0
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/.github/workflows/release-please.yml +13 -1
- package/.github/workflows/runtime-compat.yml +1 -1
- package/AGENTS.md +8 -1
- package/CHANGELOG.md +41 -0
- package/README.md +38 -19
- package/build/src/cli/flow-kit.js +9 -4
- package/build/src/cli/runtime-adapter.js +9 -5
- package/build/src/cli/telemetry-doctor.js +4 -1
- package/build/src/runtime-adapters.js +34 -0
- package/build/src/tools/build-universal-bundles.js +18 -1
- package/console.telemetry.json +115 -20
- package/docs/_layouts/default.html +2 -0
- package/docs/index.md +8 -0
- package/docs/integrations/index.md +4 -0
- package/docs/integrations/knowledge-kit-live.md +211 -0
- package/docs/kit-authoring-guide.md +169 -0
- package/docs/spec/runtime-hook-surface.md +56 -3
- package/evals/acceptance/run.sh +10 -1
- package/evals/acceptance/test_knowledge_kit_live.sh +221 -0
- package/evals/acceptance/test_pi_harness.sh +15 -0
- package/evals/integration/test_runtime_adapter_activation.sh +113 -1
- package/evals/static/test_universal_bundles.sh +10 -0
- package/integrations/strands/examples/knowledge_kit_live.py +461 -0
- package/integrations/strands/flow_agents_strands/steering.py +54 -1
- package/integrations/strands/tests/test_hooks.py +88 -0
- package/integrations/strands-ts/src/hooks.ts +104 -0
- package/integrations/strands-ts/test/test-steering.ts +159 -0
- package/kits/catalog.json +6 -0
- package/kits/knowledge/adapters/default-store/index.js +902 -0
- package/kits/knowledge/adapters/flow-runner/index.js +1469 -0
- package/kits/knowledge/adapters/flow-runner/telemetry.js +174 -0
- package/kits/knowledge/adapters/similarity-vector/index.js +284 -0
- package/kits/knowledge/docs/README.md +328 -0
- package/kits/knowledge/docs/store-contract.md +650 -0
- package/kits/knowledge/evals/consolidation/suite.test.js +1234 -0
- package/kits/knowledge/evals/contract-suite/suite.test.js +675 -0
- package/kits/knowledge/evals/ingest-compile/suite.test.js +574 -0
- package/kits/knowledge/evals/retirement/suite.test.js +1173 -0
- package/kits/knowledge/evals/similarity-vector/suite.test.js +685 -0
- package/kits/knowledge/evals/synthesis/suite.test.js +916 -0
- package/kits/knowledge/flows/compile.flow.json +60 -0
- package/kits/knowledge/flows/consolidate.flow.json +77 -0
- package/kits/knowledge/flows/ingest.flow.json +60 -0
- package/kits/knowledge/flows/retire.flow.json +77 -0
- package/kits/knowledge/flows/store-contract.flow.json +48 -0
- package/kits/knowledge/flows/synthesize.flow.json +77 -0
- package/kits/knowledge/kit.json +98 -0
- package/package.json +1 -1
- package/src/cli/flow-kit.ts +10 -4
- package/src/cli/runtime-adapter.ts +10 -5
- package/src/cli/telemetry-doctor.ts +4 -1
- package/src/runtime-adapters.ts +35 -0
- package/src/tools/build-universal-bundles.ts +18 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Knowledge Kit Live Example
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Knowledge Kit Live Example
|
|
6
|
+
|
|
7
|
+
This page documents `integrations/strands/examples/knowledge_kit_live.py`: a keyless, ollama-backed end-to-end proof of the Knowledge Kit's ingest and compile flows running against a real Strands agent.
|
|
8
|
+
|
|
9
|
+
Everything on this page is grounded in the source files and in the acceptance test that was run to validate the commands. Limitations are documented honestly.
|
|
10
|
+
|
|
11
|
+
## What it proves
|
|
12
|
+
|
|
13
|
+
The example exercises the full `knowledge.ingest` → `knowledge.compile` pipeline in a temporary workspace:
|
|
14
|
+
|
|
15
|
+
- Two raw records are created programmatically via direct Node.js subprocess calls to the kit's flow-runner (`kits/knowledge/adapters/flow-runner/index.js`).
|
|
16
|
+
- One raw record is created by the Strands agent calling the `capture_knowledge` tool.
|
|
17
|
+
- The Strands agent calls `compile_knowledge` with all three raw record IDs, producing a compiled record with verified provenance links.
|
|
18
|
+
|
|
19
|
+
Two telemetry streams are asserted:
|
|
20
|
+
|
|
21
|
+
| Stream | Path | Contents |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| Kit gate telemetry | `<workspace>/.telemetry/full.jsonl` | `tool.invoke` + `tool.result` per ingest/compile gate point |
|
|
24
|
+
| Session telemetry | `<workspace>/.flow-agents/.telemetry/full.jsonl` | `session.start`, `turn.user`, `tool.invoke`, `tool.result`, `session.end` from FlowAgentsHooks |
|
|
25
|
+
|
|
26
|
+
## Prerequisites
|
|
27
|
+
|
|
28
|
+
- ollama installed and `qwen3:1.7b` pulled:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
ollama pull qwen3:1.7b
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- Python venv with `strands-agents[ollama]` at `/tmp/strands-py-live/venv`:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python3 -m venv /tmp/strands-py-live/venv
|
|
38
|
+
/tmp/strands-py-live/venv/bin/pip install 'strands-agents[ollama]'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- Node.js on PATH (for the kit's ESM flow-runner and bridge script).
|
|
42
|
+
|
|
43
|
+
## Running the example
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# From the repo root:
|
|
47
|
+
ollama serve &
|
|
48
|
+
FLOW_AGENTS_ROOT=$(pwd) \
|
|
49
|
+
/tmp/strands-py-live/venv/bin/python3 \
|
|
50
|
+
integrations/strands/examples/knowledge_kit_live.py
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Expected output (session IDs and UUIDs vary):
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
=== Knowledge Kit S5: Keyless Live Example ===
|
|
57
|
+
Repo root: /path/to/flow-agents
|
|
58
|
+
|
|
59
|
+
Node.js: v24.16.0
|
|
60
|
+
Workspace: /tmp/knowledge-kit-live-xxxxxxxx
|
|
61
|
+
Corpus: 3 doc snippets
|
|
62
|
+
docs/integrations/framework-adapter.md (engineering.docs)
|
|
63
|
+
docs/integrations/index.md (engineering.docs)
|
|
64
|
+
kits/knowledge/docs/README.md (research.notes)
|
|
65
|
+
|
|
66
|
+
--- Step 1: Programmatic captures (2 records) ---
|
|
67
|
+
docs/integrations/framework-adapter.md → <raw-id-1>
|
|
68
|
+
docs/integrations/index.md → <raw-id-2>
|
|
69
|
+
|
|
70
|
+
--- Step 2: Agent-driven capture ---
|
|
71
|
+
Agent turn: 2.9s
|
|
72
|
+
Reply snippet: 'The captured knowledge record has been successfully stored with ID: ...'
|
|
73
|
+
Raw records in store: 3
|
|
74
|
+
|
|
75
|
+
--- Step 3: Agent-driven compile ---
|
|
76
|
+
Agent turn: 4.3s
|
|
77
|
+
Reply snippet: 'The compiled knowledge record has been successfully created with ID: ...'
|
|
78
|
+
Compiled records in store: 1
|
|
79
|
+
|
|
80
|
+
--- Provenance verification ---
|
|
81
|
+
Compiled record: <compiled-id>
|
|
82
|
+
Source IDs present in provenance: True
|
|
83
|
+
Source links in graph index: 3
|
|
84
|
+
|
|
85
|
+
Kit gate telemetry (.telemetry/full.jsonl): 18 events
|
|
86
|
+
[tool.invoke] knowledge.ingest.classify-gate
|
|
87
|
+
[tool.result] knowledge.ingest.classify-gate
|
|
88
|
+
...
|
|
89
|
+
[tool.invoke] knowledge.compile.link-gate
|
|
90
|
+
[tool.result] knowledge.compile.link-gate
|
|
91
|
+
|
|
92
|
+
Session telemetry (.flow-agents/.telemetry/full.jsonl): 9 events
|
|
93
|
+
[session.start]
|
|
94
|
+
[turn.user]
|
|
95
|
+
[tool.invoke] (capture_knowledge)
|
|
96
|
+
[tool.result] (capture_knowledge)
|
|
97
|
+
[session.end]
|
|
98
|
+
[turn.user]
|
|
99
|
+
[tool.invoke] (compile_knowledge)
|
|
100
|
+
[tool.result] (compile_knowledge)
|
|
101
|
+
[session.end]
|
|
102
|
+
|
|
103
|
+
--- Summary ---
|
|
104
|
+
Kit event types: ['tool.invoke', 'tool.result']
|
|
105
|
+
Session event types: ['session.end', 'session.start', 'tool.invoke', 'tool.result', 'turn.user']
|
|
106
|
+
Raw records: 3
|
|
107
|
+
Compiled records: 1
|
|
108
|
+
Provenance ok: True
|
|
109
|
+
|
|
110
|
+
Overall: PASS
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Running the acceptance test
|
|
114
|
+
|
|
115
|
+
The acceptance harness gates on ollama binary, model presence, and venv presence. If any gate is absent it skips cleanly.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Run the knowledge-kit-live acceptance test directly:
|
|
119
|
+
bash evals/acceptance/test_knowledge_kit_live.sh
|
|
120
|
+
|
|
121
|
+
# Or through the acceptance runner:
|
|
122
|
+
bash evals/acceptance/run.sh knowledge-kit-live
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The harness asserts:
|
|
126
|
+
|
|
127
|
+
| Assertion | What is checked |
|
|
128
|
+
| --- | --- |
|
|
129
|
+
| A1 | Example script exits 0 |
|
|
130
|
+
| A2 | `<workspace>/.telemetry/full.jsonl` contains `tool.invoke` + `tool.result` |
|
|
131
|
+
| A3 | `<workspace>/.flow-agents/.telemetry/full.jsonl` contains `session.start`, `tool.invoke`, `tool.result` |
|
|
132
|
+
| A4 | No `.telemetry` directory leaked to the workspace parent |
|
|
133
|
+
| A5 | At least 1 compiled record in the knowledge store |
|
|
134
|
+
| A6 | Compiled record has `source_ids` provenance referencing raw records |
|
|
135
|
+
|
|
136
|
+
## How the kit tools work
|
|
137
|
+
|
|
138
|
+
The example defines two Strands `@tool` functions that call the kit's flow-runner via Node.js subprocess:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
@tool
|
|
142
|
+
def capture_knowledge(text: str, category: str) -> str:
|
|
143
|
+
"""Capture raw knowledge text. Returns JSON: {"id": "<uuid>"}."""
|
|
144
|
+
meta_json = json.dumps({"category": category})
|
|
145
|
+
data = _call_node_bridge(bridge, "capture", text, meta_json, workspace=workspace)
|
|
146
|
+
return json.dumps(data)
|
|
147
|
+
|
|
148
|
+
@tool
|
|
149
|
+
def compile_knowledge(id1: str, id2: str, id3: str) -> str:
|
|
150
|
+
"""Compile three raw records into a compiled record. Returns JSON: {"id": ...}."""
|
|
151
|
+
raw_ids = [i for i in [id1, id2, id3] if i and i.strip()]
|
|
152
|
+
data = _call_node_bridge(bridge, "compile", json.dumps(raw_ids), workspace=workspace)
|
|
153
|
+
return json.dumps(data)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The bridge script (`_kit_bridge.mjs`) is written into the workspace at runtime. It imports the kit's ESM modules using absolute paths resolved from `FLOW_AGENTS_ROOT`:
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
import { DefaultKnowledgeStore } from "<FLOW_AGENTS_ROOT>/kits/knowledge/adapters/default-store/index.js";
|
|
160
|
+
import { capture, compile } from "<FLOW_AGENTS_ROOT>/kits/knowledge/adapters/flow-runner/index.js";
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Kit gate telemetry is written by the Node flow-runner to `<workspace>/.telemetry/full.jsonl` (via the `FLOW_AGENTS_WORKSPACE` env var). This path is separate from the FlowAgentsHooks telemetry path (`<workspace>/.flow-agents/.telemetry/full.jsonl`) — both files are asserted in the acceptance test.
|
|
164
|
+
|
|
165
|
+
## Why two programmatic + one agent-driven capture
|
|
166
|
+
|
|
167
|
+
`qwen3:1.7b` (1.7B parameters) reliably calls single-tool prompts, but complex multi-capture prompts cause it to loop or produce unexpected output. The example uses programmatic captures for the first two records to keep runtime bounded (~30 seconds total), and agent-driven calls for the third capture and the compile step. This gives evidence that:
|
|
168
|
+
|
|
169
|
+
- The `capture_knowledge` and `compile_knowledge` tools are callable from a real Strands agent.
|
|
170
|
+
- FlowAgentsHooks records session events for those calls.
|
|
171
|
+
- The kit's gate telemetry is written correctly for all operations regardless of call path.
|
|
172
|
+
|
|
173
|
+
The acceptance harness asserts on filesystem evidence, not on model output quality.
|
|
174
|
+
|
|
175
|
+
## console.telemetry.json mapping
|
|
176
|
+
|
|
177
|
+
A `knowledge` flow entry is registered in `console.telemetry.json` to make knowledge flow events visible in the Flow Agents Console:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"id": "knowledge",
|
|
182
|
+
"label": "Knowledge flows",
|
|
183
|
+
"match": { "attribute": "flow", "includes": "knowledge." },
|
|
184
|
+
"titleAttribute": "title",
|
|
185
|
+
"detailAttributes": { ... }
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
This matches telemetry events where the `flow` attribute includes `"knowledge."` — for example, the kit gate events emitted by the flow-runner use `knowledge.ingest` and `knowledge.compile` as the flow identifiers.
|
|
190
|
+
|
|
191
|
+
## Documented limitations
|
|
192
|
+
|
|
193
|
+
1. **Model quality**: `qwen3:1.7b` is a 1.7B parameter model. It works for single-tool prompts but has limited reliability for complex multi-step instructions. Larger models will work more reliably but require API keys or more memory.
|
|
194
|
+
|
|
195
|
+
2. **Single-turn scope**: Each agent invocation covers one operation. Multi-turn chaining with full context tracking across many captures is out of scope for this sprint.
|
|
196
|
+
|
|
197
|
+
3. **Steering seam**: The `FlowAgentsHooks` spike injects workflow steering context once at `Agent` construction time. Per-turn steering re-evaluation is not implemented. See `docs/integrations/framework-adapter.md` § Limitations for details.
|
|
198
|
+
|
|
199
|
+
4. **Kit telemetry path**: The kit's flow-runner writes telemetry to `<workspace>/.telemetry/full.jsonl` (not the `.flow-agents/.telemetry/` subdirectory used by `FlowAgentsHooks`). Both paths are separate by design: kit telemetry captures gate-point evidence, session telemetry captures agent lifecycle events.
|
|
200
|
+
|
|
201
|
+
5. **compile_knowledge tool signature**: The tool takes three separate `id1`, `id2`, `id3` parameters instead of a JSON array. This is because `qwen3:1.7b` does not reliably produce valid JSON array syntax when prompted. This signature change is limited to this example and does not affect the kit's flow-runner API.
|
|
202
|
+
|
|
203
|
+
## Related references
|
|
204
|
+
|
|
205
|
+
- `integrations/strands/examples/knowledge_kit_live.py` — the example script
|
|
206
|
+
- `evals/acceptance/test_knowledge_kit_live.sh` — the acceptance test
|
|
207
|
+
- `kits/knowledge/adapters/flow-runner/index.js` — the kit flow-runner (capture + compile)
|
|
208
|
+
- `kits/knowledge/adapters/default-store/index.js` — the store adapter
|
|
209
|
+
- `kits/knowledge/kit.json` — kit manifest
|
|
210
|
+
- <a href="framework-adapter.html">Framework Adapter</a> — `FlowAgentsHooks` documentation and limitations
|
|
211
|
+
- <a href="../spec/runtime-hook-surface.html">Runtime Hook Surface spec</a> — canonical event taxonomy
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Flow Kit Authoring Guide
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Flow Kit Authoring Guide
|
|
6
|
+
|
|
7
|
+
A Flow Kit is a portable workflow bundle you author once and install into any Flow Agents workspace. It lets you package one or more Flow Definitions — plus optional skills, docs, adapters, evals, and assets — under a single validated manifest. The same install, validation, and activation path that ships the built-in Builder Kit is available to your own kits.
|
|
8
|
+
|
|
9
|
+
This guide walks you from an empty directory to a validated, locally installed kit.
|
|
10
|
+
|
|
11
|
+
## Concepts
|
|
12
|
+
|
|
13
|
+
- **Kit** — a directory with a root `kit.json` manifest and the assets it declares. The manifest is the contract; Flow Agents validates it before anything is copied.
|
|
14
|
+
- **Flow Definition** — a `.flow.json` file that declares steps, gates, and expected evidence. Validation of the Flow Definition semantics belongs to [Kontour Flow](https://kontourai.github.io/flow/); the kit contract delegates to it.
|
|
15
|
+
- **Activation** — the step that reads the installed kit and writes runtime-local files into your workspace. Today the `codex-local` adapter is the only adapter, and it activates only Flow Definition assets.
|
|
16
|
+
|
|
17
|
+
## Directory layout
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
my-kit/
|
|
21
|
+
kit.json ← required manifest
|
|
22
|
+
flows/
|
|
23
|
+
review.flow.json ← at least one Flow Definition
|
|
24
|
+
docs/ ← optional
|
|
25
|
+
README.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
All paths declared in `kit.json` must be relative to the kit directory and must not contain `..`. The kit must be fully self-contained so it can be installed from any machine or worktree.
|
|
29
|
+
|
|
30
|
+
## Minimal kit.json
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"schema_version": "1.0",
|
|
35
|
+
"id": "my-kit",
|
|
36
|
+
"name": "My Kit",
|
|
37
|
+
"description": "A minimal kit that adds a review flow.",
|
|
38
|
+
"flows": [
|
|
39
|
+
{
|
|
40
|
+
"id": "my-kit.review",
|
|
41
|
+
"path": "flows/review.flow.json",
|
|
42
|
+
"description": "Review a change against agreed criteria."
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Required fields:
|
|
49
|
+
|
|
50
|
+
| Field | Rule |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `schema_version` | Must be `"1.0"` |
|
|
53
|
+
| `id` | Stable kebab-case string, e.g. `review-kit` |
|
|
54
|
+
| `name` | Non-empty display name |
|
|
55
|
+
| `flows` | Non-empty list; each entry must have `id` and `path` |
|
|
56
|
+
|
|
57
|
+
Optional fields: `product_name`, `description`, `skills`, `docs`, `adapters`, `evals`, `assets`. Optional fields list relative asset paths or objects with `id`, `path`, and optional `description`. They are declared for provenance but only Flow Definition assets are activated today; others appear in diagnostics as `skipped_assets`.
|
|
58
|
+
|
|
59
|
+
## Minimal flow file
|
|
60
|
+
|
|
61
|
+
A Flow Definition at minimum needs `id`, `version`, `steps`, and `gates`. Steps form a linked list; each gate names the step it guards and the evidence it expects.
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"id": "my-kit.review",
|
|
66
|
+
"version": "1.0",
|
|
67
|
+
"steps": [
|
|
68
|
+
{ "id": "review", "next": "done" },
|
|
69
|
+
{ "id": "done", "next": null }
|
|
70
|
+
],
|
|
71
|
+
"gates": {
|
|
72
|
+
"review-gate": {
|
|
73
|
+
"step": "review",
|
|
74
|
+
"expects": [
|
|
75
|
+
{
|
|
76
|
+
"id": "review-finding",
|
|
77
|
+
"kind": "surface.claim",
|
|
78
|
+
"required": true,
|
|
79
|
+
"description": "The change was reviewed and findings were recorded.",
|
|
80
|
+
"claim": {
|
|
81
|
+
"type": "my-kit.review.finding",
|
|
82
|
+
"subject": "artifact",
|
|
83
|
+
"accepted_statuses": ["trusted", "accepted"]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The `id` in the flow file should match the `id` declared in `kit.json`'s `flows` list. Look at `kits/builder/flows/shape.flow.json` and `kits/builder/flows/build.flow.json` in this repository for fuller examples of multi-step flows with required and optional gate evidence.
|
|
93
|
+
|
|
94
|
+
## Validate
|
|
95
|
+
|
|
96
|
+
Before installing or sharing a kit, run validation from the flow-agents checkout:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm run validate:source -- --kit path/to/my-kit
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This runs the same repository contract validation used by `install-local`. A validation failure exits nonzero with a diagnostic. Fix errors and re-run until it passes cleanly.
|
|
103
|
+
|
|
104
|
+
The full source-tree validation (no `--kit` flag) additionally validates the built-in catalog and Builder Kit:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm run validate:source --
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Install locally
|
|
111
|
+
|
|
112
|
+
Once validation passes, install the kit into a target workspace:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npx @kontourai/flow-agents flow-kit install-local path/to/my-kit --dest /path/to/workspace
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`--dest` is the installed Flow Agents bundle root. When omitted the command uses the current directory. From a contributor checkout of this repository, the equivalent form is `npm run flow-kit -- <command>`.
|
|
119
|
+
|
|
120
|
+
Confirm the install:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx @kontourai/flow-agents flow-kit list --dest /path/to/workspace
|
|
124
|
+
npx @kontourai/flow-agents flow-kit status my-kit --dest /path/to/workspace
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`list` prints one summary line per installed kit. `status` prints JSON provenance including the SHA256 content hash and `installed` or `missing` state.
|
|
128
|
+
|
|
129
|
+
To replace an existing install after you update the kit source:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npx @kontourai/flow-agents flow-kit install-local path/to/my-kit --dest /path/to/workspace --update
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Activate
|
|
136
|
+
|
|
137
|
+
After installing, run activate to write runtime-local files into the workspace:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npx @kontourai/flow-agents flow-kit activate --dest /path/to/workspace --format json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The `codex-local` adapter is selected automatically. It writes Flow Definition copies under `.flow-agents/runtime/codex/flows/<kit-id>/` and an `activation.json` manifest. Declared `skills`, `docs`, `adapters`, `evals`, and `assets` are recorded as `skipped_assets` — they are not an error, just not activated yet.
|
|
144
|
+
|
|
145
|
+
When installing through `npx @kontourai/flow-agents init` with the Codex runtime, pass `--activate-kits` to run activation as part of init:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npx @kontourai/flow-agents init --runtime codex --dest /path/to/workspace --activate-kits --yes
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Troubleshooting
|
|
152
|
+
|
|
153
|
+
Common validation errors and fixes are documented in the [Flow Kit Repository Contract](flow-kit-repository-contract.md#common-failures). The most frequent:
|
|
154
|
+
|
|
155
|
+
- `kit.json: .schema_version must be "1.0"` — update the manifest.
|
|
156
|
+
- `kit.json: .id must be a stable kebab-case string` — use a lowercase id like `review-kit`.
|
|
157
|
+
- `kit.json: .flows must be a non-empty list` — declare at least one Flow Definition.
|
|
158
|
+
- `kit.json: flows[0].path points at missing Flow Definition` — add the file or fix the path.
|
|
159
|
+
- `kit.json: docs[0].path points at missing asset` — add the asset or remove the entry.
|
|
160
|
+
|
|
161
|
+
For path errors: all declared paths must be relative, must not contain `..`, and must point at existing files. Absolute paths are rejected because a kit must be portable between machines.
|
|
162
|
+
|
|
163
|
+
For conflicts on re-install: if you install a different source with an existing kit id, the command fails unless you pass `--update`. Use `--force` to re-copy an existing same-source install after validation.
|
|
164
|
+
|
|
165
|
+
See the [Flow Kit Repository Contract](flow-kit-repository-contract.md) for the full validation rules, registry schema, activation diagnostics, and the install/update/force semantics.
|
|
166
|
+
|
|
167
|
+
## Direction
|
|
168
|
+
|
|
169
|
+
Flow Kits are designed to be shareable workflow units — authored once, carried across teams and workspaces. The intended growth path is distribution from git remotes and a curated Kontour kit catalog of Kontour-authored kits covering work modes beyond software delivery. Today install is local-path only; remote fetch is explicitly a non-goal in this version.
|
|
@@ -207,7 +207,7 @@ The following tables show the canonical Flow Agents events and their correspondi
|
|
|
207
207
|
|
|
208
208
|
| Canonical Event | Claude Code | Codex | Kiro | opencode | pi |
|
|
209
209
|
| --- | --- | --- | --- | --- | --- |
|
|
210
|
-
| `agentSpawn` | `SessionStart` | `SessionStart` | `SessionStart` | `session.created` | `session_start` |
|
|
210
|
+
| `agentSpawn` | `SessionStart` | `SessionStart` | `SessionStart` | `session.created` (interactive mode only — NOT delivered to plugin hooks in `run`/non-interactive mode; verified v1.16.2) | `session_start` |
|
|
211
211
|
| `userPromptSubmit` | `UserPromptSubmit` | `UserPromptSubmit` | `UserPromptSubmit` | No native equivalent | `input` (closest; fires on user input, not confirmed submission) |
|
|
212
212
|
| `preToolUse` | `PreToolUse` | `PreToolUse` | `PreToolUse` | `tool.execute.before` | `tool_call` (blockable) |
|
|
213
213
|
| `permissionRequest` | `PermissionRequest` | `PermissionRequest` | No native equivalent | No native equivalent | No native equivalent |
|
|
@@ -333,7 +333,9 @@ Each adapter must include a conformance declaration in its adapter documentation
|
|
|
333
333
|
conformance_level: L1
|
|
334
334
|
host: opencode
|
|
335
335
|
event_coverage:
|
|
336
|
-
agentSpawn: session.created
|
|
336
|
+
agentSpawn: session.created — delivered in interactive mode; NOT delivered to plugin
|
|
337
|
+
hooks in run (non-interactive) mode (verified v1.16.2, 2026-06-11). agentSpawn
|
|
338
|
+
telemetry is absent from run-mode sessions; tool.invoke/tool.result are present.
|
|
337
339
|
userPromptSubmit: no native equivalent — workflow steering unavailable at turn boundary
|
|
338
340
|
preToolUse: tool.execute.before (full fidelity, blocking available)
|
|
339
341
|
postToolUse: tool.execute.after (full fidelity)
|
|
@@ -342,10 +344,14 @@ event_coverage:
|
|
|
342
344
|
subagentStart: no native equivalent
|
|
343
345
|
subagentStop: no native equivalent
|
|
344
346
|
policy_coverage:
|
|
345
|
-
workflow_steering: partial — injected at session.created only
|
|
347
|
+
workflow_steering: partial — injected at session.created only (interactive mode); unavailable in run mode
|
|
346
348
|
quality_gate: wired at tool.execute.after
|
|
347
349
|
stop_goal_fit: degraded — session.idle does not reliably fire at completion
|
|
348
350
|
config_protection: wired at tool.execute.before (blocking)
|
|
351
|
+
named_gaps:
|
|
352
|
+
session.created_run_mode: In opencode run mode, session.created is not delivered
|
|
353
|
+
to plugin hooks. This is an opencode runtime limitation with no known workaround
|
|
354
|
+
at the plugin API level. agentSpawn telemetry is NOT_VERIFIED for run-mode sessions.
|
|
349
355
|
```
|
|
350
356
|
|
|
351
357
|
---
|
|
@@ -470,3 +476,50 @@ node packaging/conformance/run-conformance.js \
|
|
|
470
476
|
```
|
|
471
477
|
|
|
472
478
|
See `packaging/conformance/README.md` for the full fixture inventory and declaration format.
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
## 9. Framework-Path Kit Activation (strands-local adapter)
|
|
483
|
+
|
|
484
|
+
**Added**: Issue #32 — Knowledge Kit S4: framework-path kit activation.
|
|
485
|
+
|
|
486
|
+
### 9.1 Decision record (Q3)
|
|
487
|
+
|
|
488
|
+
Kit flow activation for Strands workspaces is implemented as a new runtime adapter id (`strands-local`) in `src/runtime-adapters.ts`, not as kit-flow loading inside `FlowAgentsHooks`. This keeps the `FlowAgentsHooks` class free of catalog-layout knowledge and reuses the `readKitInventory` + `safeSegment` helpers from the `codex-local` path.
|
|
489
|
+
|
|
490
|
+
The CLI command is:
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
flow-kit activate --adapter strands-local [--dest DIR] [--source-root DIR]
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
This writes activated flow files to `.flow-agents/runtime/strands/flows/<kit-id>/<asset-id>.flow.json` and produces a parity-diagnostic `activation.json` (same schema as codex-local: `schema_version`, `adapter`, `supported_asset_classes`, `generated_runtime_files`, `skipped_assets`, `warnings`, `errors`).
|
|
497
|
+
|
|
498
|
+
### 9.2 Steering context surfacing (AC2)
|
|
499
|
+
|
|
500
|
+
`FlowAgentsHooks.steering_context()` (Python) and `FlowAgentsHooks.steeringContext()` (TypeScript) read the runtime flow files written by `strands-local` activation and include a `KIT FLOWS:` section in the steering context text. This section lists each activated kit flow by id and description so the agent is aware of available workflow guidance without the hooks needing to know the catalog layout at construction time.
|
|
501
|
+
|
|
502
|
+
**Python usage** (see ):
|
|
503
|
+
|
|
504
|
+
```
|
|
505
|
+
hooks = FlowAgentsHooks(workspace=".")
|
|
506
|
+
system_prompt = base_prompt + hooks.steering_context()
|
|
507
|
+
# steering_context() includes KIT FLOWS section if .flow-agents/runtime/strands/flows/ is populated
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**TypeScript usage**:
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
const hooks = new FlowAgentsHooks({ workspace: "." });
|
|
514
|
+
const systemPrompt = basePrompt + hooks.steeringContext();
|
|
515
|
+
// steeringContext() includes KIT FLOWS section if .flow-agents/runtime/strands/flows/ is populated
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### 9.3 Co-existence with codex-local
|
|
519
|
+
|
|
520
|
+
The `codex-local` and `strands-local` runtime directories are independent:
|
|
521
|
+
|
|
522
|
+
- `codex-local` writes to `.flow-agents/runtime/codex/`
|
|
523
|
+
- `strands-local` writes to `.flow-agents/runtime/strands/`
|
|
524
|
+
|
|
525
|
+
Running either adapter does not affect the other's runtime directory. Both adapters skip non-flow asset classes (skills, docs, adapters, evals, assets) with `reason: "asset class is diagnostic-only for <adapter>"`.
|
package/evals/acceptance/run.sh
CHANGED
|
@@ -11,10 +11,18 @@ run_one() {
|
|
|
11
11
|
bash "$ACCEPT_DIR/test_${name}_harness.sh"
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
run_knowledge_kit_live() {
|
|
15
|
+
echo ""
|
|
16
|
+
bash "$ACCEPT_DIR/test_knowledge_kit_live.sh"
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
case "$TARGET" in
|
|
15
20
|
kiro|claude|codex|opencode|pi)
|
|
16
21
|
run_one "$TARGET"
|
|
17
22
|
;;
|
|
23
|
+
knowledge-kit-live)
|
|
24
|
+
run_knowledge_kit_live
|
|
25
|
+
;;
|
|
18
26
|
all)
|
|
19
27
|
status=0
|
|
20
28
|
run_one kiro || status=1
|
|
@@ -22,10 +30,11 @@ case "$TARGET" in
|
|
|
22
30
|
run_one codex || status=1
|
|
23
31
|
run_one opencode || status=1
|
|
24
32
|
run_one pi || status=1
|
|
33
|
+
run_knowledge_kit_live || status=1
|
|
25
34
|
exit "$status"
|
|
26
35
|
;;
|
|
27
36
|
*)
|
|
28
|
-
echo "Usage: bash evals/acceptance/run.sh [all|kiro|claude|codex|opencode|pi]"
|
|
37
|
+
echo "Usage: bash evals/acceptance/run.sh [all|kiro|claude|codex|opencode|pi|knowledge-kit-live]"
|
|
29
38
|
exit 1
|
|
30
39
|
;;
|
|
31
40
|
esac
|