agentopology 0.1.0 → 0.2.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/README.md +70 -33
- package/dist/analyzer/index.d.ts +1 -0
- package/dist/analyzer/index.d.ts.map +1 -1
- package/dist/analyzer/index.js +35 -0
- package/dist/analyzer/index.js.map +1 -1
- package/dist/bindings/claude-code.d.ts.map +1 -1
- package/dist/bindings/claude-code.js +283 -2
- package/dist/bindings/claude-code.js.map +1 -1
- package/dist/bindings/openclaw.d.ts.map +1 -1
- package/dist/bindings/openclaw.js +390 -12
- package/dist/bindings/openclaw.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/docs/__tests__/docs.test.js +2 -1
- package/dist/docs/__tests__/docs.test.js.map +1 -1
- package/dist/docs/content.d.ts.map +1 -1
- package/dist/docs/content.js +730 -4
- package/dist/docs/content.js.map +1 -1
- package/dist/exporters/markdown.d.ts.map +1 -1
- package/dist/exporters/markdown.js +165 -0
- package/dist/exporters/markdown.js.map +1 -1
- package/dist/exporters/mermaid.d.ts.map +1 -1
- package/dist/exporters/mermaid.js +30 -0
- package/dist/exporters/mermaid.js.map +1 -1
- package/dist/import/__tests__/import.test.js +554 -0
- package/dist/import/__tests__/import.test.js.map +1 -1
- package/dist/import/claude-code.d.ts.map +1 -1
- package/dist/import/claude-code.js +2 -0
- package/dist/import/claude-code.js.map +1 -1
- package/dist/import/index.d.ts +1 -0
- package/dist/import/index.d.ts.map +1 -1
- package/dist/import/index.js +7 -1
- package/dist/import/index.js.map +1 -1
- package/dist/import/openclaw.d.ts +70 -0
- package/dist/import/openclaw.d.ts.map +1 -0
- package/dist/import/openclaw.js +1060 -0
- package/dist/import/openclaw.js.map +1 -0
- package/dist/import/serializer.d.ts.map +1 -1
- package/dist/import/serializer.js +171 -4
- package/dist/import/serializer.js.map +1 -1
- package/dist/parser/__tests__/parser.test.js +463 -0
- package/dist/parser/__tests__/parser.test.js.map +1 -1
- package/dist/parser/ast.d.ts +122 -0
- package/dist/parser/ast.d.ts.map +1 -1
- package/dist/parser/index.d.ts +14 -2
- package/dist/parser/index.d.ts.map +1 -1
- package/dist/parser/index.js +226 -5
- package/dist/parser/index.js.map +1 -1
- package/dist/parser/validator.d.ts +1 -1
- package/dist/parser/validator.d.ts.map +1 -1
- package/dist/parser/validator.js +214 -1
- package/dist/parser/validator.js.map +1 -1
- package/dist/visualizer/index.d.ts.map +1 -1
- package/dist/visualizer/index.js +263 -27
- package/dist/visualizer/index.js.map +1 -1
- package/examples/memory-system.at +162 -0
- package/examples/script-agent-pipeline.at +65 -0
- package/package.json +1 -1
- package/spec/grammar.md +345 -10
- package/spec/reserved-keywords.md +25 -1
- package/spec/validation.md +171 -2
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
topology knowledge-assistant : [supervisor, human-gate] {
|
|
2
|
+
|
|
3
|
+
meta {
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
description: "A knowledge-powered research assistant with semantic search, entity tracking, and episodic memory"
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
orchestrator {
|
|
9
|
+
model: opus
|
|
10
|
+
plan: auto
|
|
11
|
+
handles: [research, answer]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
agent researcher {
|
|
15
|
+
model: sonnet
|
|
16
|
+
description: "Searches knowledge bases and web for information"
|
|
17
|
+
tools: [Read, WebSearch, WebFetch]
|
|
18
|
+
memory: [knowledge-base, entities]
|
|
19
|
+
retrieval: smart-retrieval
|
|
20
|
+
permissions: autonomous
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
agent writer {
|
|
24
|
+
model: sonnet
|
|
25
|
+
description: "Synthesizes research into clear answers"
|
|
26
|
+
tools: [Read, Write]
|
|
27
|
+
memory: [knowledge-base, conversation-log]
|
|
28
|
+
retrieval: smart-retrieval
|
|
29
|
+
permissions: autonomous
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
action research {
|
|
33
|
+
kind: inline
|
|
34
|
+
description: "Research a topic using knowledge stores and web"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
action answer {
|
|
38
|
+
kind: inline
|
|
39
|
+
description: "Write a comprehensive answer from research"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
flow {
|
|
43
|
+
research -> researcher
|
|
44
|
+
researcher -> writer
|
|
45
|
+
writer -> answer
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
triggers {
|
|
49
|
+
command research {
|
|
50
|
+
pattern: "/research <topic>"
|
|
51
|
+
description: "Research a topic using the knowledge base and web"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
memory {
|
|
56
|
+
workspace: ".workspace/"
|
|
57
|
+
domains: ["domains/"]
|
|
58
|
+
references: ["references/"]
|
|
59
|
+
|
|
60
|
+
store knowledge-base {
|
|
61
|
+
type: semantic
|
|
62
|
+
description: "Project knowledge base with semantic search over documentation"
|
|
63
|
+
scope: org
|
|
64
|
+
isolation: soft
|
|
65
|
+
backend: lancedb
|
|
66
|
+
path: ".memory/semantic/"
|
|
67
|
+
|
|
68
|
+
embedding {
|
|
69
|
+
provider: ollama
|
|
70
|
+
model: "nomic-embed-text"
|
|
71
|
+
dimensions: 768
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
index {
|
|
75
|
+
collection: "docs"
|
|
76
|
+
metric: cosine
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
ingestion {
|
|
80
|
+
sources: ["docs/", "references/", "wiki/"]
|
|
81
|
+
chunking: recursive
|
|
82
|
+
chunk-size: 512
|
|
83
|
+
overlap: 50
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
search {
|
|
87
|
+
strategy: hybrid
|
|
88
|
+
rerank: true
|
|
89
|
+
top-k: 10
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
lifecycle {
|
|
93
|
+
retention: 365d
|
|
94
|
+
consolidation: 0.85
|
|
95
|
+
contradiction: overwrite
|
|
96
|
+
audit-log: false
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
store entities {
|
|
101
|
+
type: graph
|
|
102
|
+
description: "Entity and relationship tracking across conversations"
|
|
103
|
+
scope: org
|
|
104
|
+
isolation: soft
|
|
105
|
+
backend: kuzu
|
|
106
|
+
path: ".memory/graph/"
|
|
107
|
+
extraction: hybrid
|
|
108
|
+
|
|
109
|
+
lifecycle {
|
|
110
|
+
retention: 365d
|
|
111
|
+
contradiction: preserve
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
store conversation-log {
|
|
116
|
+
type: episodic
|
|
117
|
+
description: "Conversation history with temporal search"
|
|
118
|
+
scope: user
|
|
119
|
+
isolation: strict
|
|
120
|
+
backend: sqlite
|
|
121
|
+
path: ".memory/episodes.db"
|
|
122
|
+
|
|
123
|
+
lifecycle {
|
|
124
|
+
retention: 90d
|
|
125
|
+
decay-half-life: 30d
|
|
126
|
+
consolidation: 0.9
|
|
127
|
+
contradiction: bi-temporal
|
|
128
|
+
audit-log: true
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
store user-prefs {
|
|
133
|
+
type: user
|
|
134
|
+
description: "User preferences and settings"
|
|
135
|
+
scope: user
|
|
136
|
+
isolation: strict
|
|
137
|
+
backend: sqlite
|
|
138
|
+
path: ".memory/user.db"
|
|
139
|
+
|
|
140
|
+
lifecycle {
|
|
141
|
+
contradiction: overwrite
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
retrieval smart-retrieval {
|
|
146
|
+
sources: [knowledge-base, conversation-log, entities]
|
|
147
|
+
budget: 4096
|
|
148
|
+
|
|
149
|
+
scoring {
|
|
150
|
+
recency-weight: 0.3
|
|
151
|
+
semantic-weight: 0.5
|
|
152
|
+
importance-weight: 0.2
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
paths: [semantic, episodic, graph, hybrid]
|
|
156
|
+
rerank: true
|
|
157
|
+
diversity: true
|
|
158
|
+
cache-hit-threshold: 0.92
|
|
159
|
+
cache-hit-action: short-circuit
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Demo: DuckDB store backend
|
|
2
|
+
# Tests the duckdb backend addition in feat/script-agents-duckdb
|
|
3
|
+
|
|
4
|
+
topology script-agent-demo : [pipeline] {
|
|
5
|
+
|
|
6
|
+
meta {
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
description: "Demo: agent pipeline with DuckDB storage"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
orchestrator {
|
|
12
|
+
model: opus
|
|
13
|
+
handles: [start]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
action start {
|
|
17
|
+
kind: decision
|
|
18
|
+
description: "Begin pipeline"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
agent data-processor {
|
|
22
|
+
model: haiku
|
|
23
|
+
tools: [Bash, Read, Write]
|
|
24
|
+
description: "Extract and transform data"
|
|
25
|
+
reads: ["workspace/raw/"]
|
|
26
|
+
writes: ["workspace/processed/"]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
agent analyzer {
|
|
30
|
+
model: sonnet
|
|
31
|
+
tools: [Read, Write, Grep]
|
|
32
|
+
memory: [data-index]
|
|
33
|
+
description: "Analyze processed data using AI"
|
|
34
|
+
reads: ["workspace/processed/"]
|
|
35
|
+
writes: ["workspace/analysis/"]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
memory {
|
|
39
|
+
store data-index {
|
|
40
|
+
type: entity
|
|
41
|
+
scope: run
|
|
42
|
+
backend: duckdb
|
|
43
|
+
path: "workspace/index.duckdb"
|
|
44
|
+
|
|
45
|
+
search {
|
|
46
|
+
strategy: hybrid
|
|
47
|
+
top-k: 100
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
flow {
|
|
53
|
+
start -> data-processor
|
|
54
|
+
data-processor -> analyzer
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
tools {
|
|
58
|
+
tool process-data {
|
|
59
|
+
script: "scripts/process.py"
|
|
60
|
+
args: [input-dir, output-dir]
|
|
61
|
+
lang: python
|
|
62
|
+
description: "Transform raw data into structured format"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
package/package.json
CHANGED
package/spec/grammar.md
CHANGED
|
@@ -308,11 +308,8 @@ agent-field = 'role' ':' identifier
|
|
|
308
308
|
| 'isolation' ':' 'worktree'
|
|
309
309
|
| 'invocation' ':' ('manual' | 'auto')
|
|
310
310
|
| 'behavior' ':' ('advisory' | 'blocking')
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
# block (workspace structure). A dedicated agent.memory field would be
|
|
314
|
-
# redundant. Retained in the grammar for future consideration.
|
|
315
|
-
| 'memory' ':' ('user' | 'project' | 'local')
|
|
311
|
+
| 'memory' ':' name-list
|
|
312
|
+
| 'retrieval' ':' identifier
|
|
316
313
|
| 'skills' ':' name-list
|
|
317
314
|
| 'mcp-servers' ':' name-list
|
|
318
315
|
| 'background' ':' boolean
|
|
@@ -352,7 +349,8 @@ scale-field = 'mode' ':' ('auto' | 'fixed' | 'config')
|
|
|
352
349
|
| `isolation` | `worktree` | no | -- | Git worktree isolation |
|
|
353
350
|
| `invocation` | `manual` / `auto` | no | `auto` | User-triggered only |
|
|
354
351
|
| `behavior` | `advisory` / `blocking` | no | `blocking` | Advisory never blocks flow |
|
|
355
|
-
| `memory` |
|
|
352
|
+
| `memory` | name-list | no | `[]` | Store IDs this agent can access (V35) |
|
|
353
|
+
| `retrieval` | identifier | no | -- | Retrieval strategy ID for memory queries (V35) |
|
|
356
354
|
| `skills` | name-list | no | `[]` | Skills to preload |
|
|
357
355
|
| `mcp-servers` | name-list | no | `[]` | MCP servers available |
|
|
358
356
|
| `background` | boolean | no | `false` | Run in background |
|
|
@@ -455,8 +453,10 @@ Maps role identifiers to human-readable descriptions. Agents reference roles wit
|
|
|
455
453
|
### 4.9 `memory`
|
|
456
454
|
|
|
457
455
|
```ebnf
|
|
458
|
-
memory = 'memory' '{' memory-sub-block* '}'
|
|
456
|
+
memory = 'memory' '{' (memory-sub-block | store-block | retrieval-block)* '}'
|
|
459
457
|
memory-sub-block = identifier '{' (identifier ':' (string | identifier | name-list))* '}'
|
|
458
|
+
store-block = 'store' identifier '{' store-field* '}'
|
|
459
|
+
retrieval-block = 'retrieval' identifier '{' retrieval-field* '}'
|
|
460
460
|
```
|
|
461
461
|
|
|
462
462
|
```agenttopology
|
|
@@ -499,7 +499,341 @@ memory {
|
|
|
499
499
|
| `metrics` | `path` (string), `mode` (identifier: `append-only`) | Execution log |
|
|
500
500
|
| `workspace` | `path` (string), `protocol` (string), `structure` (name-list) | Per-run working directory |
|
|
501
501
|
|
|
502
|
-
Memory sub-blocks are named blocks with known field schemas.
|
|
502
|
+
Memory sub-blocks are named blocks with known field schemas. The `store` and `retrieval` blocks are typed named blocks parsed into `StoreNode[]` and `RetrievalNode[]` on the AST. Other unknown sub-block names produce a warning (V24).
|
|
503
|
+
|
|
504
|
+
#### 4.9.1 `store`
|
|
505
|
+
|
|
506
|
+
A named memory store declaration. Stores define the infrastructure for a specific type of agent memory -- backend, embedding model, indexing, ingestion, search, and lifecycle management.
|
|
507
|
+
|
|
508
|
+
```ebnf
|
|
509
|
+
store-block = 'store' identifier '{' store-field* '}'
|
|
510
|
+
store-field = 'type' ':' store-type
|
|
511
|
+
| 'description' ':' string
|
|
512
|
+
| 'scope' ':' scope-enum
|
|
513
|
+
| 'isolation' ':' isolation-enum
|
|
514
|
+
| 'backend' ':' backend-enum
|
|
515
|
+
| 'path' ':' string
|
|
516
|
+
| 'connection' ':' secret-string
|
|
517
|
+
| 'extraction' ':' extraction-enum
|
|
518
|
+
| embedding-block
|
|
519
|
+
| index-block
|
|
520
|
+
| ingestion-block
|
|
521
|
+
| search-block
|
|
522
|
+
| lifecycle-block
|
|
523
|
+
| backend-config-block
|
|
524
|
+
store-type = 'semantic' | 'episodic' | 'procedural' | 'entity'
|
|
525
|
+
| 'graph' | 'user' | 'session' | 'temporal'
|
|
526
|
+
scope-enum = 'agent' | 'user' | 'session' | 'org' | 'global'
|
|
527
|
+
isolation-enum = 'strict' | 'soft' | 'none'
|
|
528
|
+
backend-enum = 'lancedb' | 'sqlite-vec' | 'chroma' | 'kuzu' | 'falkordb'
|
|
529
|
+
| 'mongodb' | 'pinecone' | 'qdrant' | 'pgvector' | 'neo4j' | 'sqlite'
|
|
530
|
+
| 'duckdb'
|
|
531
|
+
extraction-enum = 'llm' | 'regex' | 'hybrid'
|
|
532
|
+
secret-string = 'secret'? string
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
```agenttopology
|
|
536
|
+
memory {
|
|
537
|
+
store codebase-knowledge {
|
|
538
|
+
type: semantic
|
|
539
|
+
description: "Indexed codebase documentation and patterns"
|
|
540
|
+
scope: agent
|
|
541
|
+
isolation: strict
|
|
542
|
+
backend: lancedb
|
|
543
|
+
path: ".memory/semantic/"
|
|
544
|
+
extraction: llm
|
|
545
|
+
|
|
546
|
+
embedding {
|
|
547
|
+
provider: ollama
|
|
548
|
+
model: "nomic-embed-text"
|
|
549
|
+
dimensions: 768
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
index {
|
|
553
|
+
collection: "chunks"
|
|
554
|
+
metric: cosine
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
ingestion {
|
|
558
|
+
sources: ["docs/", "references/"]
|
|
559
|
+
chunking: recursive
|
|
560
|
+
chunk-size: 512
|
|
561
|
+
overlap: 50
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
search {
|
|
565
|
+
strategy: hybrid
|
|
566
|
+
rerank: true
|
|
567
|
+
top-k: 10
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
lifecycle {
|
|
571
|
+
retention: 90d
|
|
572
|
+
decay-half-life: 30d
|
|
573
|
+
consolidation: 0.85
|
|
574
|
+
contradiction: overwrite
|
|
575
|
+
audit-log: true
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
store user-preferences {
|
|
580
|
+
type: user
|
|
581
|
+
description: "Per-user preferences and corrections"
|
|
582
|
+
scope: user
|
|
583
|
+
isolation: soft
|
|
584
|
+
backend: sqlite
|
|
585
|
+
path: ".memory/user.db"
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
store session-context {
|
|
589
|
+
type: session
|
|
590
|
+
description: "Short-lived conversation context"
|
|
591
|
+
scope: session
|
|
592
|
+
isolation: none
|
|
593
|
+
backend: sqlite-vec
|
|
594
|
+
path: ".memory/session/"
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
store knowledge-graph {
|
|
598
|
+
type: graph
|
|
599
|
+
description: "Entity relationships across the codebase"
|
|
600
|
+
scope: global
|
|
601
|
+
backend: kuzu
|
|
602
|
+
path: ".memory/graph/"
|
|
603
|
+
|
|
604
|
+
search {
|
|
605
|
+
strategy: graph
|
|
606
|
+
top-k: 20
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
store cloud-vectors {
|
|
611
|
+
type: semantic
|
|
612
|
+
description: "Cloud-hosted vector store"
|
|
613
|
+
scope: org
|
|
614
|
+
backend: pinecone
|
|
615
|
+
connection: secret "PINECONE_URL"
|
|
616
|
+
|
|
617
|
+
embedding {
|
|
618
|
+
provider: openai
|
|
619
|
+
model: "text-embedding-3-large"
|
|
620
|
+
dimensions: 3072
|
|
621
|
+
endpoint: secret "OPENAI_EMBEDDING_URL"
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
| Field | Type | Required | Default | Description |
|
|
628
|
+
|-------|------|----------|---------|-------------|
|
|
629
|
+
| `type` | store-type | yes | -- | Memory type classification |
|
|
630
|
+
| `description` | string | no | -- | Human-readable purpose |
|
|
631
|
+
| `scope` | scope-enum | no | -- | Access scope (V32 warning if omitted) |
|
|
632
|
+
| `isolation` | isolation-enum | no | -- | Isolation level between scopes |
|
|
633
|
+
| `backend` | backend-enum | yes | -- | Storage backend (V30 enum check) |
|
|
634
|
+
| `path` | string | no | -- | File system path for local backends |
|
|
635
|
+
| `connection` | secret-string | no | -- | Connection URI for remote backends (V34) |
|
|
636
|
+
| `extraction` | extraction-enum | no | -- | Entity/fact extraction method |
|
|
637
|
+
| `embedding` | embedding-block | no | -- | Embedding configuration (V31 warning if omitted for semantic/episodic/procedural) |
|
|
638
|
+
| `index` | index-block | no | -- | Index/collection configuration |
|
|
639
|
+
| `ingestion` | ingestion-block | no | -- | Data ingestion configuration |
|
|
640
|
+
| `search` | search-block | no | -- | Search/query configuration |
|
|
641
|
+
| `lifecycle` | lifecycle-block | no | -- | Memory lifecycle management |
|
|
642
|
+
| `backend-config` | backend-config-block | no | -- | Backend-specific passthrough |
|
|
643
|
+
|
|
644
|
+
**`connection` and secrets:** The `connection` field supports the `secret` modifier, parsed identically to `checkpoint.connection`. When `secret` is present, the string value is treated as a secret reference (e.g., `secret "PINECONE_URL"` references the `PINECONE_URL` secret).
|
|
645
|
+
|
|
646
|
+
**`backend-config`:** A passthrough block for backend-specific key-value pairs not covered by the standard fields. Stored as `Record<string, unknown>` on the AST. Same pattern as `ProviderDef.extra`.
|
|
647
|
+
|
|
648
|
+
**Local vs remote backends:** Backends `lancedb`, `sqlite-vec`, `sqlite`, `kuzu`, and `chroma` are local-first (use `path`). Backends `pinecone`, `qdrant`, `pgvector`, `neo4j`, `mongodb`, and `falkordb` are remote (require `connection`, V34).
|
|
649
|
+
|
|
650
|
+
##### `embedding` sub-block
|
|
651
|
+
|
|
652
|
+
```ebnf
|
|
653
|
+
embedding-block = 'embedding' '{' embedding-field* '}'
|
|
654
|
+
embedding-field = 'provider' ':' embedding-provider
|
|
655
|
+
| 'model' ':' string
|
|
656
|
+
| 'dimensions' ':' number
|
|
657
|
+
| 'endpoint' ':' secret-string
|
|
658
|
+
embedding-provider = 'ollama' | 'local' | 'voyage' | 'openai' | 'gemini'
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
| Field | Type | Required | Default | Description |
|
|
662
|
+
|-------|------|----------|---------|-------------|
|
|
663
|
+
| `provider` | embedding-provider | no | -- | Embedding provider |
|
|
664
|
+
| `model` | string | no | -- | Model identifier |
|
|
665
|
+
| `dimensions` | number | no | -- | Vector dimensions |
|
|
666
|
+
| `endpoint` | secret-string | no | -- | Endpoint URL or secret reference |
|
|
667
|
+
|
|
668
|
+
##### `index` sub-block
|
|
669
|
+
|
|
670
|
+
```ebnf
|
|
671
|
+
index-block = 'index' '{' index-field* '}'
|
|
672
|
+
index-field = 'collection' ':' string
|
|
673
|
+
| 'metric' ':' metric-enum
|
|
674
|
+
metric-enum = 'cosine' | 'euclidean' | 'dot-product'
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
| Field | Type | Required | Default | Description |
|
|
678
|
+
|-------|------|----------|---------|-------------|
|
|
679
|
+
| `collection` | string | no | -- | Collection or table name |
|
|
680
|
+
| `metric` | metric-enum | no | -- | Distance metric for vector similarity |
|
|
681
|
+
|
|
682
|
+
##### `ingestion` sub-block
|
|
683
|
+
|
|
684
|
+
```ebnf
|
|
685
|
+
ingestion-block = 'ingestion' '{' ingestion-field* '}'
|
|
686
|
+
ingestion-field = 'sources' ':' string-list
|
|
687
|
+
| 'chunking' ':' chunking-enum
|
|
688
|
+
| 'chunk-size' ':' number
|
|
689
|
+
| 'overlap' ':' number
|
|
690
|
+
chunking-enum = 'recursive' | 'sentence' | 'paragraph' | 'fixed'
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
| Field | Type | Required | Default | Description |
|
|
694
|
+
|-------|------|----------|---------|-------------|
|
|
695
|
+
| `sources` | string-list | no | `[]` | Source paths or globs to ingest |
|
|
696
|
+
| `chunking` | chunking-enum | no | -- | Chunking strategy |
|
|
697
|
+
| `chunk-size` | number | no | -- | Target chunk size in tokens or characters |
|
|
698
|
+
| `overlap` | number | no | -- | Overlap between chunks |
|
|
699
|
+
|
|
700
|
+
##### `search` sub-block
|
|
701
|
+
|
|
702
|
+
```ebnf
|
|
703
|
+
search-block = 'search' '{' search-field* '}'
|
|
704
|
+
search-field = 'strategy' ':' strategy-enum
|
|
705
|
+
| 'rerank' ':' boolean
|
|
706
|
+
| 'top-k' ':' number
|
|
707
|
+
strategy-enum = 'vector' | 'keyword' | 'hybrid' | 'graph'
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
| Field | Type | Required | Default | Description |
|
|
711
|
+
|-------|------|----------|---------|-------------|
|
|
712
|
+
| `strategy` | strategy-enum | no | -- | Search strategy |
|
|
713
|
+
| `rerank` | boolean | no | `false` | Whether to apply reranking |
|
|
714
|
+
| `top-k` | number | no | -- | Number of top results to return |
|
|
715
|
+
|
|
716
|
+
##### `lifecycle` sub-block
|
|
717
|
+
|
|
718
|
+
```ebnf
|
|
719
|
+
lifecycle-block = 'lifecycle' '{' lifecycle-field* '}'
|
|
720
|
+
lifecycle-field = 'retention' ':' duration
|
|
721
|
+
| 'decay-half-life' ':' duration
|
|
722
|
+
| 'consolidation' ':' number
|
|
723
|
+
| 'contradiction' ':' contradiction-enum
|
|
724
|
+
| 'audit-log' ':' boolean
|
|
725
|
+
duration = [0-9]+ ('d' | 'h' | 'm' | 'y')
|
|
726
|
+
contradiction-enum = 'overwrite' | 'preserve' | 'bi-temporal'
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
| Field | Type | Required | Default | Description |
|
|
730
|
+
|-------|------|----------|---------|-------------|
|
|
731
|
+
| `retention` | duration | no | -- | Retention period (e.g., `90d`, `1y`) |
|
|
732
|
+
| `decay-half-life` | duration | no | -- | Half-life for memory decay scoring |
|
|
733
|
+
| `consolidation` | number (0-1) | no | -- | Consolidation threshold |
|
|
734
|
+
| `contradiction` | contradiction-enum | no | -- | Contradiction resolution strategy |
|
|
735
|
+
| `audit-log` | boolean | no | `false` | Whether to maintain an audit log |
|
|
736
|
+
|
|
737
|
+
##### `backend-config` sub-block
|
|
738
|
+
|
|
739
|
+
```ebnf
|
|
740
|
+
backend-config-block = 'backend-config' '{' (identifier ':' value)* '}'
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
A passthrough block for backend-specific configuration. All key-value pairs are stored as-is in `StoreNode.backendConfig` without schema validation.
|
|
744
|
+
|
|
745
|
+
#### 4.9.2 `retrieval`
|
|
746
|
+
|
|
747
|
+
A named retrieval strategy declaration. Retrieval blocks define how an agent queries across one or more stores -- source selection, scoring weights, budget constraints, and cache-hit routing.
|
|
748
|
+
|
|
749
|
+
```ebnf
|
|
750
|
+
retrieval-block = 'retrieval' identifier '{' retrieval-field* '}'
|
|
751
|
+
retrieval-field = 'sources' ':' name-list
|
|
752
|
+
| 'budget' ':' number
|
|
753
|
+
| 'paths' ':' name-list
|
|
754
|
+
| 'rerank' ':' boolean
|
|
755
|
+
| 'diversity' ':' boolean
|
|
756
|
+
| 'cache-hit-threshold' ':' number
|
|
757
|
+
| 'cache-hit-action' ':' cache-hit-enum
|
|
758
|
+
| scoring-block
|
|
759
|
+
cache-hit-enum = 'short-circuit' | 'augment' | 'pass-through'
|
|
760
|
+
scoring-block = 'scoring' '{' scoring-field* '}'
|
|
761
|
+
scoring-field = 'recency-weight' ':' number
|
|
762
|
+
| 'semantic-weight' ':' number
|
|
763
|
+
| 'importance-weight' ':' number
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
```agenttopology
|
|
767
|
+
memory {
|
|
768
|
+
retrieval balanced {
|
|
769
|
+
sources: [codebase-knowledge, user-preferences, knowledge-graph]
|
|
770
|
+
budget: 4096
|
|
771
|
+
|
|
772
|
+
scoring {
|
|
773
|
+
recency-weight: 0.3
|
|
774
|
+
semantic-weight: 0.5
|
|
775
|
+
importance-weight: 0.2
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
paths: [semantic, episodic, graph]
|
|
779
|
+
rerank: true
|
|
780
|
+
diversity: true
|
|
781
|
+
|
|
782
|
+
cache-hit-threshold: 0.92
|
|
783
|
+
cache-hit-action: short-circuit
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
retrieval fast-lookup {
|
|
787
|
+
sources: [session-context]
|
|
788
|
+
budget: 1024
|
|
789
|
+
rerank: false
|
|
790
|
+
|
|
791
|
+
cache-hit-threshold: 0.95
|
|
792
|
+
cache-hit-action: short-circuit
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
| Field | Type | Required | Default | Description |
|
|
798
|
+
|-------|------|----------|---------|-------------|
|
|
799
|
+
| `sources` | name-list | no | `[]` | Store IDs to draw from (V33 reference check) |
|
|
800
|
+
| `budget` | number | no | -- | Token budget for retrieved context |
|
|
801
|
+
| `paths` | name-list | no | `[]` | Retrieval paths to activate |
|
|
802
|
+
| `rerank` | boolean | no | `false` | Whether to apply cross-source reranking |
|
|
803
|
+
| `diversity` | boolean | no | `false` | Whether to enforce diversity across results |
|
|
804
|
+
| `cache-hit-threshold` | number (0-1) | no | -- | Similarity threshold for cache-hit detection |
|
|
805
|
+
| `cache-hit-action` | cache-hit-enum | no | -- | Action on cache hit |
|
|
806
|
+
| `scoring` | scoring-block | no | -- | Scoring weight configuration |
|
|
807
|
+
|
|
808
|
+
**`scoring` sub-block:** Weights should sum to 1.0 but this is not enforced at parse time. Bindings may normalize weights at runtime.
|
|
809
|
+
|
|
810
|
+
| Scoring Field | Type | Required | Default | Description |
|
|
811
|
+
|---------------|------|----------|---------|-------------|
|
|
812
|
+
| `recency-weight` | number (0-1) | no | -- | Weight for recency in scoring |
|
|
813
|
+
| `semantic-weight` | number (0-1) | no | -- | Weight for semantic similarity |
|
|
814
|
+
| `importance-weight` | number (0-1) | no | -- | Weight for importance/frequency |
|
|
815
|
+
|
|
816
|
+
**Memory-gated routing:** The `cache-hit-threshold` and `cache-hit-action` fields enable memory-gated routing -- when a query closely matches existing memories, the retrieval strategy can short-circuit (skip the LLM call), augment (add cached answer to context), or pass through (proceed normally). This is a first-class declarative primitive for BudgetMem-style memory optimization.
|
|
817
|
+
|
|
818
|
+
#### 4.9.3 Agent-Level Memory References
|
|
819
|
+
|
|
820
|
+
Agents reference stores and retrieval strategies via two new fields on the `agent` block:
|
|
821
|
+
|
|
822
|
+
```agenttopology
|
|
823
|
+
agent researcher {
|
|
824
|
+
model: sonnet
|
|
825
|
+
memory: [codebase-knowledge, session-context]
|
|
826
|
+
retrieval: balanced
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
agent assistant {
|
|
830
|
+
model: haiku
|
|
831
|
+
memory: [user-preferences, session-context]
|
|
832
|
+
retrieval: fast-lookup
|
|
833
|
+
}
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
The `memory` field is a name-list of store IDs. The `retrieval` field is a single identifier referencing a retrieval strategy. Both are validated against declared stores and retrievals (V35).
|
|
503
837
|
|
|
504
838
|
---
|
|
505
839
|
|
|
@@ -1323,7 +1657,7 @@ agent expensive-thinker {
|
|
|
1323
1657
|
|
|
1324
1658
|
## 5. Validation Rules
|
|
1325
1659
|
|
|
1326
|
-
See `validation.md` for the complete list of
|
|
1660
|
+
See `validation.md` for the complete list of 35 validation rules with examples.
|
|
1327
1661
|
|
|
1328
1662
|
---
|
|
1329
1663
|
|
|
@@ -1354,7 +1688,8 @@ All optional fields and their defaults when omitted:
|
|
|
1354
1688
|
| `agent` | `isolation` | -- (no isolation) |
|
|
1355
1689
|
| `agent` | `invocation` | `auto` |
|
|
1356
1690
|
| `agent` | `behavior` | `blocking` |
|
|
1357
|
-
| `agent` | `memory` |
|
|
1691
|
+
| `agent` | `memory` | `[]` |
|
|
1692
|
+
| `agent` | `retrieval` | -- (none) |
|
|
1358
1693
|
| `agent` | `skills` | `[]` |
|
|
1359
1694
|
| `agent` | `mcp-servers` | `[]` |
|
|
1360
1695
|
| `agent` | `background` | `false` |
|
|
@@ -126,6 +126,30 @@ round-robin, random, reflection, rate-limit
|
|
|
126
126
|
|
|
127
127
|
---
|
|
128
128
|
|
|
129
|
+
## Wave 8 Keywords (Agent Memory)
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
store, retrieval, embedding, ingestion, lifecycle, scoring, backend-config,
|
|
133
|
+
type, scope, backend, connection, extraction,
|
|
134
|
+
provider, dimensions, endpoint, collection, metric,
|
|
135
|
+
sources, chunking, chunk-size, overlap,
|
|
136
|
+
strategy, rerank, top-k,
|
|
137
|
+
retention, decay-half-life, consolidation, contradiction, audit-log,
|
|
138
|
+
budget, paths, diversity, cache-hit-threshold, cache-hit-action,
|
|
139
|
+
recency-weight, semantic-weight, importance-weight,
|
|
140
|
+
semantic, episodic, procedural, entity, graph, temporal,
|
|
141
|
+
lancedb, sqlite-vec, chroma, kuzu, falkordb, pinecone, qdrant, pgvector,
|
|
142
|
+
ollama, voyage, gemini,
|
|
143
|
+
cosine, euclidean, dot-product,
|
|
144
|
+
recursive, paragraph,
|
|
145
|
+
vector, keyword, hybrid,
|
|
146
|
+
overwrite, preserve, bi-temporal,
|
|
147
|
+
short-circuit, augment, pass-through,
|
|
148
|
+
strict, soft, org, global
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
129
153
|
## Not Reserved
|
|
130
154
|
|
|
131
155
|
These are free-form values and can be used as names:
|
|
@@ -143,5 +167,5 @@ Environment block field names, custom role names, and user-defined enum values a
|
|
|
143
167
|
Reserved for future use, not yet in grammar:
|
|
144
168
|
|
|
145
169
|
```
|
|
146
|
-
event
|
|
170
|
+
event, working
|
|
147
171
|
```
|