@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
package/SECURITY.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
| ------- | ------------------ |
|
|
7
|
+
| 0.7.x | :white_check_mark: |
|
|
8
|
+
| < 0.7 | :x: |
|
|
9
|
+
|
|
10
|
+
## Reporting a Vulnerability
|
|
11
|
+
|
|
12
|
+
If you discover a security vulnerability in `@oni.bot/core`, please report it responsibly:
|
|
13
|
+
|
|
14
|
+
1. **Do not** open a public GitHub issue
|
|
15
|
+
2. Email **security@oni.bot** with:
|
|
16
|
+
- Description of the vulnerability
|
|
17
|
+
- Steps to reproduce
|
|
18
|
+
- Potential impact
|
|
19
|
+
- Suggested fix (if any)
|
|
20
|
+
3. You will receive acknowledgment within **48 hours**
|
|
21
|
+
4. A fix will be released within **7 days** for critical issues
|
|
22
|
+
|
|
23
|
+
## Security Considerations
|
|
24
|
+
|
|
25
|
+
### Tool Execution
|
|
26
|
+
|
|
27
|
+
`@oni.bot/core` provides a tool execution framework. The framework itself does not execute arbitrary code, but user-defined node functions and tools can. Users are responsible for:
|
|
28
|
+
|
|
29
|
+
- Validating tool inputs before execution
|
|
30
|
+
- Using the built-in `Permissions` guardrail to restrict tool access
|
|
31
|
+
- Implementing appropriate sandboxing for untrusted tool code
|
|
32
|
+
|
|
33
|
+
### Model API Keys
|
|
34
|
+
|
|
35
|
+
API keys for model providers (OpenAI, Anthropic, etc.) should be:
|
|
36
|
+
|
|
37
|
+
- Stored in environment variables, not in code
|
|
38
|
+
- Never logged or included in error messages
|
|
39
|
+
- Rotated regularly
|
|
40
|
+
|
|
41
|
+
### Budget Enforcement
|
|
42
|
+
|
|
43
|
+
The `BudgetTracker` guardrail provides cost limits but should not be the sole control:
|
|
44
|
+
|
|
45
|
+
- Set conservative budget limits
|
|
46
|
+
- Monitor usage through the telemetry/audit system
|
|
47
|
+
- Implement server-side rate limiting for production deployments
|
|
48
|
+
|
|
49
|
+
### Checkpoint Data
|
|
50
|
+
|
|
51
|
+
Checkpoint data may contain sensitive state. When using persistent checkpointers:
|
|
52
|
+
|
|
53
|
+
- Use encrypted storage for SQLite/PostgreSQL backends
|
|
54
|
+
- Implement TTL-based cleanup for old checkpoints
|
|
55
|
+
- Restrict access to checkpoint storage
|
|
56
|
+
|
|
57
|
+
### Content Filtering
|
|
58
|
+
|
|
59
|
+
The guardrails module provides content filters (PII, topic). These are best-effort:
|
|
60
|
+
|
|
61
|
+
- Do not rely solely on built-in filters for compliance
|
|
62
|
+
- Layer additional filtering for sensitive domains (healthcare, finance)
|
|
63
|
+
- Audit filter effectiveness regularly
|
|
64
|
+
|
|
65
|
+
## Dependencies
|
|
66
|
+
|
|
67
|
+
`@oni.bot/core` ships with **zero runtime dependencies**. Optional peer dependencies:
|
|
68
|
+
|
|
69
|
+
- `better-sqlite3` — for SQLite checkpointing (optional)
|
|
70
|
+
|
|
71
|
+
This minimizes supply chain attack surface.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/checkpointers/sqlite.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAQzF,qBAAa,kBAAkB,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,EAAE;IAAvC,OAAO;WAEM,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/checkpointers/sqlite.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAQzF,qBAAa,kBAAkB,CAAC,CAAC,CAAE,YAAW,eAAe,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,EAAE;IAAvC,OAAO;WAEM,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IA4BhE,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAOvD,GAAG,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IA6BjF,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAK7E,KAAK,IAAI,IAAI;IAEb,OAAO,CAAC,WAAW;CAapB"}
|
|
@@ -22,19 +22,20 @@ export class SqliteCheckpointer {
|
|
|
22
22
|
}
|
|
23
23
|
const db = new DB(dbPath);
|
|
24
24
|
db.exec("PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL;");
|
|
25
|
-
db.exec(`
|
|
26
|
-
CREATE TABLE IF NOT EXISTS oni_checkpoints (
|
|
27
|
-
thread_id TEXT NOT NULL,
|
|
28
|
-
step INTEGER NOT NULL,
|
|
29
|
-
agent_id TEXT,
|
|
30
|
-
state TEXT NOT NULL,
|
|
31
|
-
next_nodes TEXT NOT NULL,
|
|
32
|
-
pending_sends
|
|
33
|
-
metadata
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
db.exec(`
|
|
26
|
+
CREATE TABLE IF NOT EXISTS oni_checkpoints (
|
|
27
|
+
thread_id TEXT NOT NULL,
|
|
28
|
+
step INTEGER NOT NULL,
|
|
29
|
+
agent_id TEXT,
|
|
30
|
+
state TEXT NOT NULL,
|
|
31
|
+
next_nodes TEXT NOT NULL,
|
|
32
|
+
pending_sends TEXT NOT NULL DEFAULT '[]',
|
|
33
|
+
metadata TEXT DEFAULT NULL,
|
|
34
|
+
pending_writes TEXT DEFAULT NULL,
|
|
35
|
+
timestamp INTEGER NOT NULL,
|
|
36
|
+
PRIMARY KEY (thread_id, step)
|
|
37
|
+
);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_thread ON oni_checkpoints (thread_id);
|
|
38
39
|
`);
|
|
39
40
|
return new SqliteCheckpointer(db);
|
|
40
41
|
}
|
|
@@ -45,11 +46,11 @@ export class SqliteCheckpointer {
|
|
|
45
46
|
return row ? this.deserialize(row) : null;
|
|
46
47
|
}
|
|
47
48
|
async put(cp) {
|
|
48
|
-
this.db.prepare(`
|
|
49
|
-
INSERT OR REPLACE INTO oni_checkpoints
|
|
50
|
-
(thread_id, step, agent_id, state, next_nodes, pending_sends, metadata, timestamp)
|
|
51
|
-
VALUES (
|
|
52
|
-
`).run(cp.threadId, cp.step, cp.agentId ?? null, JSON.stringify(cp.state), JSON.stringify(cp.nextNodes), JSON.stringify(cp.pendingSends ?? []), cp.metadata ? JSON.stringify(cp.metadata) : null, cp.timestamp);
|
|
49
|
+
this.db.prepare(`
|
|
50
|
+
INSERT OR REPLACE INTO oni_checkpoints
|
|
51
|
+
(thread_id, step, agent_id, state, next_nodes, pending_sends, metadata, pending_writes, timestamp)
|
|
52
|
+
VALUES (?,?,?,?,?,?,?,?,?)
|
|
53
|
+
`).run(cp.threadId, cp.step, cp.agentId ?? null, JSON.stringify(cp.state), JSON.stringify(cp.nextNodes), JSON.stringify(cp.pendingSends ?? []), cp.metadata ? JSON.stringify(cp.metadata) : null, cp.pendingWrites ? JSON.stringify(cp.pendingWrites) : null, cp.timestamp);
|
|
53
54
|
}
|
|
54
55
|
async list(threadId, opts) {
|
|
55
56
|
let sql = "SELECT * FROM oni_checkpoints WHERE thread_id=?";
|
|
@@ -91,6 +92,7 @@ export class SqliteCheckpointer {
|
|
|
91
92
|
nextNodes: JSON.parse(row["next_nodes"]),
|
|
92
93
|
pendingSends: JSON.parse(row["pending_sends"]),
|
|
93
94
|
metadata: row["metadata"] ? JSON.parse(row["metadata"]) : undefined,
|
|
95
|
+
pendingWrites: row["pending_writes"] ? JSON.parse(row["pending_writes"]) : undefined,
|
|
94
96
|
timestamp: row["timestamp"],
|
|
95
97
|
};
|
|
96
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/checkpointers/sqlite.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sCAAsC;AACtC,+DAA+D;AAC/D,uDAAuD;AACvD,EAAE;AACF,+BAA+B;AAC/B,yCAAyC;AACzC,+DAA+D;AAU/D,MAAM,OAAO,kBAAkB;IACQ;IAArC,YAAqC,EAAY;QAAZ,OAAE,GAAF,EAAE,CAAU;IAAG,CAAC;IAErD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAI,MAAc;QACnC,IAAI,EAA+B,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,gBAA0B,CAAC,CAAC;YACrD,EAAE,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;QAC1B,EAAE,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;QAC/D,EAAE,CAAC,IAAI,CAAC
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/checkpointers/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type CircuitState = "closed" | "open" | "half_open";
|
|
2
|
+
export interface CircuitBreakerConfig {
|
|
3
|
+
threshold: number;
|
|
4
|
+
resetAfter: number;
|
|
5
|
+
fallback?: (...args: unknown[]) => unknown;
|
|
6
|
+
}
|
|
7
|
+
export declare class CircuitBreaker {
|
|
8
|
+
private readonly config;
|
|
9
|
+
private _state;
|
|
10
|
+
private consecutiveFailures;
|
|
11
|
+
private lastFailureTime;
|
|
12
|
+
private readonly nodeName;
|
|
13
|
+
constructor(config: CircuitBreakerConfig, nodeName?: string);
|
|
14
|
+
get state(): CircuitState;
|
|
15
|
+
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
16
|
+
private onSuccess;
|
|
17
|
+
private onFailure;
|
|
18
|
+
reset(): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;CAC5C;AAED,qBAAa,cAAc;IAMb,OAAO,CAAC,QAAQ,CAAC,MAAM;IALnC,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEL,MAAM,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,MAAM;IAI5E,IAAI,KAAK,IAAI,YAAY,CAKxB;IAEK,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAgBlD,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,SAAS;IAUjB,KAAK,IAAI,IAAI;CAKd"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core — Circuit Breaker
|
|
3
|
+
// ============================================================
|
|
4
|
+
import { CircuitBreakerOpenError } from "./errors.js";
|
|
5
|
+
export class CircuitBreaker {
|
|
6
|
+
config;
|
|
7
|
+
_state = "closed";
|
|
8
|
+
consecutiveFailures = 0;
|
|
9
|
+
lastFailureTime = 0;
|
|
10
|
+
nodeName;
|
|
11
|
+
constructor(config, nodeName) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.nodeName = nodeName ?? "unknown";
|
|
14
|
+
}
|
|
15
|
+
get state() {
|
|
16
|
+
if (this._state === "open" && Date.now() - this.lastFailureTime >= this.config.resetAfter) {
|
|
17
|
+
this._state = "half_open";
|
|
18
|
+
}
|
|
19
|
+
return this._state;
|
|
20
|
+
}
|
|
21
|
+
async execute(fn) {
|
|
22
|
+
const currentState = this.state;
|
|
23
|
+
if (currentState === "open") {
|
|
24
|
+
if (this.config.fallback)
|
|
25
|
+
return this.config.fallback();
|
|
26
|
+
throw new CircuitBreakerOpenError(this.nodeName, this.config.resetAfter);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const result = await fn();
|
|
30
|
+
this.onSuccess();
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
this.onFailure();
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
onSuccess() {
|
|
39
|
+
this.consecutiveFailures = 0;
|
|
40
|
+
this._state = "closed";
|
|
41
|
+
}
|
|
42
|
+
onFailure() {
|
|
43
|
+
this.consecutiveFailures++;
|
|
44
|
+
this.lastFailureTime = Date.now();
|
|
45
|
+
if (this._state === "half_open") {
|
|
46
|
+
this._state = "open";
|
|
47
|
+
}
|
|
48
|
+
else if (this.consecutiveFailures >= this.config.threshold) {
|
|
49
|
+
this._state = "open";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
reset() {
|
|
53
|
+
this._state = "closed";
|
|
54
|
+
this.consecutiveFailures = 0;
|
|
55
|
+
this.lastFailureTime = 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,kCAAkC;AAClC,+DAA+D;AAE/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAUtD,MAAM,OAAO,cAAc;IAMI;IALrB,MAAM,GAAiB,QAAQ,CAAC;IAChC,mBAAmB,GAAG,CAAC,CAAC;IACxB,eAAe,GAAG,CAAC,CAAC;IACX,QAAQ,CAAS;IAElC,YAA6B,MAA4B,EAAE,QAAiB;QAA/C,WAAM,GAAN,MAAM,CAAsB;QACvD,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,SAAS,CAAC;IACxC,CAAC;IAED,IAAI,KAAK;QACP,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC1F,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,OAAO,CAAI,EAAoB;QACnC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;QAChC,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAO,CAAC;YAC7D,MAAM,IAAI,uBAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;IACzB,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC7D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACvB,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QACvB,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ============================================================
|
|
3
|
+
// @oni.bot/core CLI — entry point
|
|
4
|
+
// ============================================================
|
|
5
|
+
import { initProject } from "./init.js";
|
|
6
|
+
import { resolve, basename } from "node:path";
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const command = args[0];
|
|
9
|
+
if (command === "init" && args[1]) {
|
|
10
|
+
const name = basename(args[1]);
|
|
11
|
+
const targetDir = resolve(process.cwd(), args[1]);
|
|
12
|
+
console.log(`\n Creating ONI project: ${name}\n`);
|
|
13
|
+
await initProject(name, targetDir);
|
|
14
|
+
console.log(` Done! Next steps:\n`);
|
|
15
|
+
console.log(` cd ${name}`);
|
|
16
|
+
console.log(` npm install`);
|
|
17
|
+
console.log(` npx tsx src/index.ts\n`);
|
|
18
|
+
console.log(` Documentation: https://github.com/oni-bot/core\n`);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
console.log(`
|
|
22
|
+
Usage: oni init <project-name>
|
|
23
|
+
|
|
24
|
+
Commands:
|
|
25
|
+
init <name> Create a new ONI project
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
oni init my-swarm
|
|
29
|
+
oni init research-team
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,+DAA+D;AAC/D,kCAAkC;AAClC,+DAA+D;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAExB,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,IAAI,CAAC,CAAC;IAEnD,MAAM,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;AACpE,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC;;;;;;;;;CASb,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhF"}
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core CLI — init command
|
|
3
|
+
// ============================================================
|
|
4
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { templates } from "./templates.js";
|
|
7
|
+
export async function initProject(name, targetDir) {
|
|
8
|
+
await mkdir(targetDir, { recursive: true });
|
|
9
|
+
await mkdir(join(targetDir, "src"), { recursive: true });
|
|
10
|
+
// Write files
|
|
11
|
+
await writeFile(join(targetDir, "package.json"), templates.packageJson(name));
|
|
12
|
+
await writeFile(join(targetDir, "tsconfig.json"), templates.tsconfig());
|
|
13
|
+
await writeFile(join(targetDir, "src", "index.ts"), templates.entrypoint());
|
|
14
|
+
await writeFile(join(targetDir, "src", "agent.test.ts"), templates.test());
|
|
15
|
+
await writeFile(join(targetDir, ".gitignore"), templates.gitignore());
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,mCAAmC;AACnC,+DAA+D;AAE/D,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,SAAiB;IAC/D,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzD,cAAc;IACd,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9E,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxE,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5E,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,eAAe,CAAC,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS;sBACF,MAAM,GAAG,MAAM;gBAwBrB,MAAM;kBAiBJ,MAAM;YA8CZ,MAAM;iBAuBD,MAAM;CAOpB,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core CLI — Project templates
|
|
3
|
+
// ============================================================
|
|
4
|
+
export const templates = {
|
|
5
|
+
packageJson(name) {
|
|
6
|
+
const pkg = {
|
|
7
|
+
name,
|
|
8
|
+
version: "0.1.0",
|
|
9
|
+
type: "module",
|
|
10
|
+
scripts: {
|
|
11
|
+
dev: "tsx watch src/index.ts",
|
|
12
|
+
build: "tsc",
|
|
13
|
+
start: "node dist/index.js",
|
|
14
|
+
test: "vitest run",
|
|
15
|
+
},
|
|
16
|
+
dependencies: {
|
|
17
|
+
"@oni.bot/core": "^0.7.0",
|
|
18
|
+
},
|
|
19
|
+
devDependencies: {
|
|
20
|
+
tsx: "^4.0.0",
|
|
21
|
+
typescript: "^5.4.0",
|
|
22
|
+
vitest: "^4.0.0",
|
|
23
|
+
"@types/node": "^20.0.0",
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
return JSON.stringify(pkg, null, 2) + "\n";
|
|
27
|
+
},
|
|
28
|
+
tsconfig() {
|
|
29
|
+
const config = {
|
|
30
|
+
compilerOptions: {
|
|
31
|
+
target: "ES2022",
|
|
32
|
+
module: "NodeNext",
|
|
33
|
+
moduleResolution: "NodeNext",
|
|
34
|
+
outDir: "./dist",
|
|
35
|
+
rootDir: "./src",
|
|
36
|
+
declaration: true,
|
|
37
|
+
strict: true,
|
|
38
|
+
skipLibCheck: true,
|
|
39
|
+
},
|
|
40
|
+
include: ["src/**/*"],
|
|
41
|
+
};
|
|
42
|
+
return JSON.stringify(config, null, 2) + "\n";
|
|
43
|
+
},
|
|
44
|
+
entrypoint() {
|
|
45
|
+
return `import { StateGraph, START, END, lastValue, appendList } from "@oni.bot/core";
|
|
46
|
+
import { MemoryCheckpointer } from "@oni.bot/core";
|
|
47
|
+
import type { Message } from "@oni.bot/core";
|
|
48
|
+
|
|
49
|
+
// Define your state
|
|
50
|
+
type AgentState = {
|
|
51
|
+
messages: Message[];
|
|
52
|
+
result: string;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Build the graph
|
|
56
|
+
const graph = new StateGraph<AgentState>({
|
|
57
|
+
channels: {
|
|
58
|
+
messages: appendList<Message>(),
|
|
59
|
+
result: lastValue(() => ""),
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Add nodes
|
|
64
|
+
graph.addNode("process", async (state) => {
|
|
65
|
+
const lastMessage = state.messages[state.messages.length - 1];
|
|
66
|
+
return {
|
|
67
|
+
result: \`Processed: \${lastMessage?.content ?? "no input"}\`,
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Wire edges
|
|
72
|
+
graph.addEdge(START, "process");
|
|
73
|
+
graph.addEdge("process", END);
|
|
74
|
+
|
|
75
|
+
// Compile with checkpointing
|
|
76
|
+
const app = graph.compile({
|
|
77
|
+
checkpointer: new MemoryCheckpointer(),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Run it
|
|
81
|
+
const result = await app.invoke(
|
|
82
|
+
{ messages: [{ id: "1", role: "user", content: "Hello, ONI!" }] },
|
|
83
|
+
{ threadId: "demo-1" },
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
console.log("Result:", result.result);
|
|
87
|
+
`;
|
|
88
|
+
},
|
|
89
|
+
test() {
|
|
90
|
+
return `import { describe, it, expect } from "vitest";
|
|
91
|
+
import { StateGraph, START, END, lastValue } from "@oni.bot/core";
|
|
92
|
+
import { createTestHarness } from "@oni.bot/core/testing";
|
|
93
|
+
|
|
94
|
+
describe("my agent", () => {
|
|
95
|
+
it("processes input", async () => {
|
|
96
|
+
type S = { value: string };
|
|
97
|
+
const graph = new StateGraph<S>({
|
|
98
|
+
channels: { value: lastValue(() => "") },
|
|
99
|
+
});
|
|
100
|
+
graph.addNode("echo", async (s) => ({ value: s.value + "!" }));
|
|
101
|
+
graph.addEdge(START, "echo");
|
|
102
|
+
graph.addEdge("echo", END);
|
|
103
|
+
|
|
104
|
+
const harness = createTestHarness(graph);
|
|
105
|
+
const result = await harness.invoke({ value: "test" });
|
|
106
|
+
expect(result.value).toBe("test!");
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
`;
|
|
110
|
+
},
|
|
111
|
+
gitignore() {
|
|
112
|
+
return `node_modules/
|
|
113
|
+
dist/
|
|
114
|
+
*.js.map
|
|
115
|
+
.env
|
|
116
|
+
`;
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,wCAAwC;AACxC,+DAA+D;AAE/D,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,WAAW,CAAC,IAAY;QACtB,MAAM,GAAG,GAAG;YACV,IAAI;YACJ,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE;gBACP,GAAG,EAAE,wBAAwB;gBAC7B,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,YAAY;aACnB;YACD,YAAY,EAAE;gBACZ,eAAe,EAAE,QAAQ;aAC1B;YACD,eAAe,EAAE;gBACf,GAAG,EAAE,QAAQ;gBACb,UAAU,EAAE,QAAQ;gBACpB,MAAM,EAAE,QAAQ;gBAChB,aAAa,EAAE,SAAS;aACzB;SACF,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7C,CAAC;IAED,QAAQ;QACN,MAAM,MAAM,GAAG;YACb,eAAe,EAAE;gBACf,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,UAAU;gBAClB,gBAAgB,EAAE,UAAU;gBAC5B,MAAM,EAAE,QAAQ;gBAChB,OAAO,EAAE,OAAO;gBAChB,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;aACnB;YACD,OAAO,EAAE,CAAC,UAAU,CAAC;SACtB,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD,CAAC;IAED,UAAU;QACR,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CV,CAAC;IACA,CAAC;IAED,IAAI;QACF,OAAO;;;;;;;;;;;;;;;;;;;CAmBV,CAAC;IACA,CAAC;IAED,SAAS;QACP,OAAO;;;;CAIV,CAAC;IACA,CAAC;CACF,CAAC"}
|
package/dist/dlq.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface DeadLetter {
|
|
2
|
+
id: string;
|
|
3
|
+
node: string;
|
|
4
|
+
input: Record<string, unknown>;
|
|
5
|
+
error: Error;
|
|
6
|
+
attempts: number;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class DeadLetterQueue {
|
|
10
|
+
private letters;
|
|
11
|
+
record(threadId: string, node: string, input: Record<string, unknown>, error: Error, attempts: number): DeadLetter;
|
|
12
|
+
getAll(threadId: string): DeadLetter[];
|
|
13
|
+
remove(threadId: string, dlId: string): boolean;
|
|
14
|
+
clear(threadId: string): void;
|
|
15
|
+
size(): number;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=dlq.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlq.d.ts","sourceRoot":"","sources":["../src/dlq.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAmC;IAElD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAWlH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAItC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAS/C,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI7B,IAAI,IAAI,MAAM;CAKf"}
|
package/dist/dlq.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core — Dead Letter Queue
|
|
3
|
+
// ============================================================
|
|
4
|
+
let _nextId = 1;
|
|
5
|
+
export class DeadLetterQueue {
|
|
6
|
+
letters = new Map();
|
|
7
|
+
record(threadId, node, input, error, attempts) {
|
|
8
|
+
const dl = {
|
|
9
|
+
id: `dlq-${_nextId++}`,
|
|
10
|
+
node, input, error, attempts,
|
|
11
|
+
timestamp: Date.now(),
|
|
12
|
+
};
|
|
13
|
+
if (!this.letters.has(threadId))
|
|
14
|
+
this.letters.set(threadId, []);
|
|
15
|
+
this.letters.get(threadId).push(dl);
|
|
16
|
+
return dl;
|
|
17
|
+
}
|
|
18
|
+
getAll(threadId) {
|
|
19
|
+
return this.letters.get(threadId) ?? [];
|
|
20
|
+
}
|
|
21
|
+
remove(threadId, dlId) {
|
|
22
|
+
const list = this.letters.get(threadId);
|
|
23
|
+
if (!list)
|
|
24
|
+
return false;
|
|
25
|
+
const idx = list.findIndex((dl) => dl.id === dlId);
|
|
26
|
+
if (idx === -1)
|
|
27
|
+
return false;
|
|
28
|
+
list.splice(idx, 1);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
clear(threadId) {
|
|
32
|
+
this.letters.delete(threadId);
|
|
33
|
+
}
|
|
34
|
+
size() {
|
|
35
|
+
let total = 0;
|
|
36
|
+
for (const list of this.letters.values())
|
|
37
|
+
total += list.length;
|
|
38
|
+
return total;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=dlq.js.map
|
package/dist/dlq.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlq.js","sourceRoot":"","sources":["../src/dlq.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,oCAAoC;AACpC,+DAA+D;AAE/D,IAAI,OAAO,GAAG,CAAC,CAAC;AAWhB,MAAM,OAAO,eAAe;IAClB,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAElD,MAAM,CAAC,QAAgB,EAAE,IAAY,EAAE,KAA8B,EAAE,KAAY,EAAE,QAAgB;QACnG,MAAM,EAAE,GAAe;YACrB,EAAE,EAAE,OAAO,OAAO,EAAE,EAAE;YACtB,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ;YAC5B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,CAAC,QAAgB;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED,MAAM,CAAC,QAAgB,EAAE,IAAY;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;QACnD,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,QAAgB;QACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,IAAI;QACF,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;QAC/D,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
|
+
export type ErrorCategory = "GRAPH" | "NODE" | "EDGE" | "CHECKPOINT" | "STREAM" | "HITL" | "SWARM" | "MODEL" | "STORE" | "CONFIG";
|
|
2
|
+
export interface ONIErrorOptions {
|
|
3
|
+
code: string;
|
|
4
|
+
category: ErrorCategory;
|
|
5
|
+
recoverable: boolean;
|
|
6
|
+
suggestion?: string;
|
|
7
|
+
context?: Record<string, unknown>;
|
|
8
|
+
}
|
|
1
9
|
export declare class ONIError extends Error {
|
|
2
|
-
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly category: ErrorCategory;
|
|
12
|
+
readonly recoverable: boolean;
|
|
13
|
+
readonly suggestion: string;
|
|
14
|
+
readonly context: Record<string, unknown>;
|
|
15
|
+
constructor(message: string, opts?: ONIErrorOptions);
|
|
16
|
+
toJSON(): Record<string, unknown>;
|
|
3
17
|
}
|
|
4
18
|
export declare class InvalidSkeletonError extends ONIError {
|
|
5
19
|
constructor(msg: string);
|
|
@@ -16,6 +30,27 @@ export declare class EdgeConflictError extends ONIError {
|
|
|
16
30
|
export declare class NodeExecutionError extends ONIError {
|
|
17
31
|
constructor(node: string, cause: Error);
|
|
18
32
|
}
|
|
33
|
+
export declare class NodeTimeoutError extends ONIError {
|
|
34
|
+
constructor(node: string, timeoutMs: number);
|
|
35
|
+
}
|
|
36
|
+
export declare class CircuitBreakerOpenError extends ONIError {
|
|
37
|
+
constructor(node: string, resetAfterMs: number);
|
|
38
|
+
}
|
|
39
|
+
export declare class SwarmDeadlockError extends ONIError {
|
|
40
|
+
constructor(agents: string[]);
|
|
41
|
+
}
|
|
42
|
+
export declare class ModelRateLimitError extends ONIError {
|
|
43
|
+
constructor(provider: string, retryAfterMs?: number);
|
|
44
|
+
}
|
|
45
|
+
export declare class ModelContextLengthError extends ONIError {
|
|
46
|
+
constructor(provider: string, maxTokens: number);
|
|
47
|
+
}
|
|
48
|
+
export declare class CheckpointCorruptError extends ONIError {
|
|
49
|
+
constructor(threadId: string, detail: string);
|
|
50
|
+
}
|
|
51
|
+
export declare class StoreKeyNotFoundError extends ONIError {
|
|
52
|
+
constructor(namespace: string[], key: string);
|
|
53
|
+
}
|
|
19
54
|
/** Thrown at interrupt checkpoints — caught externally to pause/resume */
|
|
20
55
|
export declare class ONIInterrupt {
|
|
21
56
|
readonly node: string;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAIA,qBAAa,QAAS,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GACrB,OAAO,GACP,MAAM,GACN,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,MAAM,GACN,OAAO,GACP,OAAO,GACP,OAAO,GACP,QAAQ,CAAC;AAEb,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAID,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE9B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe;IAUnD,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAYlC;AAID,qBAAa,oBAAqB,SAAQ,QAAQ;gBACpC,GAAG,EAAE,MAAM;CAUxB;AAED,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,KAAK,EAAE,MAAM;CAa1B;AAED,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,IAAI,EAAE,MAAM;CAUzB;AAED,qBAAa,iBAAkB,SAAQ,QAAQ;gBACjC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAUrC;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CAWvC;AAID,qBAAa,gBAAiB,SAAQ,QAAQ;gBAChC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAU5C;AAED,qBAAa,uBAAwB,SAAQ,QAAQ;gBACvC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAa/C;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,MAAM,EAAE,MAAM,EAAE;CAa7B;AAED,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;CAapD;AAED,qBAAa,uBAAwB,SAAQ,QAAQ;gBACvC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAahD;AAED,qBAAa,sBAAuB,SAAQ,QAAQ;gBACtC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAU7C;AAED,qBAAa,qBAAsB,SAAQ,QAAQ;gBACrC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM;CAW7C;AAID,0EAA0E;AAC1E,qBAAa,YAAY;aAGL,IAAI,EAAI,MAAM;aACd,MAAM,EAAE,QAAQ,GAAG,OAAO;aAC1B,KAAK,EAAG,OAAO;IAJjC,QAAQ,CAAC,cAAc,QAAQ;gBAEb,IAAI,EAAI,MAAM,EACd,MAAM,EAAE,QAAQ,GAAG,OAAO,EAC1B,KAAK,EAAG,OAAO;CAElC"}
|