@vraxis/agent-v 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/AGENTS.md +61 -0
- package/ARCHITECTURE.md +148 -0
- package/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/compatibility.json +41 -0
- package/dist/adapters/ai-sdk/index.d.ts +46 -0
- package/dist/adapters/ai-sdk/index.d.ts.map +1 -0
- package/dist/adapters/ai-sdk/index.js +383 -0
- package/dist/adapters/ai-sdk/index.js.map +1 -0
- package/dist/adapters/local-cli/definitions.d.ts +22 -0
- package/dist/adapters/local-cli/definitions.d.ts.map +1 -0
- package/dist/adapters/local-cli/definitions.js +72 -0
- package/dist/adapters/local-cli/definitions.js.map +1 -0
- package/dist/adapters/local-cli/engine.d.ts +26 -0
- package/dist/adapters/local-cli/engine.d.ts.map +1 -0
- package/dist/adapters/local-cli/engine.js +200 -0
- package/dist/adapters/local-cli/engine.js.map +1 -0
- package/dist/adapters/local-cli/index.d.ts +6 -0
- package/dist/adapters/local-cli/index.d.ts.map +1 -0
- package/dist/adapters/local-cli/index.js +6 -0
- package/dist/adapters/local-cli/index.js.map +1 -0
- package/dist/adapters/local-cli/parsing.d.ts +7 -0
- package/dist/adapters/local-cli/parsing.d.ts.map +1 -0
- package/dist/adapters/local-cli/parsing.js +95 -0
- package/dist/adapters/local-cli/parsing.js.map +1 -0
- package/dist/adapters/local-cli/process.d.ts +12 -0
- package/dist/adapters/local-cli/process.d.ts.map +1 -0
- package/dist/adapters/local-cli/process.js +19 -0
- package/dist/adapters/local-cli/process.js.map +1 -0
- package/dist/adapters/local-cli/store.d.ts +11 -0
- package/dist/adapters/local-cli/store.d.ts.map +1 -0
- package/dist/adapters/local-cli/store.js +11 -0
- package/dist/adapters/local-cli/store.js.map +1 -0
- package/dist/adapters/ollama/index.d.ts +45 -0
- package/dist/adapters/ollama/index.d.ts.map +1 -0
- package/dist/adapters/ollama/index.js +155 -0
- package/dist/adapters/ollama/index.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +116 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/agent-v.d.ts +29 -0
- package/dist/core/agent-v.d.ts.map +1 -0
- package/dist/core/agent-v.js +153 -0
- package/dist/core/agent-v.js.map +1 -0
- package/dist/core/config.d.ts +31 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +21 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/contracts.d.ts +135 -0
- package/dist/core/contracts.d.ts.map +1 -0
- package/dist/core/contracts.js +2 -0
- package/dist/core/contracts.js.map +1 -0
- package/dist/core/errors.d.ts +12 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +27 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events.d.ts +74 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +14 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/extensions.d.ts +80 -0
- package/dist/core/extensions.d.ts.map +1 -0
- package/dist/core/extensions.js +77 -0
- package/dist/core/extensions.js.map +1 -0
- package/dist/core/index.d.ts +12 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/memory.d.ts +15 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +21 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/output.d.ts +10 -0
- package/dist/core/output.d.ts.map +1 -0
- package/dist/core/output.js +15 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/registry.d.ts +13 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +29 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/types.d.ts +141 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +21 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/version.d.ts +3 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +3 -0
- package/dist/core/version.js.map +1 -0
- package/dist/node/doctor.d.ts +50 -0
- package/dist/node/doctor.d.ts.map +1 -0
- package/dist/node/doctor.js +121 -0
- package/dist/node/doctor.js.map +1 -0
- package/dist/node/index.d.ts +26 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +84 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/skills.d.ts +12 -0
- package/dist/node/skills.d.ts.map +1 -0
- package/dist/node/skills.js +96 -0
- package/dist/node/skills.js.map +1 -0
- package/dist/testing/index.d.ts +25 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +33 -0
- package/dist/testing/index.js.map +1 -0
- package/examples/approved-tool.ts +56 -0
- package/examples/basic-ai-sdk.ts +29 -0
- package/examples/custom-model-resolver.ts +14 -0
- package/examples/filesystem-skill.ts +12 -0
- package/examples/local-cli.ts +28 -0
- package/examples/ollama.ts +15 -0
- package/examples/sessions-and-events.ts +18 -0
- package/examples/smoke.ts +35 -0
- package/examples/tsconfig.json +16 -0
- package/llms.txt +13 -0
- package/package.json +97 -0
- package/skills/agent-v/SKILL.md +39 -0
- package/skills/agent-v/references/integration-patterns.md +57 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Working on agent-v
|
|
2
|
+
|
|
3
|
+
`agent-v` is a provider-neutral execution engine. Preserve the boundary between reusable execution mechanics and product-owned meaning.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
Read these files before changing behavior:
|
|
8
|
+
|
|
9
|
+
1. `README.md` for the supported consumer surface.
|
|
10
|
+
2. `ARCHITECTURE.md` for dependency and safety boundaries.
|
|
11
|
+
3. `compatibility.json` for adapter strategies and dependency ranges.
|
|
12
|
+
4. The relevant executable example under `examples/`.
|
|
13
|
+
|
|
14
|
+
Use current local dependency documentation and source when editing an adapter. In particular, inspect `node_modules/ai/docs` and `node_modules/ai/src` before changing AI SDK integration code.
|
|
15
|
+
|
|
16
|
+
## Package routing
|
|
17
|
+
|
|
18
|
+
- `@vraxis/agent-v`: provider-neutral contracts, registries, policies, and composition.
|
|
19
|
+
- `@vraxis/agent-v/ai-sdk`: AI SDK structured generation and tool agents.
|
|
20
|
+
- `@vraxis/agent-v/local-cli`: bounded Codex, OpenCode, Claude Code, and Cursor runtime integration.
|
|
21
|
+
- `@vraxis/agent-v/ollama`: optional Ollama model runtime support.
|
|
22
|
+
- `@vraxis/agent-v/node`: filesystem persistence, diagnostics, and Agent Skills loading.
|
|
23
|
+
- `@vraxis/agent-v/testing`: deterministic fakes and approval policies.
|
|
24
|
+
|
|
25
|
+
Do not import adapter or Node types into `src/core`. Optional provider dependencies must remain isolated behind their package subpath.
|
|
26
|
+
|
|
27
|
+
## Non-negotiable invariants
|
|
28
|
+
|
|
29
|
+
- Every execution requires an explicit `ExecutionScope`.
|
|
30
|
+
- Tool input and output are both validated.
|
|
31
|
+
- External-side-effect and privileged tools require approval.
|
|
32
|
+
- Skill tool allowlists fail closed; tools are never silently dropped.
|
|
33
|
+
- Requested workspace access must be enforceable by the selected runtime.
|
|
34
|
+
- Never retry by weakening sandbox, approval, permission, schema, or isolation requirements.
|
|
35
|
+
- Every run records an adapter strategy. Local executables and model runtimes record detected versions when available.
|
|
36
|
+
- Credentials remain host-resolved values; config, events, and sessions store references only.
|
|
37
|
+
- Product evidence policy, prompts, ranking, retrieval, billing, and UX stay outside this package.
|
|
38
|
+
|
|
39
|
+
## Public API changes
|
|
40
|
+
|
|
41
|
+
There are no legacy consumers to preserve by default, but public changes must still be deliberate and internally consistent:
|
|
42
|
+
|
|
43
|
+
1. Update types and runtime behavior together.
|
|
44
|
+
2. Add a behavioral test, not only a type assertion.
|
|
45
|
+
3. Update the relevant example and `compatibility.json`.
|
|
46
|
+
4. Update `README.md`, `ARCHITECTURE.md`, or `CHANGELOG.md` when the consumer contract changes.
|
|
47
|
+
5. Keep package exports and the built-package smoke test synchronized.
|
|
48
|
+
|
|
49
|
+
Do not advertise a capability until an adapter can enforce it and a test demonstrates it.
|
|
50
|
+
|
|
51
|
+
## Verification
|
|
52
|
+
|
|
53
|
+
Run the complete release gate:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm run check
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This must typecheck source and tests, run behavioral tests, build declarations and JavaScript, compile and execute consumer examples, verify package imports and CLI help, and perform an npm package dry run.
|
|
60
|
+
|
|
61
|
+
Live probes are evidence beyond unit tests. They may use credentials, local services, or paid models, so run them only when the task authorizes that external action. Never download an Ollama model or start a background service merely to make a test pass.
|
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Objective
|
|
4
|
+
|
|
5
|
+
`agent-v` is the stable application-facing contract over changing AI providers, orchestration frameworks, and local agent runtimes. It optimizes for substitution, auditability, client isolation, local ownership, and narrowly scoped capabilities.
|
|
6
|
+
|
|
7
|
+
There are no current consumers to preserve. Version 0.2 intentionally chooses explicit, fail-closed contracts over compatibility with the 0.1 prototype.
|
|
8
|
+
|
|
9
|
+
## Dependency rule
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
products ───────────────► agent-v core ◄────────────── adapters
|
|
13
|
+
domain policy + UX contracts + policy ports AI SDK / local CLI / future engines
|
|
14
|
+
▲
|
|
15
|
+
│
|
|
16
|
+
host persistence, identity,
|
|
17
|
+
credentials, and telemetry
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The core imports no provider SDK and no Node-only module. Adapters translate framework behavior into normalized contracts and events. Products do not expose provider result objects to their domain layer.
|
|
21
|
+
|
|
22
|
+
## Engine contracts
|
|
23
|
+
|
|
24
|
+
The engine types remain separate because they have different safety semantics:
|
|
25
|
+
|
|
26
|
+
1. `StructuredModelEngine` performs one schema-bound model operation.
|
|
27
|
+
2. `ToolAgentEngine` runs a bounded model/tool loop and can stream normalized events.
|
|
28
|
+
3. `CodingRuntimeEngine` invokes an installed coding agent against an explicitly scoped workspace.
|
|
29
|
+
|
|
30
|
+
`EngineRegistry` resolves by id, kind, and capabilities. It does not silently substitute a weaker engine.
|
|
31
|
+
|
|
32
|
+
## Mandatory execution scope
|
|
33
|
+
|
|
34
|
+
Every run supplies `ExecutionScope`:
|
|
35
|
+
|
|
36
|
+
- tenant, project, principal, and optional engagement isolate persisted state and event queries;
|
|
37
|
+
- principal, roles, and permissions drive host and tool policy;
|
|
38
|
+
- optional engagement id supports consulting/client work without inventing a separate runtime;
|
|
39
|
+
- data classification gives middleware and adapters a stable privacy signal.
|
|
40
|
+
|
|
41
|
+
The same scope is attached to approval requests, sessions, run events, tool contexts, and model resolution. This prevents a universal engine from relying on ambient application identity.
|
|
42
|
+
|
|
43
|
+
## Tools and authority
|
|
44
|
+
|
|
45
|
+
An `AgentTool` declares a stable name/version, JSON-schema input and output contracts, risk, side-effect behavior, required permissions, approval requirement, and timeout. Execution follows this order:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
model tool call
|
|
49
|
+
→ validate input
|
|
50
|
+
→ verify scoped permissions
|
|
51
|
+
→ request and record approval when required
|
|
52
|
+
→ execute with cancellation and timeout
|
|
53
|
+
→ validate output
|
|
54
|
+
→ return normalized result to the model
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
External-side-effect and privileged tools must require approval. A host approval policy remains authoritative; skill metadata can never bypass it. Tool failures emitted as events use safe normalized messages.
|
|
58
|
+
|
|
59
|
+
The shared repository should contain broadly reusable, well-tested tool contracts and adapters. Product-specific tools stay with the product until their semantics are genuinely shared. This avoids turning `agent-v` into an ungoverned catalog with ambient authority.
|
|
60
|
+
|
|
61
|
+
## Skills and agents
|
|
62
|
+
|
|
63
|
+
- An **agent blueprint** selects exactly one engine or profile, instructions, skills, tools, required capabilities, and a step bound.
|
|
64
|
+
- A **skill** is portable domain guidance plus a tool allowlist and optional evidence artifacts.
|
|
65
|
+
- An **extension** packages tools, skills, and middleware but gains no authority merely by registration.
|
|
66
|
+
- **Middleware** handles cross-cutting policy, telemetry, redaction, and budget enforcement supplied by a host.
|
|
67
|
+
|
|
68
|
+
When an agent selects skills, every requested tool must appear in their combined allowlist. A mismatch rejects preparation rather than silently reducing capability.
|
|
69
|
+
|
|
70
|
+
The Node adapter loads the open Agent Skills directory format: `SKILL.md` with optional scripts, references, and assets. Loading only validates and indexes content. Script execution requires a separate explicit tool or sandbox owned by the host.
|
|
71
|
+
|
|
72
|
+
## Models, profiles, and credentials
|
|
73
|
+
|
|
74
|
+
The AI SDK adapter resolves a model per run. Resolution can use a static model, a model registry, or a host function receiving model id, run id, execution scope, metadata, and credential reference. Provenance describes what was actually selected; a request cannot relabel a static model as something else.
|
|
75
|
+
|
|
76
|
+
Every provenance record includes an adapter strategy identifier. Local CLI adapters additionally detect and record the executable version before invocation. Model resolvers may return authoritative runtime provenance with their model; the Ollama resolver uses this to record its live daemon version. These fields are evidence for compatibility diagnosis, not promises that an unverified version is supported.
|
|
77
|
+
|
|
78
|
+
Profiles are configuration, not engines. They bind a blueprint to an engine id, model id, and opaque credential reference. The host resolves secrets at execution time; configuration and events contain references, never credential values.
|
|
79
|
+
|
|
80
|
+
This keeps the core compatible with direct provider clients, the Vercel AI SDK, LangGraph, durable workflow runtimes, local models, and future harnesses without adopting their types.
|
|
81
|
+
|
|
82
|
+
## Events, sessions, and persistence
|
|
83
|
+
|
|
84
|
+
Adapters normalize execution into:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
run.started
|
|
88
|
+
model.started / model.completed
|
|
89
|
+
text.delta*
|
|
90
|
+
tool.requested
|
|
91
|
+
approval.requested → approval.resolved
|
|
92
|
+
tool.completed | tool.failed
|
|
93
|
+
run.completed | run.failed
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Events are UI-neutral and scope-carrying. `AgentMessage` uses typed parts for text, JSON, artifacts, files, and images rather than overloading one string.
|
|
97
|
+
|
|
98
|
+
Persistence is port-based:
|
|
99
|
+
|
|
100
|
+
- `ConfigStore` stores profiles and safe defaults.
|
|
101
|
+
- `SessionStore` stores host-approved conversational state by scope.
|
|
102
|
+
- `RunEventStore` stores normalized execution history by scope.
|
|
103
|
+
- `CredentialResolver` is a host port for resolving opaque references.
|
|
104
|
+
|
|
105
|
+
The Node implementation uses private atomic JSON files and a serialized append-only JSONL ledger. Products can replace these with SQLite, Postgres, object storage, encrypted stores, or consulting-specific infrastructure without changing agent definitions.
|
|
106
|
+
|
|
107
|
+
## Local runtime control plane
|
|
108
|
+
|
|
109
|
+
Local coding agents are fallible external systems:
|
|
110
|
+
|
|
111
|
+
- installed, authenticated/verified, and runnable are distinct states;
|
|
112
|
+
- readiness belongs to an executable version and expires when that version changes;
|
|
113
|
+
- execution has time and output bounds and closes stdin immediately;
|
|
114
|
+
- schema/output files are private and temporary;
|
|
115
|
+
- workspace access defaults to read-only and must match an advertised enforceable capability;
|
|
116
|
+
- unstructured or schema-invalid output is rejected and can receive one bounded repair attempt;
|
|
117
|
+
- safe failure categories are emitted without persisting raw diagnostics.
|
|
118
|
+
|
|
119
|
+
Codex supports enforced read-only and workspace-write modes. OpenCode currently advertises workspace-write only. Claude Code advertises read-only only. Cursor remains discoverable but does not advertise structured output, so the engine refuses to run it through the structured contract.
|
|
120
|
+
|
|
121
|
+
Ollama is a model runtime rather than a coding CLI and therefore lives in its own optional adapter. It verifies the native version and tags endpoints, confirms the requested model is installed, and delegates model/tool protocol behavior to the AI SDK 7-compatible `ai-sdk-ollama` provider. Products that do not use Ollama do not load or require that dependency.
|
|
122
|
+
|
|
123
|
+
## Product boundary
|
|
124
|
+
|
|
125
|
+
Keep meaning and judgment in the product:
|
|
126
|
+
|
|
127
|
+
- Distribution OS: evidence scoring, opportunity ranking, founder voice, channel policy, approval UX, and outcome learning.
|
|
128
|
+
- Aperta: proof graphs, patch verification, repository policy, and ownership claims.
|
|
129
|
+
- Reader products: document ingestion, layout, highlights, search/retrieval, pedagogy, and citation presentation.
|
|
130
|
+
- Consulting: client-specific prompts, data connectors, deliverables, retention rules, and contractual policy.
|
|
131
|
+
|
|
132
|
+
Centralize execution mechanisms only when their semantics and safety rules are reusable.
|
|
133
|
+
|
|
134
|
+
## Verification standard
|
|
135
|
+
|
|
136
|
+
A release must pass strict TypeScript checking, deterministic unit/integration tests, a production build, compiled and executed consumer examples, imports from the built package subpaths, CLI help execution, and `npm pack --dry-run`. CI runs this suite on the minimum Node version and the current release line.
|
|
137
|
+
|
|
138
|
+
## Agent accuracy surface
|
|
139
|
+
|
|
140
|
+
Coding-agent guidance is part of the release contract rather than informal prose:
|
|
141
|
+
|
|
142
|
+
- `AGENTS.md` governs repository changes and dependency direction.
|
|
143
|
+
- `skills/agent-v` routes consuming agents to the correct engine and safety contract.
|
|
144
|
+
- `examples/` are executable documentation compiled against package exports after every build.
|
|
145
|
+
- `compatibility.json` is checked against runtime strategy identifiers and capabilities.
|
|
146
|
+
- `agent-v doctor` exposes dependency and readiness evidence without making inference calls by default.
|
|
147
|
+
|
|
148
|
+
These artifacts must change with the implementation they describe. Documentation that cannot be compiled or mechanically compared is supporting explanation, not authoritative API evidence.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- Add a packaged `agent-v` Agent Skill and repository guidance for coding agents.
|
|
6
|
+
- Add executable consumer examples compiled against the built package exports.
|
|
7
|
+
- Add `agent-v doctor` with safe dependency, CLI, authentication-probe, and Ollama readiness reporting.
|
|
8
|
+
- Add machine-readable compatibility metadata synchronized with executable runtime strategies.
|
|
9
|
+
- Add the package version constant and strengthen public API guidance for automated consumers.
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
12
|
+
|
|
13
|
+
- Record an adapter strategy on every run and the detected executable version on local CLI runs.
|
|
14
|
+
- Add a first-class optional Ollama adapter for AI SDK 7 with daemon readiness, installed-model checks, structured generation, tool agents, and runtime-aware provenance.
|
|
15
|
+
- Allow AI SDK model resolvers to return authoritative provenance alongside the resolved model.
|
|
16
|
+
|
|
17
|
+
## 0.2.0
|
|
18
|
+
|
|
19
|
+
- Require tenant, project, principal, role, permission, and data-classification scope on every execution.
|
|
20
|
+
- Make tool input and output contracts, risk, side effects, permissions, approval, version, and timeout explicit.
|
|
21
|
+
- Resolve AI SDK models per run, including scoped credential references supplied by the host.
|
|
22
|
+
- Add scoped memory and filesystem session stores plus scoped run-event ledgers.
|
|
23
|
+
- Load portable Agent Skills packages from `SKILL.md` without executing bundled resources.
|
|
24
|
+
- Refuse local runtime access modes the selected CLI cannot enforce.
|
|
25
|
+
- Add typed multimodal message parts, session continuation, event persistence, CI, and package-surface smoke tests.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# agent-v
|
|
2
|
+
|
|
3
|
+
`agent-v` is a provider-neutral TypeScript engine for building inspectable agentic products. It centralizes the mechanics that should be shared across products—runtime selection, scoped execution, tools, approvals, skills, sessions, events, artifacts, and testing—while leaving domain truth and user experience in each application.
|
|
4
|
+
|
|
5
|
+
It is an engine, not a chatbot framework and not a repository of every product-specific tool. Distribution OS can own evidence and channel policy, Aperta can own proof graphs, a reader can own PDF/EPUB ingestion and pedagogy, and consulting products can own client-specific workflows while all use the same execution contract.
|
|
6
|
+
|
|
7
|
+
## What works in 0.4
|
|
8
|
+
|
|
9
|
+
- Vercel AI SDK 7 structured generation, tool loops, streaming, and per-run model resolution.
|
|
10
|
+
- Codex CLI, OpenCode, and Claude Code runtime adapters with honest access-mode capabilities and bounded schema output. Cursor is discoverable but rejected for structured execution until its adapter can guarantee the contract.
|
|
11
|
+
- Local Ollama models through an optional AI SDK 7-compatible adapter with daemon and installed-model readiness checks.
|
|
12
|
+
- Typed tools with input and output validation, version, risk, side-effect, permission, approval, and timeout declarations.
|
|
13
|
+
- Portable skills defined in code or loaded from standard `SKILL.md` packages.
|
|
14
|
+
- Tenant/project/principal execution scope on every run, approval, event, session, and model-resolution request.
|
|
15
|
+
- Memory and local JSON/JSONL persistence with tenant/project isolation.
|
|
16
|
+
- Deterministic fakes, provider-free tests, built-package smoke testing, and CI on Node 22 and 24.
|
|
17
|
+
- Packaged guidance for coding agents, executable consumer examples, compatibility metadata, and a safe readiness doctor.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @vraxis/agent-v
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The optional AI SDK adapter requires a compatible peer:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install ai
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Ollama support uses the tool-capable AI SDK community provider and is installed only by products that need it:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install ai ai-sdk-ollama
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Node and local CLI adapters require Node.js 22.12 or newer. The core has no provider SDK dependency.
|
|
38
|
+
|
|
39
|
+
## Define a tool, skill, and agent
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import {
|
|
43
|
+
AgentV,
|
|
44
|
+
EngineRegistry,
|
|
45
|
+
ExtensionRegistry,
|
|
46
|
+
defineAgent,
|
|
47
|
+
defineExtension,
|
|
48
|
+
defineOutput,
|
|
49
|
+
defineSkill,
|
|
50
|
+
defineTool,
|
|
51
|
+
localExecutionScope,
|
|
52
|
+
} from "@vraxis/agent-v";
|
|
53
|
+
|
|
54
|
+
const lookupSelection = defineTool({
|
|
55
|
+
name: "lookup-selection",
|
|
56
|
+
version: "1.0.0",
|
|
57
|
+
description: "Find supporting material for a selected passage.",
|
|
58
|
+
input: defineOutput({
|
|
59
|
+
name: "selection-query",
|
|
60
|
+
jsonSchema: {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: { query: { type: "string" } },
|
|
63
|
+
required: ["query"],
|
|
64
|
+
additionalProperties: false,
|
|
65
|
+
},
|
|
66
|
+
parse(value) {
|
|
67
|
+
const query = (value as { query?: unknown }).query;
|
|
68
|
+
if (typeof query !== "string") throw new Error("query is required");
|
|
69
|
+
return { query };
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
output: defineOutput({
|
|
73
|
+
name: "selection-results",
|
|
74
|
+
jsonSchema: { type: "object" },
|
|
75
|
+
parse(value) {
|
|
76
|
+
const matches = (value as { matches?: unknown }).matches;
|
|
77
|
+
if (!Array.isArray(matches) || !matches.every(item => typeof item === "string")) throw new Error("matches are required");
|
|
78
|
+
return { matches };
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
risk: "read",
|
|
82
|
+
sideEffect: "none",
|
|
83
|
+
requiredPermissions: ["sources:read"],
|
|
84
|
+
requiresApproval: false,
|
|
85
|
+
timeoutMs: 5_000,
|
|
86
|
+
async execute({ query }) {
|
|
87
|
+
return { matches: [`Host search result for: ${query}`] };
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const closeReading = defineSkill({
|
|
92
|
+
id: "close-reading",
|
|
93
|
+
name: "Close reading",
|
|
94
|
+
version: "1.0.0",
|
|
95
|
+
description: "Ground explanations in supplied source material.",
|
|
96
|
+
instructions: "Distinguish source claims from interpretation and cite anchors.",
|
|
97
|
+
tools: [lookupSelection.name],
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const reader = defineAgent({
|
|
101
|
+
id: "engineering-reader",
|
|
102
|
+
name: "Engineering reader",
|
|
103
|
+
engineId: "primary-agent",
|
|
104
|
+
instructions: "Help the reader understand and question the material.",
|
|
105
|
+
skills: [closeReading.id],
|
|
106
|
+
tools: [lookupSelection.name],
|
|
107
|
+
requiredCapabilities: ["tools", "streaming", "artifacts"],
|
|
108
|
+
maxSteps: 12,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const engines = new EngineRegistry(); // register an adapter with id "primary-agent"
|
|
112
|
+
const extensions = new ExtensionRegistry().use(defineExtension({
|
|
113
|
+
id: "reader-kit",
|
|
114
|
+
version: "1.0.0",
|
|
115
|
+
skills: [closeReading],
|
|
116
|
+
tools: [lookupSelection],
|
|
117
|
+
}));
|
|
118
|
+
const agentV = new AgentV({ engines, extensions });
|
|
119
|
+
|
|
120
|
+
const scope = {
|
|
121
|
+
...localExecutionScope("engineering-reader"),
|
|
122
|
+
permissions: ["sources:read"],
|
|
123
|
+
};
|
|
124
|
+
// await agentV.run(reader, { scope, sessionId: "chapter-4", input: { prompt, artifacts } });
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Every tool requested by an agent using skills must be allowed by those skills. Missing grants fail before provider execution; they are never silently filtered.
|
|
128
|
+
|
|
129
|
+
## Model and credential resolution
|
|
130
|
+
|
|
131
|
+
`AiSdkToolAgentEngine` accepts a static model, a named model registry, or a `resolveModel(selection)` function. The resolver receives the requested model id, execution scope, run id, metadata, and an opaque `credentialRef`. The host resolves that reference and constructs the provider model; `agent-v` never stores credential values.
|
|
132
|
+
|
|
133
|
+
Engine profiles can select an engine/model/credential reference without changing an agent blueprint. A blueprint chooses either `engineId` or `profileId`, never both.
|
|
134
|
+
|
|
135
|
+
Model resolvers can return authoritative provider/runtime provenance with the model. Every run records an `adapterStrategy`; local runtimes and Ollama also record the detected runtime version. This makes upstream protocol changes diagnosable from persisted run events.
|
|
136
|
+
|
|
137
|
+
## Ollama
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { OllamaRuntime } from "@vraxis/agent-v/ollama";
|
|
141
|
+
|
|
142
|
+
const ollama = new OllamaRuntime({
|
|
143
|
+
defaultModel: "your-installed-model",
|
|
144
|
+
// baseURL defaults to http://127.0.0.1:11434
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const readiness = await ollama.inspect();
|
|
148
|
+
if (readiness.availability === "ready") {
|
|
149
|
+
engines.register(ollama.agent);
|
|
150
|
+
engines.register(ollama.structured);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Resolution checks the live daemon version and installed model list before creating the AI SDK model. Missing daemons, rejected credentials, unexpected readiness responses, and absent models fail closed. Remote Ollama servers can provide `baseURL`, headers, and an API key when the host has resolved its credential reference.
|
|
155
|
+
|
|
156
|
+
## Skills
|
|
157
|
+
|
|
158
|
+
`@vraxis/agent-v/node` exports `loadSkillPackage()` and `discoverSkillPackages()`. A package is a directory containing a standard `SKILL.md` plus optional `scripts/`, `references/`, and `assets/` directories. Discovery validates and indexes these resources but never executes scripts.
|
|
159
|
+
|
|
160
|
+
The standard `allowed-tools` field is preserved as `preapprovedTools`, but it does not bypass host policy. It also seeds the skill's tool allowlist. Tools marked `requiresApproval` still require an `ApprovalPolicy` at execution time.
|
|
161
|
+
|
|
162
|
+
## Adapters
|
|
163
|
+
|
|
164
|
+
- `@vraxis/agent-v/ai-sdk`: AI SDK structured and tool-agent engines.
|
|
165
|
+
- `@vraxis/agent-v/local-cli`: bounded local coding runtimes and readiness probes.
|
|
166
|
+
- `@vraxis/agent-v/ollama`: optional local/remote Ollama structured and tool-agent engines.
|
|
167
|
+
- `@vraxis/agent-v/node`: JSON config/session stores, JSONL event ledger, and filesystem skills.
|
|
168
|
+
- `@vraxis/agent-v/testing`: deterministic engines and approval policies.
|
|
169
|
+
|
|
170
|
+
Local CLI discovery and readiness are separate. An executable is `installed`; only a bounded, authenticated, schema-valid probe is `ready`. OpenCode advertises workspace-write only, so a default read-only request fails closed instead of weakening the requested policy.
|
|
171
|
+
|
|
172
|
+
## Agent-readable integration guidance
|
|
173
|
+
|
|
174
|
+
The package ships four synchronized sources for coding agents:
|
|
175
|
+
|
|
176
|
+
- `AGENTS.md` explains repository boundaries and contribution invariants.
|
|
177
|
+
- `skills/agent-v/SKILL.md` is a portable integration skill with precise subpath routing.
|
|
178
|
+
- `examples/` contains consumer programs compiled and executed against the built package exports.
|
|
179
|
+
- `compatibility.json` records dependency ranges, adapter strategies, runtime capabilities, and version policies.
|
|
180
|
+
- `llms.txt` gives documentation crawlers a short map to the canonical sources.
|
|
181
|
+
|
|
182
|
+
Agents should start with the closest executable example and verify against installed type declarations. They should not infer `agent-v` methods from LangChain, the AI SDK, or older examples.
|
|
183
|
+
|
|
184
|
+
Locate the packaged portable skill from an installed dependency with:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
npx @vraxis/agent-v skill-path
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The consuming harness can copy or link that directory into its configured Agent Skills location; discovery locations are owned by the harness, not guessed by `agent-v`.
|
|
191
|
+
|
|
192
|
+
## Doctor
|
|
193
|
+
|
|
194
|
+
Run safe discovery without provider inference:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npx @vraxis/agent-v doctor
|
|
198
|
+
npx @vraxis/agent-v doctor --json
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Run an authenticated CLI probe only by naming the runtime explicitly:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx @vraxis/agent-v doctor --runtime codex --probe
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Require an Ollama server and model:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npx @vraxis/agent-v doctor --ollama-url http://127.0.0.1:11434 --ollama-model <installed-model>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The default command does not start services, download models, or make model inference calls. Live CLI probing may use configured credentials, so `--probe` requires an explicit `--runtime`.
|
|
214
|
+
|
|
215
|
+
## Design commitments
|
|
216
|
+
|
|
217
|
+
- The host owns identity, approval decisions, credentials, and real side effects.
|
|
218
|
+
- Every run carries explicit tenant, project, principal, role, permission, and data-classification scope.
|
|
219
|
+
- Tools validate both model-supplied input and application-supplied output.
|
|
220
|
+
- Workspace access defaults to read-only and must be enforceable by the selected runtime.
|
|
221
|
+
- Normalized events and sessions are scope-isolated; raw provider objects do not leak into core contracts.
|
|
222
|
+
- Product evidence, prompts, retrieval, ranking, billing, and UX stay outside the engine.
|
|
223
|
+
|
|
224
|
+
See [ARCHITECTURE.md](./ARCHITECTURE.md) for boundaries and extension rules.
|
|
225
|
+
|
|
226
|
+
## Development
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
npm ci
|
|
230
|
+
npm run check
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`check` runs strict typechecking, all tests, the production build, consumer example compilation and execution, built-package and CLI smoke tests, and an npm package dry run.
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"packageVersion": "0.4.0",
|
|
4
|
+
"node": ">=22.12",
|
|
5
|
+
"adapters": {
|
|
6
|
+
"ai-sdk": {
|
|
7
|
+
"packageRange": ">=7.0.0 <8",
|
|
8
|
+
"strategies": [
|
|
9
|
+
"ai-sdk-v7-structured-model",
|
|
10
|
+
"ai-sdk-v7-tool-agent"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"ollama": {
|
|
14
|
+
"aiSdkOllamaRange": ">=4.2.0 <5",
|
|
15
|
+
"aiSdkRange": ">=7.0.0 <8",
|
|
16
|
+
"strategy": "ai-sdk-ollama-v4-native-chat",
|
|
17
|
+
"versionPolicy": "inspect-daemon-and-models-before-each-resolution"
|
|
18
|
+
},
|
|
19
|
+
"local-cli": {
|
|
20
|
+
"versionPolicy": "detect-before-each-run-and-invalidate-readiness-on-change",
|
|
21
|
+
"runtimes": {
|
|
22
|
+
"codex": {
|
|
23
|
+
"strategy": "codex-exec-json-v1",
|
|
24
|
+
"capabilities": ["structured-output", "local-workspace", "read-only-workspace", "workspace-write", "artifacts"]
|
|
25
|
+
},
|
|
26
|
+
"opencode": {
|
|
27
|
+
"strategy": "opencode-run-json-v1",
|
|
28
|
+
"capabilities": ["structured-output", "local-workspace", "workspace-write", "artifacts"]
|
|
29
|
+
},
|
|
30
|
+
"claude-code": {
|
|
31
|
+
"strategy": "claude-print-json-v1",
|
|
32
|
+
"capabilities": ["structured-output", "local-workspace", "read-only-workspace", "artifacts"]
|
|
33
|
+
},
|
|
34
|
+
"cursor": {
|
|
35
|
+
"strategy": "cursor-print-json-v1",
|
|
36
|
+
"capabilities": ["local-workspace", "workspace-write", "artifacts"]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type LanguageModel } from "ai";
|
|
2
|
+
import { type AgentRunStream, type EngineDescriptor, type EventSink, type RunProvenance, type StructuredGenerationRequest, type StructuredGenerationResult, type ToolAgentEngine, type ToolAgentRequest, type ToolAgentResult } from "../../core/index.js";
|
|
3
|
+
/** Provider/model sources and provenance defaults for an AI SDK engine. */
|
|
4
|
+
export interface AiSdkEngineOptions {
|
|
5
|
+
id: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
model?: LanguageModel;
|
|
8
|
+
models?: Readonly<Record<string, LanguageModel>>;
|
|
9
|
+
resolveModel?: AiSdkModelResolver;
|
|
10
|
+
provider?: string;
|
|
11
|
+
modelId?: string;
|
|
12
|
+
adapterStrategy?: string;
|
|
13
|
+
runtime?: string;
|
|
14
|
+
runtimeVersion?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Host context supplied whenever an AI SDK model is resolved for a run. */
|
|
17
|
+
export interface AiSdkModelSelection {
|
|
18
|
+
modelId?: string;
|
|
19
|
+
runId: string;
|
|
20
|
+
metadata?: import("../../core/index.js").JsonObject;
|
|
21
|
+
scope: import("../../core/index.js").ExecutionScope;
|
|
22
|
+
credentialRef?: string;
|
|
23
|
+
options?: import("../../core/index.js").JsonObject;
|
|
24
|
+
}
|
|
25
|
+
/** Model plus authoritative provenance discovered during resolution. */
|
|
26
|
+
export interface AiSdkResolvedModel {
|
|
27
|
+
model: LanguageModel;
|
|
28
|
+
provenance?: Partial<Omit<RunProvenance, "engineId">>;
|
|
29
|
+
}
|
|
30
|
+
/** Per-run model resolver used for provider, tenant, or credential selection. */
|
|
31
|
+
export type AiSdkModelResolver = (selection: AiSdkModelSelection) => LanguageModel | AiSdkResolvedModel | Promise<LanguageModel | AiSdkResolvedModel>;
|
|
32
|
+
export declare class AiSdkStructuredModelEngine {
|
|
33
|
+
readonly descriptor: EngineDescriptor;
|
|
34
|
+
private readonly options;
|
|
35
|
+
constructor(options: AiSdkEngineOptions);
|
|
36
|
+
generate<T>(request: StructuredGenerationRequest<T>, sink?: EventSink): Promise<StructuredGenerationResult<T>>;
|
|
37
|
+
}
|
|
38
|
+
export declare class AiSdkToolAgentEngine implements ToolAgentEngine {
|
|
39
|
+
readonly descriptor: EngineDescriptor;
|
|
40
|
+
private readonly options;
|
|
41
|
+
constructor(options: AiSdkEngineOptions);
|
|
42
|
+
private generate;
|
|
43
|
+
run<T = string>(request: ToolAgentRequest<T>, sink?: EventSink): Promise<ToolAgentResult<T>>;
|
|
44
|
+
stream<T = string>(request: ToolAgentRequest<T>, sink?: EventSink): Promise<AgentRunStream<T>>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/ai-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,IAAI,CAAC;AACZ,OAAO,EAQL,KAAK,cAAc,EAEnB,KAAK,gBAAgB,EAErB,KAAK,SAAS,EAGd,KAAK,aAAa,EAClB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAErB,MAAM,qBAAqB,CAAC;AAE7B,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IACjD,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,4EAA4E;AAC5E,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,qBAAqB,EAAE,UAAU,CAAC;IACpD,KAAK,EAAE,OAAO,qBAAqB,EAAE,cAAc,CAAC;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,UAAU,CAAC;CACpD;AAED,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC;CACvD;AAED,iFAAiF;AACjF,MAAM,MAAM,kBAAkB,GAAG,CAAC,SAAS,EAAE,mBAAmB,KAAK,aAAa,GAAG,kBAAkB,GAAG,OAAO,CAAC,aAAa,GAAG,kBAAkB,CAAC,CAAC;AAuGtJ,qBAAa,0BAA0B;IACrC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,OAAO,EAAE,kBAAkB;IAMjC,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,SAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;CAyCpI;AAmFD,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,OAAO,EAAE,kBAAkB;YAMzB,QAAQ;IAuBhB,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,SAAyB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IA4B3G,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,GAAE,SAAyB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;CAwDpH"}
|