@axiastudio/aioc 0.1.0-beta.3 → 0.1.0-beta.5
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 +132 -87
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -6,97 +6,109 @@ AIOC is designed for enterprise and public-sector contexts with privacy-by-desig
|
|
|
6
6
|
|
|
7
7
|
Project home: [https://github.com/axiastudio/aioc](https://github.com/axiastudio/aioc)
|
|
8
8
|
|
|
9
|
-
## Release
|
|
9
|
+
## Release Status
|
|
10
10
|
|
|
11
11
|
This package is currently in beta and is not production-ready.
|
|
12
12
|
Breaking changes may occur before a stable release.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
|
|
14
|
+
- Beta contract: `docs/BETA-CONTRACT.md`
|
|
15
|
+
- Alpha contract (historical): `docs/ALPHA-CONTRACT.md`
|
|
16
|
+
- Privacy baseline: `docs/PRIVACY-BASELINE.md`
|
|
16
17
|
|
|
17
18
|
## Contact
|
|
18
19
|
|
|
19
20
|
If you want to collaborate or provide feedback, write to `tiziano.lattisi@axia.studio`.
|
|
20
21
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
AIOC adopts the following non-negotiable principles:
|
|
22
|
+
## Install
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- **Non-degeneration validation**: each correction must pass regression tests and quality checks.
|
|
29
|
-
- **Bias and misalignment control**: continuous monitoring, dedicated tests, and clear mitigation/escalation mechanisms.
|
|
30
|
-
- **Privacy by design and data minimization**: collect and process only what is strictly necessary, protect sensitive data by default (redaction, encryption, retention limits), and provide auditable controls for access and deletion.
|
|
24
|
+
```bash
|
|
25
|
+
npm install @axiastudio/aioc
|
|
26
|
+
```
|
|
31
27
|
|
|
32
|
-
|
|
28
|
+
## Quickstart
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- `docs/ALPHA-CONTRACT.md`
|
|
38
|
-
- `docs/BETA-CONTRACT.md`
|
|
39
|
-
- `docs/PRIVACY-BASELINE.md`
|
|
40
|
-
|
|
41
|
-
Canonical examples reference:
|
|
30
|
+
```ts
|
|
31
|
+
import "dotenv/config";
|
|
32
|
+
import { Agent, run, setupMistral } from "@axiastudio/aioc";
|
|
42
33
|
|
|
43
|
-
|
|
34
|
+
setupMistral(); // reads MISTRAL_API_KEY from env
|
|
44
35
|
|
|
45
|
-
|
|
36
|
+
const agent = new Agent({
|
|
37
|
+
name: "Hello Agent",
|
|
38
|
+
model: "mistral-small-latest",
|
|
39
|
+
instructions: "Answer in 2 short sentences.",
|
|
40
|
+
});
|
|
46
41
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
const result = await run(
|
|
43
|
+
agent,
|
|
44
|
+
"In one sentence, what is a deterministic policy gate in an agent SDK?",
|
|
45
|
+
);
|
|
46
|
+
console.log(result.finalOutput);
|
|
47
|
+
```
|
|
50
48
|
|
|
51
|
-
##
|
|
49
|
+
## Core API
|
|
52
50
|
|
|
53
51
|
- `Agent`, `RunContext`
|
|
54
52
|
- optional `Agent.promptVersion` to version resolved instructions
|
|
55
53
|
- `Tool`, `tool(...)`
|
|
56
|
-
-
|
|
57
|
-
- `run(...)` with streaming support
|
|
58
|
-
-
|
|
59
|
-
- deterministic policy gates via `run(..., { policies })` (tool execution and handoff transitions are default-deny without explicit allow policy)
|
|
60
|
-
- policy helpers `allow(...)` and `deny(...)` for deterministic policy results (including optional `publicReason` and `denyMode`)
|
|
61
|
-
- tool/handoff call outputs are normalized in an envelope: `{ status, code, publicReason, data }`
|
|
54
|
+
- handoffs via `Agent({ handoffs: [...] })`
|
|
55
|
+
- `run(...)` with streaming support (`stream` defaults to `false`)
|
|
56
|
+
- policy helpers `allow(...)` / `deny(...)`
|
|
62
57
|
- provider setup helpers `setupMistral(...)`, `setupOpenAI(...)`, `setupProvider(...)`
|
|
63
|
-
-
|
|
64
|
-
- run record hook
|
|
65
|
-
- run
|
|
66
|
-
-
|
|
67
|
-
- run record utilities:
|
|
68
|
-
- `extractToolCalls(...)`
|
|
69
|
-
- `compareRunRecords(...)`
|
|
70
|
-
- `replayFromRunRecord(...)` with modes `live | strict | hybrid`
|
|
71
|
-
- JSON helper `toJsonValue(...)` to map runtime artifacts (for example `RunRecord.items`) into JSON-safe values for storage adapters
|
|
72
|
-
- message helpers `user(...)`, `assistant(...)`, `system(...)`
|
|
73
|
-
- `setDefaultProvider(...)`
|
|
74
|
-
- error classes including `OutputGuardrailTripwireTriggered`
|
|
75
|
-
- `OpenAIProvider`, `MistralProvider`
|
|
58
|
+
- run logger hook `run(..., { logger })`
|
|
59
|
+
- run record hook `run(..., { record })`
|
|
60
|
+
- run-record utilities `extractToolCalls(...)`, `compareRunRecords(...)`, `replayFromRunRecord(...)`
|
|
61
|
+
- JSON helper `toJsonValue(...)`
|
|
76
62
|
|
|
77
|
-
|
|
63
|
+
## Policy Gate (Minimal)
|
|
78
64
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
65
|
+
```ts
|
|
66
|
+
import { Agent, allow, deny, run, tool, type ToolPolicy } from "@axiastudio/aioc";
|
|
67
|
+
|
|
68
|
+
const toolPolicy: ToolPolicy<{ actor: { groups: string[] } }> = ({ runContext }) => {
|
|
69
|
+
if (!runContext.context.actor.groups.includes("finance")) {
|
|
70
|
+
return deny("deny_missing_finance_group", {
|
|
71
|
+
denyMode: "tool_result",
|
|
72
|
+
publicReason: "You are not authorized to access this report.",
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return allow("allow_finance_group_access");
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
await run(agent, "Summarize report Q1.", {
|
|
79
|
+
context: { actor: { groups: ["finance"] } },
|
|
80
|
+
policies: { toolPolicy },
|
|
81
|
+
});
|
|
82
|
+
```
|
|
85
83
|
|
|
86
|
-
|
|
87
|
-
- Policies can choose `denyMode: "tool_result"` to return a denied tool result to the model without throwing.
|
|
84
|
+
Default behavior is deny when no policy is configured.
|
|
88
85
|
|
|
89
|
-
Run
|
|
86
|
+
## Run Record (Minimal)
|
|
90
87
|
|
|
91
|
-
|
|
88
|
+
```ts
|
|
89
|
+
const records = [] as RunRecord<MyContext>[];
|
|
90
|
+
|
|
91
|
+
await run(agent, "question", {
|
|
92
|
+
context,
|
|
93
|
+
policies: { toolPolicy },
|
|
94
|
+
record: {
|
|
95
|
+
includePromptText: true,
|
|
96
|
+
contextRedactor: (ctx) => ({
|
|
97
|
+
contextSnapshot: { ...ctx, userId: "[redacted]" },
|
|
98
|
+
contextRedacted: true,
|
|
99
|
+
}),
|
|
100
|
+
sink: (record) => records.push(record),
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
```
|
|
92
104
|
|
|
93
|
-
Privacy
|
|
105
|
+
Privacy notes:
|
|
94
106
|
|
|
95
|
-
- `record.includePromptText` defaults to `false
|
|
96
|
-
- `record.contextRedactor` should be considered mandatory for production
|
|
97
|
-
- sink adapters should implement encryption, access controls, retention, and deletion
|
|
107
|
+
- `record.includePromptText` defaults to `false`; keep it disabled unless needed.
|
|
108
|
+
- `record.contextRedactor` should be considered mandatory for production persistence.
|
|
109
|
+
- sink adapters should implement encryption, access controls, retention, and deletion.
|
|
98
110
|
|
|
99
|
-
## RunRecord Utilities
|
|
111
|
+
## RunRecord Utilities (Minimal)
|
|
100
112
|
|
|
101
113
|
### `extractToolCalls(...)`
|
|
102
114
|
|
|
@@ -104,7 +116,7 @@ Privacy baseline highlights:
|
|
|
104
116
|
import { extractToolCalls } from "@axiastudio/aioc";
|
|
105
117
|
|
|
106
118
|
const calls = extractToolCalls(runRecord);
|
|
107
|
-
|
|
119
|
+
console.log(calls[0]?.name, calls[0]?.argsHash, calls[0]?.hasOutput);
|
|
108
120
|
```
|
|
109
121
|
|
|
110
122
|
### `compareRunRecords(...)`
|
|
@@ -113,18 +125,16 @@ const calls = extractToolCalls(runRecord);
|
|
|
113
125
|
import { compareRunRecords } from "@axiastudio/aioc";
|
|
114
126
|
|
|
115
127
|
const comparison = compareRunRecords(runRecordA, runRecordB, {
|
|
116
|
-
responseMatchMode: "exact",
|
|
117
128
|
includeSections: ["response", "toolCalls", "policy", "guardrails", "metadata"],
|
|
129
|
+
responseMatchMode: "exact",
|
|
118
130
|
});
|
|
119
131
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
console.log(comparison.differences);
|
|
124
|
-
}
|
|
132
|
+
console.log(comparison.summary);
|
|
133
|
+
console.log(comparison.metrics);
|
|
134
|
+
console.log(comparison.differences);
|
|
125
135
|
```
|
|
126
136
|
|
|
127
|
-
### `replayFromRunRecord(...)`
|
|
137
|
+
### `replayFromRunRecord(...)`
|
|
128
138
|
|
|
129
139
|
```ts
|
|
130
140
|
import { allow, replayFromRunRecord } from "@axiastudio/aioc";
|
|
@@ -132,7 +142,7 @@ import { allow, replayFromRunRecord } from "@axiastudio/aioc";
|
|
|
132
142
|
const replay = await replayFromRunRecord({
|
|
133
143
|
sourceRunRecord,
|
|
134
144
|
agent,
|
|
135
|
-
mode: "strict",
|
|
145
|
+
mode: "strict", // live | strict | hybrid
|
|
136
146
|
runOptions: {
|
|
137
147
|
policies: {
|
|
138
148
|
toolPolicy: () => allow("allow_replay"),
|
|
@@ -144,14 +154,40 @@ console.log(replay.result.finalOutput);
|
|
|
144
154
|
console.log(replay.replayStats);
|
|
145
155
|
```
|
|
146
156
|
|
|
147
|
-
`replayFromRunRecord(...)` does not bypass policy enforcement: in `strict` and `hybrid
|
|
157
|
+
`replayFromRunRecord(...)` does not bypass policy enforcement: in `strict` and `hybrid`, provide `runOptions.policies` when tool/handoff execution must be authorized.
|
|
158
|
+
|
|
159
|
+
## Reference UI Example
|
|
160
|
+
|
|
161
|
+
This repository also contains `aioc-inspect`, a private reference example UI for visual `RunRecord` analysis:
|
|
162
|
+
|
|
163
|
+
- path: `apps/aioc-inspect`
|
|
164
|
+
- public sample files: `apps/aioc-inspect/public/samples`
|
|
165
|
+
- regenerate samples: `npm run inspect:samples`
|
|
166
|
+
- purpose: show one possible way to inspect, navigate, and compare `RunRecord` artifacts visually
|
|
167
|
+
- scope: experimental, stateless, session-only
|
|
168
|
+
- positioning: example application for implementors, not a hosted service or production console
|
|
148
169
|
|
|
149
|
-
|
|
170
|
+
`aioc-inspect` exists to demonstrate the value of the `RunRecord` contract. It should be read as one possible interpretation of the data model, not as the only intended UI for `aioc`.
|
|
150
171
|
|
|
151
|
-
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
172
|
+

|
|
173
|
+
|
|
174
|
+
## Examples
|
|
175
|
+
|
|
176
|
+
| Command | Purpose | Needs API key |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| `npm run example:hello` | Minimal single-agent run | Yes (`MISTRAL_API_KEY`) |
|
|
179
|
+
| `npm run example:tool-policy` | Tool calls with deterministic policy gate | Yes (`MISTRAL_API_KEY`) |
|
|
180
|
+
| `npm run example:run-record` | Run-record persistence with redaction + audit | Yes (`MISTRAL_API_KEY`) |
|
|
181
|
+
| `npm run example:rru:01-extract` | Minimal `extractToolCalls(...)` | No |
|
|
182
|
+
| `npm run example:rru:02-compare` | Minimal `compareRunRecords(...)` | No |
|
|
183
|
+
| `npm run example:rru:03-replay-strict` | Minimal strict replay | No |
|
|
184
|
+
| `npm run example:rru:04-replay-hybrid` | Minimal hybrid replay | No |
|
|
185
|
+
| `npm run example:non-regression` | Advanced v1/v2 run-record diff | Yes (`MISTRAL_API_KEY`) |
|
|
186
|
+
|
|
187
|
+
Notes:
|
|
188
|
+
|
|
189
|
+
- `example:non-regression` is educational and can be non-deterministic because it uses a live provider.
|
|
190
|
+
- canonical examples guide: `docs/CANONICAL-EXAMPLES.md`.
|
|
155
191
|
|
|
156
192
|
## Test Commands
|
|
157
193
|
|
|
@@ -160,16 +196,25 @@ console.log(replay.replayStats);
|
|
|
160
196
|
- `npm run test:regression`
|
|
161
197
|
- `npm run test:ci`
|
|
162
198
|
|
|
163
|
-
##
|
|
199
|
+
## Project Principles
|
|
164
200
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
201
|
+
AIOC adopts the following non-negotiable principles:
|
|
202
|
+
|
|
203
|
+
- **LLM outside the control plane**: critical decisions remain in deterministic components; the LLM supports but does not govern.
|
|
204
|
+
- **End-to-end transparency**: each decision is traceable (inputs, context, prompt/policy version, output).
|
|
205
|
+
- **Verifiable corrigibility**: prompts, policies, and materials are versioned, editable, and comparable before/after changes.
|
|
206
|
+
- **Non-degeneration validation**: each correction must pass regression tests and quality checks.
|
|
207
|
+
- **Bias and misalignment control**: continuous monitoring, dedicated tests, and clear mitigation/escalation mechanisms.
|
|
208
|
+
- **Privacy by design and data minimization**: collect and process only what is strictly necessary, protect sensitive data by default (redaction, encryption, retention limits), and provide auditable controls for access and deletion.
|
|
209
|
+
|
|
210
|
+
## Governance References
|
|
211
|
+
|
|
212
|
+
- `docs/RFC-0001-governance-first-runtime.md`
|
|
213
|
+
- `docs/RFC-0002-policy-gates-for-tools-and-handoffs.md`
|
|
214
|
+
- `docs/RFC-0003-run-record-audit-trail-and-persistence.md`
|
|
215
|
+
- `docs/ALPHA-CONTRACT.md`
|
|
216
|
+
- `docs/BETA-CONTRACT.md`
|
|
217
|
+
- `docs/PRIVACY-BASELINE.md`
|
|
173
218
|
|
|
174
219
|
## License
|
|
175
220
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiastudio/aioc",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.5",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"example:rru:03-replay-strict": "tsx src/examples/run-record-utils-minimal/03-replay-strict.ts",
|
|
26
26
|
"example:rru:04-replay-hybrid": "tsx src/examples/run-record-utils-minimal/04-replay-hybrid.ts",
|
|
27
27
|
"example:non-regression": "tsx src/examples/non-regression/v1-v2-runrecord-diff.ts",
|
|
28
|
+
"inspect:samples": "tsx scripts/generate-aioc-inspect-samples.ts",
|
|
28
29
|
"test:mistral": "tsx src/examples/mistral-smoke.ts",
|
|
29
30
|
"prepack": "npm run build:package"
|
|
30
31
|
},
|