@oni.bot/core 0.6.2 → 0.8.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/CHANGELOG.md +111 -0
- package/README.md +315 -200
- package/SECURITY.md +71 -0
- package/dist/checkpointers/sqlite.d.ts.map +1 -1
- package/dist/checkpointers/sqlite.js +20 -18
- package/dist/checkpointers/sqlite.js.map +1 -1
- package/dist/circuit-breaker.d.ts +20 -0
- package/dist/circuit-breaker.d.ts.map +1 -0
- package/dist/circuit-breaker.js +58 -0
- package/dist/circuit-breaker.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 +32 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +17 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/templates.d.ts +8 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +119 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/dlq.d.ts +17 -0
- package/dist/dlq.d.ts.map +1 -0
- package/dist/dlq.js +41 -0
- package/dist/dlq.js.map +1 -0
- package/dist/errors.d.ts +36 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +163 -7
- package/dist/errors.js.map +1 -1
- package/dist/graph.d.ts +17 -0
- package/dist/graph.d.ts.map +1 -1
- package/dist/graph.js +13 -2
- package/dist/graph.js.map +1 -1
- package/dist/harness/agent-loop.d.ts +8 -0
- package/dist/harness/agent-loop.d.ts.map +1 -0
- package/dist/harness/agent-loop.js +327 -0
- package/dist/harness/agent-loop.js.map +1 -0
- package/dist/harness/context-compactor.d.ts +73 -0
- package/dist/harness/context-compactor.d.ts.map +1 -0
- package/dist/harness/context-compactor.js +162 -0
- package/dist/harness/context-compactor.js.map +1 -0
- package/dist/harness/harness.d.ts +41 -0
- package/dist/harness/harness.d.ts.map +1 -0
- package/dist/harness/harness.js +140 -0
- package/dist/harness/harness.js.map +1 -0
- package/dist/harness/hooks-engine.d.ts +71 -0
- package/dist/harness/hooks-engine.d.ts.map +1 -0
- package/dist/harness/hooks-engine.js +232 -0
- package/dist/harness/hooks-engine.js.map +1 -0
- package/dist/harness/index.d.ts +16 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +19 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/safety-gate.d.ts +29 -0
- package/dist/harness/safety-gate.d.ts.map +1 -0
- package/dist/harness/safety-gate.js +72 -0
- package/dist/harness/safety-gate.js.map +1 -0
- package/dist/harness/skill-loader.d.ts +63 -0
- package/dist/harness/skill-loader.d.ts.map +1 -0
- package/dist/harness/skill-loader.js +214 -0
- package/dist/harness/skill-loader.js.map +1 -0
- package/dist/harness/todo-module.d.ts +39 -0
- package/dist/harness/todo-module.d.ts.map +1 -0
- package/dist/harness/todo-module.js +179 -0
- package/dist/harness/todo-module.js.map +1 -0
- package/dist/harness/types.d.ts +78 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +9 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/hitl/interrupt.d.ts.map +1 -1
- package/dist/hitl/interrupt.js +7 -6
- package/dist/hitl/interrupt.js.map +1 -1
- package/dist/index.d.ts +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/models/google.d.ts.map +1 -1
- package/dist/models/google.js +7 -6
- package/dist/models/google.js.map +1 -1
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +1 -0
- package/dist/models/index.js.map +1 -1
- package/dist/models/openai.js +6 -1
- package/dist/models/openai.js.map +1 -1
- package/dist/models/openrouter.d.ts +13 -0
- package/dist/models/openrouter.d.ts.map +1 -0
- package/dist/models/openrouter.js +322 -0
- package/dist/models/openrouter.js.map +1 -0
- package/dist/prebuilt/tool-node.d.ts.map +1 -1
- package/dist/prebuilt/tool-node.js +0 -1
- package/dist/prebuilt/tool-node.js.map +1 -1
- package/dist/pregel.d.ts +11 -1
- package/dist/pregel.d.ts.map +1 -1
- package/dist/pregel.js +88 -7
- package/dist/pregel.js.map +1 -1
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js +6 -1
- package/dist/retry.js.map +1 -1
- package/dist/store/index.d.ts +10 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +15 -1
- package/dist/store/index.js.map +1 -1
- package/dist/stream-events.js +2 -2
- package/dist/stream-events.js.map +1 -1
- package/dist/streaming.d.ts +10 -0
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +28 -0
- package/dist/streaming.js.map +1 -1
- package/dist/swarm/graph.d.ts.map +1 -1
- package/dist/swarm/graph.js +0 -4
- package/dist/swarm/graph.js.map +1 -1
- package/dist/swarm/supervisor.d.ts.map +1 -1
- package/dist/swarm/supervisor.js +0 -4
- package/dist/swarm/supervisor.js.map +1 -1
- package/dist/telemetry.d.ts +41 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +69 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/testing/index.d.ts +33 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +95 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +38 -5
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core/harness — ONIHarness Integration Class
|
|
3
|
+
// Wires all harness modules together and bridges to ONI-Core
|
|
4
|
+
// ============================================================
|
|
5
|
+
import { agentLoop, wrapWithAgentLoop } from "./agent-loop.js";
|
|
6
|
+
import { TodoModule } from "./todo-module.js";
|
|
7
|
+
import { HooksEngine } from "./hooks-engine.js";
|
|
8
|
+
import { ContextCompactor } from "./context-compactor.js";
|
|
9
|
+
import { SafetyGate } from "./safety-gate.js";
|
|
10
|
+
import { SkillLoader } from "./skill-loader.js";
|
|
11
|
+
// ─── ONIHarness ───────────────────────────────────────────────────────────
|
|
12
|
+
export class ONIHarness {
|
|
13
|
+
config;
|
|
14
|
+
todoModule;
|
|
15
|
+
hooksEngine;
|
|
16
|
+
compactor;
|
|
17
|
+
safetyGate;
|
|
18
|
+
skillLoader;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
// Create TodoModule
|
|
22
|
+
this.todoModule = new TodoModule();
|
|
23
|
+
// Create HooksEngine — compose user hooks with security guardrails
|
|
24
|
+
const userEngine = new HooksEngine();
|
|
25
|
+
if (config.hooks) {
|
|
26
|
+
userEngine.configure(config.hooks);
|
|
27
|
+
}
|
|
28
|
+
this.hooksEngine = HooksEngine.compose(HooksEngine.withSecurityGuardrails(), userEngine);
|
|
29
|
+
// Create ContextCompactor with fastModel (or model if no fastModel)
|
|
30
|
+
const summaryModel = config.fastModel ?? config.model;
|
|
31
|
+
this.compactor = new ContextCompactor({
|
|
32
|
+
summaryModel,
|
|
33
|
+
threshold: config.compaction?.threshold,
|
|
34
|
+
maxTokens: config.compaction?.maxTokens,
|
|
35
|
+
charsPerToken: config.compaction?.charsPerToken,
|
|
36
|
+
compactInstructions: config.compaction?.compactInstructions,
|
|
37
|
+
});
|
|
38
|
+
// Create SafetyGate with fastModel (or model)
|
|
39
|
+
const safetyModel = config.fastModel ?? config.model;
|
|
40
|
+
this.safetyGate = new SafetyGate({
|
|
41
|
+
safetyModel,
|
|
42
|
+
protectedTools: config.safety?.protectedTools,
|
|
43
|
+
safetySystemPrompt: config.safety?.safetySystemPrompt,
|
|
44
|
+
timeout: config.safety?.timeout,
|
|
45
|
+
});
|
|
46
|
+
// Create SkillLoader — from directories or empty
|
|
47
|
+
if (config.skillPaths && config.skillPaths.length > 0) {
|
|
48
|
+
this.skillLoader = SkillLoader.fromDirectories(config.skillPaths);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.skillLoader = new SkillLoader();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// ── Static Factory ──────────────────────────────────────────────────
|
|
55
|
+
static create(config) {
|
|
56
|
+
return new ONIHarness(config);
|
|
57
|
+
}
|
|
58
|
+
// ── Private: Build Loop Config ──────────────────────────────────────
|
|
59
|
+
buildLoopConfig(agentConfig) {
|
|
60
|
+
// Build systemPrompt from soul fragments + skill descriptions
|
|
61
|
+
const systemPrompt = [
|
|
62
|
+
this.config.soul,
|
|
63
|
+
agentConfig.soul,
|
|
64
|
+
this.skillLoader.getDescriptionsForContext(),
|
|
65
|
+
]
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.join("\n\n");
|
|
68
|
+
// Build tools array
|
|
69
|
+
const tools = [
|
|
70
|
+
...this.todoModule.getTools(),
|
|
71
|
+
this.skillLoader.getSkillTool(),
|
|
72
|
+
...(this.config.sharedTools ?? []),
|
|
73
|
+
...(agentConfig.tools ?? []),
|
|
74
|
+
];
|
|
75
|
+
return {
|
|
76
|
+
model: this.config.model,
|
|
77
|
+
tools,
|
|
78
|
+
agentName: agentConfig.name,
|
|
79
|
+
systemPrompt,
|
|
80
|
+
maxTurns: agentConfig.maxTurns ?? this.config.maxTurns,
|
|
81
|
+
todoModule: this.todoModule,
|
|
82
|
+
hooksEngine: this.hooksEngine,
|
|
83
|
+
compactor: this.compactor,
|
|
84
|
+
safetyGate: this.safetyGate,
|
|
85
|
+
skillLoader: this.skillLoader,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// ── Public: run ─────────────────────────────────────────────────────
|
|
89
|
+
async *run(prompt, agentConfig) {
|
|
90
|
+
const config = typeof agentConfig === "string"
|
|
91
|
+
? { name: agentConfig }
|
|
92
|
+
: agentConfig;
|
|
93
|
+
const loopConfig = this.buildLoopConfig(config);
|
|
94
|
+
yield* agentLoop(prompt, loopConfig);
|
|
95
|
+
}
|
|
96
|
+
// ── Public: runToResult ─────────────────────────────────────────────
|
|
97
|
+
async runToResult(prompt, agentConfig) {
|
|
98
|
+
let finalResult = "";
|
|
99
|
+
for await (const msg of this.run(prompt, agentConfig)) {
|
|
100
|
+
if (msg.type === "result") {
|
|
101
|
+
finalResult = msg.content ?? "";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return finalResult;
|
|
105
|
+
}
|
|
106
|
+
// ── Public: asNode ──────────────────────────────────────────────────
|
|
107
|
+
asNode(agentConfig) {
|
|
108
|
+
const loopConfig = this.buildLoopConfig(agentConfig);
|
|
109
|
+
return wrapWithAgentLoop(loopConfig);
|
|
110
|
+
}
|
|
111
|
+
// ── Public: asSwarmAgent ────────────────────────────────────────────
|
|
112
|
+
asSwarmAgent(name, soul, tools, opts) {
|
|
113
|
+
const agentConfig = { name, soul, tools };
|
|
114
|
+
const loopConfig = this.buildLoopConfig(agentConfig);
|
|
115
|
+
return {
|
|
116
|
+
name,
|
|
117
|
+
description: opts?.description ?? soul,
|
|
118
|
+
capabilities: opts?.capabilities ?? [],
|
|
119
|
+
handler: wrapWithAgentLoop(loopConfig),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// ── Public: Module Access ───────────────────────────────────────────
|
|
123
|
+
getTodoModule() {
|
|
124
|
+
return this.todoModule;
|
|
125
|
+
}
|
|
126
|
+
getHooksEngine() {
|
|
127
|
+
return this.hooksEngine;
|
|
128
|
+
}
|
|
129
|
+
getSkillLoader() {
|
|
130
|
+
return this.skillLoader;
|
|
131
|
+
}
|
|
132
|
+
// ── Public: Runtime Registration ────────────────────────────────────
|
|
133
|
+
registerSkill(skill) {
|
|
134
|
+
this.skillLoader.register(skill);
|
|
135
|
+
}
|
|
136
|
+
addHooks(config) {
|
|
137
|
+
this.hooksEngine.configure(config);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/harness/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export type HookEvent = "SessionStart" | "SessionEnd" | "UserPromptSubmit" | "PreToolUse" | "PermissionRequest" | "PostToolUse" | "PostToolUseFailure" | "SubagentStart" | "SubagentStop" | "Stop" | "Notification" | "PreCompact";
|
|
2
|
+
export interface BasePayload {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface SessionStartPayload extends BasePayload {
|
|
7
|
+
agentName: string;
|
|
8
|
+
tools: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface SessionEndPayload extends BasePayload {
|
|
11
|
+
reason: string;
|
|
12
|
+
turns: number;
|
|
13
|
+
}
|
|
14
|
+
export interface UserPromptPayload extends BasePayload {
|
|
15
|
+
prompt: string;
|
|
16
|
+
}
|
|
17
|
+
export interface PreToolUsePayload extends BasePayload {
|
|
18
|
+
toolName: string;
|
|
19
|
+
input: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
export interface PostToolUsePayload extends BasePayload {
|
|
22
|
+
toolName: string;
|
|
23
|
+
input: Record<string, unknown>;
|
|
24
|
+
output: unknown;
|
|
25
|
+
durationMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface PostToolUseFailurePayload extends BasePayload {
|
|
28
|
+
toolName: string;
|
|
29
|
+
input: Record<string, unknown>;
|
|
30
|
+
error: Error | string;
|
|
31
|
+
}
|
|
32
|
+
export interface StopPayload extends BasePayload {
|
|
33
|
+
response: string;
|
|
34
|
+
}
|
|
35
|
+
export interface PreCompactPayload extends BasePayload {
|
|
36
|
+
messageCount: number;
|
|
37
|
+
estimatedTokens: number;
|
|
38
|
+
}
|
|
39
|
+
export interface SubagentPayload extends BasePayload {
|
|
40
|
+
agentName: string;
|
|
41
|
+
parentSessionId?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface HookResult {
|
|
44
|
+
decision: "allow" | "deny" | "block" | "escalate";
|
|
45
|
+
reason?: string;
|
|
46
|
+
additionalContext?: string;
|
|
47
|
+
modifiedInput?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
export interface HookDefinition {
|
|
50
|
+
/** Regex/pattern for tool name filtering. Supports pipe OR, wildcard, arg patterns. */
|
|
51
|
+
matcher?: string;
|
|
52
|
+
handler: (payload: BasePayload) => Promise<HookResult> | HookResult;
|
|
53
|
+
timeout?: number;
|
|
54
|
+
description?: string;
|
|
55
|
+
}
|
|
56
|
+
export type HooksConfig = Partial<Record<HookEvent, HookDefinition[]>>;
|
|
57
|
+
export declare class HooksEngine {
|
|
58
|
+
private hooks;
|
|
59
|
+
private anyListeners;
|
|
60
|
+
on(event: HookEvent, definition: HookDefinition): void;
|
|
61
|
+
configure(config: HooksConfig): void;
|
|
62
|
+
off(event: HookEvent): void;
|
|
63
|
+
clear(): void;
|
|
64
|
+
onAny(listener: (event: HookEvent, payload: BasePayload) => void): void;
|
|
65
|
+
fire(event: HookEvent, payload: BasePayload): Promise<HookResult | null>;
|
|
66
|
+
private matches;
|
|
67
|
+
static withSecurityGuardrails(): HooksEngine;
|
|
68
|
+
static withQualityGate(validate: (response: string) => string | null): HooksEngine;
|
|
69
|
+
static compose(...engines: HooksEngine[]): HooksEngine;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=hooks-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-engine.d.ts","sourceRoot":"","sources":["../../src/harness/hooks-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core/harness — HooksEngine
|
|
3
|
+
// 12 lifecycle events for the agent loop
|
|
4
|
+
// ============================================================
|
|
5
|
+
// ─── withTimeout helper ─────────────────────────────────────────────────────
|
|
6
|
+
function withTimeout(promise, ms) {
|
|
7
|
+
return Promise.race([
|
|
8
|
+
promise,
|
|
9
|
+
new Promise((resolve) => setTimeout(() => resolve(null), ms)),
|
|
10
|
+
]);
|
|
11
|
+
}
|
|
12
|
+
// ─── HooksEngine ────────────────────────────────────────────────────────────
|
|
13
|
+
export class HooksEngine {
|
|
14
|
+
hooks = new Map();
|
|
15
|
+
anyListeners = [];
|
|
16
|
+
// ── Registration ────────────────────────────────────────────────────
|
|
17
|
+
on(event, definition) {
|
|
18
|
+
const list = this.hooks.get(event);
|
|
19
|
+
if (list) {
|
|
20
|
+
list.push(definition);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.hooks.set(event, [definition]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
configure(config) {
|
|
27
|
+
for (const event of Object.keys(config)) {
|
|
28
|
+
const defs = config[event];
|
|
29
|
+
if (defs) {
|
|
30
|
+
for (const def of defs) {
|
|
31
|
+
this.on(event, def);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
off(event) {
|
|
37
|
+
this.hooks.delete(event);
|
|
38
|
+
}
|
|
39
|
+
clear() {
|
|
40
|
+
this.hooks.clear();
|
|
41
|
+
this.anyListeners = [];
|
|
42
|
+
}
|
|
43
|
+
// ── Observability ───────────────────────────────────────────────────
|
|
44
|
+
onAny(listener) {
|
|
45
|
+
this.anyListeners.push(listener);
|
|
46
|
+
}
|
|
47
|
+
// ── Fire ────────────────────────────────────────────────────────────
|
|
48
|
+
async fire(event, payload) {
|
|
49
|
+
// Notify any-listeners (best-effort)
|
|
50
|
+
for (const listener of this.anyListeners) {
|
|
51
|
+
try {
|
|
52
|
+
listener(event, payload);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// silently ignore
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const defs = this.hooks.get(event);
|
|
59
|
+
if (!defs || defs.length === 0)
|
|
60
|
+
return null;
|
|
61
|
+
const aggregatedContext = [];
|
|
62
|
+
for (const def of defs) {
|
|
63
|
+
// Check matcher against toolName in payload
|
|
64
|
+
if (def.matcher && !this.matches(def.matcher, payload)) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
let result;
|
|
68
|
+
try {
|
|
69
|
+
const promise = Promise.resolve(def.handler(payload));
|
|
70
|
+
if (def.timeout != null && def.timeout > 0) {
|
|
71
|
+
result = await withTimeout(promise, def.timeout);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
result = await promise;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Errors are caught silently; treat as pass
|
|
79
|
+
result = null;
|
|
80
|
+
}
|
|
81
|
+
if (result == null)
|
|
82
|
+
continue;
|
|
83
|
+
// Short-circuit on deny or block
|
|
84
|
+
if (result.decision === "deny" || result.decision === "block") {
|
|
85
|
+
// Attach any previously aggregated context
|
|
86
|
+
if (aggregatedContext.length > 0) {
|
|
87
|
+
result.additionalContext = [
|
|
88
|
+
...aggregatedContext,
|
|
89
|
+
...(result.additionalContext ? [result.additionalContext] : []),
|
|
90
|
+
].join("\n");
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
// Collect additionalContext from allow/escalate results
|
|
95
|
+
if (result.additionalContext) {
|
|
96
|
+
aggregatedContext.push(result.additionalContext);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// All hooks passed
|
|
100
|
+
if (aggregatedContext.length > 0) {
|
|
101
|
+
return {
|
|
102
|
+
decision: "allow",
|
|
103
|
+
additionalContext: aggregatedContext.join("\n"),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
// ── Matcher ─────────────────────────────────────────────────────────
|
|
109
|
+
matches(matcher, payload) {
|
|
110
|
+
const toolName = payload.toolName;
|
|
111
|
+
if (!toolName)
|
|
112
|
+
return true;
|
|
113
|
+
// Wildcard — matches everything
|
|
114
|
+
if (matcher === "*")
|
|
115
|
+
return true;
|
|
116
|
+
// CC-style arg pattern: "Bash(git:*)"
|
|
117
|
+
const argMatch = matcher.match(/^([^(]+)\((.+)\)$/);
|
|
118
|
+
if (argMatch) {
|
|
119
|
+
const toolPattern = argMatch[1];
|
|
120
|
+
const argPattern = argMatch[2];
|
|
121
|
+
if (toolName !== toolPattern)
|
|
122
|
+
return false;
|
|
123
|
+
// Extract the arg prefix from pattern like "git:*" → prefix "git"
|
|
124
|
+
const input = payload.input;
|
|
125
|
+
if (!input)
|
|
126
|
+
return false;
|
|
127
|
+
// Check the first string value in input against the arg pattern
|
|
128
|
+
const argPrefix = argPattern.replace(/:\*$/, "");
|
|
129
|
+
for (const val of Object.values(input)) {
|
|
130
|
+
if (typeof val === "string" && val.startsWith(argPrefix)) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
// Pipe-separated OR patterns: "Write|Edit"
|
|
137
|
+
const patterns = matcher.split("|");
|
|
138
|
+
return patterns.some((p) => p === toolName);
|
|
139
|
+
}
|
|
140
|
+
// ── Static Factories ──────────────────────────────────────────────
|
|
141
|
+
static withSecurityGuardrails() {
|
|
142
|
+
const engine = new HooksEngine();
|
|
143
|
+
const dangerousBashPatterns = [
|
|
144
|
+
/rm\s+(-[a-zA-Z]*)?r[a-zA-Z]*f/, // rm -rf
|
|
145
|
+
/mkfs/,
|
|
146
|
+
/dd\s+if=/,
|
|
147
|
+
/chmod\s+777/,
|
|
148
|
+
/curl[^|]*\|\s*sh/,
|
|
149
|
+
/curl[^|]*\|\s*bash/,
|
|
150
|
+
/wget[^|]*\|\s*sh/,
|
|
151
|
+
/wget[^|]*\|\s*bash/,
|
|
152
|
+
];
|
|
153
|
+
const sensitiveFilePatterns = [
|
|
154
|
+
/\.env$/,
|
|
155
|
+
/\.env\./,
|
|
156
|
+
/\.pem$/,
|
|
157
|
+
/id_rsa/,
|
|
158
|
+
/credentials/,
|
|
159
|
+
];
|
|
160
|
+
engine.on("PreToolUse", {
|
|
161
|
+
description: "Block dangerous bash commands",
|
|
162
|
+
matcher: "*",
|
|
163
|
+
handler: async (payload) => {
|
|
164
|
+
const p = payload;
|
|
165
|
+
const input = p.input ?? {};
|
|
166
|
+
// Check bash commands
|
|
167
|
+
if (p.toolName === "Bash") {
|
|
168
|
+
const command = typeof input.command === "string" ? input.command : "";
|
|
169
|
+
for (const pattern of dangerousBashPatterns) {
|
|
170
|
+
if (pattern.test(command)) {
|
|
171
|
+
return {
|
|
172
|
+
decision: "deny",
|
|
173
|
+
reason: `Dangerous command blocked: matches ${pattern.source}`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Check file access for sensitive files
|
|
179
|
+
const filePath = typeof input.file_path === "string"
|
|
180
|
+
? input.file_path
|
|
181
|
+
: typeof input.path === "string"
|
|
182
|
+
? input.path
|
|
183
|
+
: "";
|
|
184
|
+
if (filePath) {
|
|
185
|
+
for (const pattern of sensitiveFilePatterns) {
|
|
186
|
+
if (pattern.test(filePath)) {
|
|
187
|
+
return {
|
|
188
|
+
decision: "deny",
|
|
189
|
+
reason: `Sensitive file access blocked: ${filePath}`,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return { decision: "allow" };
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
return engine;
|
|
198
|
+
}
|
|
199
|
+
static withQualityGate(validate) {
|
|
200
|
+
const engine = new HooksEngine();
|
|
201
|
+
engine.on("Stop", {
|
|
202
|
+
description: "Quality gate — validates response before allowing stop",
|
|
203
|
+
handler: async (payload) => {
|
|
204
|
+
const p = payload;
|
|
205
|
+
const feedback = validate(p.response);
|
|
206
|
+
if (feedback) {
|
|
207
|
+
return {
|
|
208
|
+
decision: "block",
|
|
209
|
+
reason: feedback,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return { decision: "allow" };
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
return engine;
|
|
216
|
+
}
|
|
217
|
+
static compose(...engines) {
|
|
218
|
+
const merged = new HooksEngine();
|
|
219
|
+
for (const engine of engines) {
|
|
220
|
+
for (const [event, defs] of engine.hooks.entries()) {
|
|
221
|
+
for (const def of defs) {
|
|
222
|
+
merged.on(event, def);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
for (const listener of engine.anyListeners) {
|
|
226
|
+
merged.onAny(listener);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return merged;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=hooks-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-engine.js","sourceRoot":"","sources":["../../src/harness/hooks-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { agentLoop, wrapWithAgentLoop } from "./agent-loop.js";
|
|
2
|
+
export { TodoModule } from "./todo-module.js";
|
|
3
|
+
export type { Todo, TodoState, TodoStatus, TodoPriority } from "./todo-module.js";
|
|
4
|
+
export { HooksEngine } from "./hooks-engine.js";
|
|
5
|
+
export type { HookEvent, HookDefinition, HookResult, HooksConfig, BasePayload, SessionStartPayload, SessionEndPayload, PreToolUsePayload, PostToolUsePayload, PostToolUseFailurePayload, StopPayload, PreCompactPayload, SubagentPayload, UserPromptPayload, } from "./hooks-engine.js";
|
|
6
|
+
export { ContextCompactor } from "./context-compactor.js";
|
|
7
|
+
export type { CompactorConfig } from "./context-compactor.js";
|
|
8
|
+
export { SafetyGate } from "./safety-gate.js";
|
|
9
|
+
export type { SafetyGateConfig, SafetyCheckResult } from "./safety-gate.js";
|
|
10
|
+
export { SkillLoader } from "./skill-loader.js";
|
|
11
|
+
export type { SkillDefinition } from "./skill-loader.js";
|
|
12
|
+
export { ONIHarness } from "./harness.js";
|
|
13
|
+
export type { SwarmAgentCompat } from "./harness.js";
|
|
14
|
+
export type { HarnessToolContext, LoopMessage, LoopMessageType, LoopToolResult, AgentLoopConfig, HarnessConfig, AgentNodeConfig, } from "./types.js";
|
|
15
|
+
export { generateId } from "./types.js";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAG/D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGlF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EACV,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAClD,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EACnD,iBAAiB,EAAE,kBAAkB,EAAE,yBAAyB,EAChE,WAAW,EAAE,iBAAiB,EAAE,eAAe,EAC/C,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,YAAY,EACV,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAChE,eAAe,EAAE,aAAa,EAAE,eAAe,GAChD,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core/harness — Public API
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Core loop
|
|
5
|
+
export { agentLoop, wrapWithAgentLoop } from "./agent-loop.js";
|
|
6
|
+
// Working memory
|
|
7
|
+
export { TodoModule } from "./todo-module.js";
|
|
8
|
+
// Lifecycle hooks
|
|
9
|
+
export { HooksEngine } from "./hooks-engine.js";
|
|
10
|
+
// Context compaction
|
|
11
|
+
export { ContextCompactor } from "./context-compactor.js";
|
|
12
|
+
// Safety gate
|
|
13
|
+
export { SafetyGate } from "./safety-gate.js";
|
|
14
|
+
// Skill loader
|
|
15
|
+
export { SkillLoader } from "./skill-loader.js";
|
|
16
|
+
// Integration layer
|
|
17
|
+
export { ONIHarness } from "./harness.js";
|
|
18
|
+
export { generateId } from "./types.js";
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,qCAAqC;AACrC,+DAA+D;AAE/D,YAAY;AACZ,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE/D,iBAAiB;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,kBAAkB;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAShD,qBAAqB;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,oBAAoB;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAQ1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ONIModel } from "../models/types.js";
|
|
2
|
+
export interface SafetyGateConfig {
|
|
3
|
+
safetyModel: ONIModel;
|
|
4
|
+
protectedTools?: string[];
|
|
5
|
+
safetySystemPrompt?: string;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface SafetyCheckResult {
|
|
9
|
+
approved: boolean;
|
|
10
|
+
reason?: string;
|
|
11
|
+
riskScore?: number;
|
|
12
|
+
suggestion?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class SafetyGate {
|
|
15
|
+
private readonly model;
|
|
16
|
+
private readonly protectedTools;
|
|
17
|
+
private readonly systemPrompt;
|
|
18
|
+
private readonly timeout;
|
|
19
|
+
constructor(config: SafetyGateConfig);
|
|
20
|
+
/** Returns true if the tool requires a safety check before execution. */
|
|
21
|
+
requiresCheck(toolName: string): boolean;
|
|
22
|
+
/** Sends tool call info to the safety model and returns the check result. */
|
|
23
|
+
check(call: {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
args: Record<string, unknown>;
|
|
27
|
+
}): Promise<SafetyCheckResult>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=safety-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety-gate.d.ts","sourceRoot":"","sources":["../../src/harness/safety-gate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAInD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,QAAQ,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAkCD,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,gBAAgB;IAOpC,yEAAyE;IACzE,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIxC,6EAA6E;IACvE,KAAK,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA2B3G"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core/harness — SafetyGate
|
|
3
|
+
// Fast-model pre-execution checks for destructive operations
|
|
4
|
+
// ============================================================
|
|
5
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
6
|
+
const DEFAULT_PROTECTED_TOOLS = ["Bash", "Write", "MultiEdit"];
|
|
7
|
+
const DEFAULT_TIMEOUT = 5000;
|
|
8
|
+
const DEFAULT_SAFETY_PROMPT = `You are a safety evaluator for an AI agent's tool calls. Analyze the tool call and respond with a JSON object:
|
|
9
|
+
{"approved": boolean, "reason": string, "riskScore": number (0-1), "suggestion"?: string}
|
|
10
|
+
|
|
11
|
+
Be strict about:
|
|
12
|
+
- Irreversible deletions (rm -rf, DROP TABLE, etc.)
|
|
13
|
+
- Broad file writes that could overwrite important files
|
|
14
|
+
- Pipe-to-shell patterns (curl | sh, wget | bash)
|
|
15
|
+
- Credential access (.env, secrets, tokens, API keys)
|
|
16
|
+
|
|
17
|
+
Be permissive about:
|
|
18
|
+
- Read operations (cat, ls, grep, find)
|
|
19
|
+
- Targeted writes to specific files
|
|
20
|
+
- Build and test commands (npm test, make, vitest)
|
|
21
|
+
- Version control operations (git status, git diff)
|
|
22
|
+
|
|
23
|
+
Respond ONLY with the JSON object, no other text.`;
|
|
24
|
+
// ─── Fallback result ────────────────────────────────────────────────────────
|
|
25
|
+
const FALLBACK_RESULT = {
|
|
26
|
+
approved: true,
|
|
27
|
+
reason: "Safety check skipped (timeout/error)",
|
|
28
|
+
riskScore: 0.1,
|
|
29
|
+
};
|
|
30
|
+
// ─── SafetyGate ─────────────────────────────────────────────────────────────
|
|
31
|
+
export class SafetyGate {
|
|
32
|
+
model;
|
|
33
|
+
protectedTools;
|
|
34
|
+
systemPrompt;
|
|
35
|
+
timeout;
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.model = config.safetyModel;
|
|
38
|
+
this.protectedTools = new Set(config.protectedTools ?? DEFAULT_PROTECTED_TOOLS);
|
|
39
|
+
this.systemPrompt = config.safetySystemPrompt ?? DEFAULT_SAFETY_PROMPT;
|
|
40
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
41
|
+
}
|
|
42
|
+
/** Returns true if the tool requires a safety check before execution. */
|
|
43
|
+
requiresCheck(toolName) {
|
|
44
|
+
return this.protectedTools.has(toolName);
|
|
45
|
+
}
|
|
46
|
+
/** Sends tool call info to the safety model and returns the check result. */
|
|
47
|
+
async check(call) {
|
|
48
|
+
try {
|
|
49
|
+
const userMessage = `Tool: ${call.name}\nArguments: ${JSON.stringify(call.args, null, 2)}`;
|
|
50
|
+
const responsePromise = this.model.chat({
|
|
51
|
+
messages: [{ role: "user", content: userMessage }],
|
|
52
|
+
systemPrompt: this.systemPrompt,
|
|
53
|
+
maxTokens: 256,
|
|
54
|
+
});
|
|
55
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
56
|
+
setTimeout(() => reject(new Error("Safety check timeout")), this.timeout);
|
|
57
|
+
});
|
|
58
|
+
const response = await Promise.race([responsePromise, timeoutPromise]);
|
|
59
|
+
const parsed = JSON.parse(response.content);
|
|
60
|
+
return {
|
|
61
|
+
approved: Boolean(parsed.approved),
|
|
62
|
+
reason: parsed.reason,
|
|
63
|
+
riskScore: parsed.riskScore,
|
|
64
|
+
suggestion: parsed.suggestion,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return { ...FALLBACK_RESULT };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=safety-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety-gate.js","sourceRoot":"","sources":["../../src/harness/safety-gate.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,qCAAqC;AACrC,6DAA6D;AAC7D,+DAA+D;AAoB/D,+EAA+E;AAE/E,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAC/D,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;kDAeoB,CAAC;AAEnD,+EAA+E;AAE/E,MAAM,eAAe,GAAsB;IACzC,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE,sCAAsC;IAC9C,SAAS,EAAE,GAAG;CACf,CAAC;AAEF,+EAA+E;AAE/E,MAAM,OAAO,UAAU;IACJ,KAAK,CAAW;IAChB,cAAc,CAAc;IAC5B,YAAY,CAAS;IACrB,OAAO,CAAS;IAEjC,YAAY,MAAwB;QAClC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,uBAAuB,CAAC,CAAC;QAChF,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,kBAAkB,IAAI,qBAAqB,CAAC;QACvE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,eAAe,CAAC;IACnD,CAAC;IAED,yEAAyE;IACzE,aAAa,CAAC,QAAgB;QAC5B,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,KAAK,CAAC,IAAiE;QAC3E,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,SAAS,IAAI,CAAC,IAAI,gBAAgB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YAE3F,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBACtC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;gBAClD,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,SAAS,EAAE,GAAG;aACf,CAAC,CAAC;YAEH,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;gBACtD,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5E,CAAC,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAiB,CAAC,CAAC;YAEtD,OAAO;gBACL,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAClC,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,GAAG,eAAe,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;CACF"}
|