@cef-ai/cli 0.2.6 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -1247
- package/dist/build/duration.d.ts +22 -0
- package/dist/build/duration.d.ts.map +1 -0
- package/dist/build/duration.js +44 -0
- package/dist/build/duration.js.map +1 -0
- package/dist/build/esbuild-plugin.d.ts +32 -0
- package/dist/build/esbuild-plugin.d.ts.map +1 -0
- package/dist/build/esbuild-plugin.js +53 -0
- package/dist/build/esbuild-plugin.js.map +1 -0
- package/dist/build/lints.d.ts +55 -0
- package/dist/build/lints.d.ts.map +1 -0
- package/dist/build/lints.js +214 -0
- package/dist/build/lints.js.map +1 -0
- package/dist/build/load-config.d.ts +114 -0
- package/dist/build/load-config.d.ts.map +1 -0
- package/dist/build/load-config.js +150 -0
- package/dist/build/load-config.js.map +1 -0
- package/dist/build/manifest.d.ts +156 -0
- package/dist/build/manifest.d.ts.map +1 -0
- package/dist/build/manifest.js +111 -0
- package/dist/build/manifest.js.map +1 -0
- package/dist/build/targeting.d.ts +15 -0
- package/dist/build/targeting.d.ts.map +1 -0
- package/dist/build/targeting.js +69 -0
- package/dist/build/targeting.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +107 -62
- package/dist/cli.js.map +1 -0
- package/dist/commands/build.d.ts +41 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +252 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/inspect.d.ts +49 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +135 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/typegen.d.ts +36 -0
- package/dist/commands/typegen.d.ts.map +1 -0
- package/dist/commands/typegen.js +210 -0
- package/dist/commands/typegen.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +12 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +9 -0
- package/dist/lib.js.map +1 -0
- package/dist/typegen/augment.d.ts +57 -0
- package/dist/typegen/augment.d.ts.map +1 -0
- package/dist/typegen/augment.js +87 -0
- package/dist/typegen/augment.js.map +1 -0
- package/dist/typegen/fetch.d.ts +30 -0
- package/dist/typegen/fetch.d.ts.map +1 -0
- package/dist/typegen/fetch.js +38 -0
- package/dist/typegen/fetch.js.map +1 -0
- package/dist/typegen/lockfile.d.ts +42 -0
- package/dist/typegen/lockfile.d.ts.map +1 -0
- package/dist/typegen/lockfile.js +58 -0
- package/dist/typegen/lockfile.js.map +1 -0
- package/dist/typegen/schema-to-ts.d.ts +21 -0
- package/dist/typegen/schema-to-ts.d.ts.map +1 -0
- package/dist/typegen/schema-to-ts.js +29 -0
- package/dist/typegen/schema-to-ts.js.map +1 -0
- package/package.json +20 -58
- package/dist/commands/auth/index.d.ts +0 -2
- package/dist/commands/auth/index.js +0 -162
- package/dist/commands/deploy/clone.d.ts +0 -13
- package/dist/commands/deploy/clone.js +0 -143
- package/dist/commands/deploy/delete.d.ts +0 -14
- package/dist/commands/deploy/delete.js +0 -134
- package/dist/commands/deploy/deploy.d.ts +0 -24
- package/dist/commands/deploy/deploy.js +0 -654
- package/dist/commands/deploy/index.d.ts +0 -2
- package/dist/commands/deploy/index.js +0 -216
- package/dist/commands/deploy/status.d.ts +0 -14
- package/dist/commands/deploy/status.js +0 -61
- package/dist/commands/dev/index.d.ts +0 -2
- package/dist/commands/dev/index.js +0 -134
- package/dist/commands/dev/server.d.ts +0 -14
- package/dist/commands/dev/server.js +0 -195
- package/dist/commands/dev/static/app.js +0 -633
- package/dist/commands/dev/static/index.html +0 -205
- package/dist/commands/dev/static/static/app.js +0 -633
- package/dist/commands/dev/static/static/index.html +0 -205
- package/dist/commands/dev/static/static/style.css +0 -184
- package/dist/commands/dev/static/style.css +0 -184
- package/dist/commands/playground/index.d.ts +0 -2
- package/dist/commands/playground/index.js +0 -75
- package/dist/commands/playground/test.d.ts +0 -15
- package/dist/commands/playground/test.js +0 -166
- package/dist/commands/service/index.d.ts +0 -2
- package/dist/commands/service/index.js +0 -75
- package/dist/lib/api.d.ts +0 -146
- package/dist/lib/api.js +0 -330
- package/dist/lib/config.d.ts +0 -12
- package/dist/lib/config.js +0 -145
- package/dist/lib/credentials.d.ts +0 -19
- package/dist/lib/credentials.js +0 -68
- package/dist/lib/runtime/agent-router.d.ts +0 -12
- package/dist/lib/runtime/agent-router.js +0 -67
- package/dist/lib/runtime/context-builder.d.ts +0 -27
- package/dist/lib/runtime/context-builder.js +0 -166
- package/dist/lib/runtime/cubby-manager.d.ts +0 -20
- package/dist/lib/runtime/cubby-manager.js +0 -162
- package/dist/lib/runtime/index.d.ts +0 -51
- package/dist/lib/runtime/index.js +0 -181
- package/dist/lib/runtime/log-collector.d.ts +0 -17
- package/dist/lib/runtime/log-collector.js +0 -61
- package/dist/lib/runtime/stream-manager.d.ts +0 -10
- package/dist/lib/runtime/stream-manager.js +0 -77
- package/dist/lib/runtime/types.d.ts +0 -76
- package/dist/lib/runtime/types.js +0 -2
- package/dist/lib/transpile.d.ts +0 -1
- package/dist/lib/transpile.js +0 -9
- package/dist/lib/typecheck.d.ts +0 -31
- package/dist/lib/typecheck.js +0 -175
- package/dist/lib/types.d.ts +0 -246
- package/dist/lib/types.js +0 -2
- package/dist/lib/utils.d.ts +0 -4
- package/dist/lib/utils.js +0 -33
- package/example/.env.example +0 -6
- package/example/agents/object-detection/tasks/yolo.ts +0 -28
- package/example/agents/parking-violation-detector/tasks/detect.ts +0 -326
- package/example/cef.config.yaml +0 -91
- package/example/engagements/engagement.ts +0 -902
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Builds the context object injected into agent/engagement V8 sandboxes.
|
|
3
|
-
*
|
|
4
|
-
* This is THE single source of truth for the Context API shape.
|
|
5
|
-
* When the platform API changes, update this file.
|
|
6
|
-
*
|
|
7
|
-
* Properties are grouped into:
|
|
8
|
-
* 1. Typed properties (from typecheck.ts Context interface)
|
|
9
|
-
* 2. Non-typed extensions (in platform docs but not in typecheck.ts)
|
|
10
|
-
*/
|
|
11
|
-
export function buildContext(opts) {
|
|
12
|
-
const { executionId, logCollector, agentRouter, cubbyManager, streamManager, workspaceId, agentServiceId, agentAlias, taskAlias, callerLabel, } = opts;
|
|
13
|
-
const currentLabel = agentAlias && taskAlias
|
|
14
|
-
? `${agentAlias}.${taskAlias}`
|
|
15
|
-
: callerLabel ?? 'engagement';
|
|
16
|
-
// ─── Typed properties (from typecheck.ts Context interface) ───────────
|
|
17
|
-
const log = (...args) => {
|
|
18
|
-
logCollector.add(executionId, 'log', args, agentAlias, taskAlias);
|
|
19
|
-
};
|
|
20
|
-
const warn = (...args) => {
|
|
21
|
-
logCollector.add(executionId, 'warn', args, agentAlias, taskAlias);
|
|
22
|
-
};
|
|
23
|
-
const error = (...args) => {
|
|
24
|
-
logCollector.add(executionId, 'error', args, agentAlias, taskAlias);
|
|
25
|
-
};
|
|
26
|
-
const emit = (eventType, payload, _targetId) => {
|
|
27
|
-
logCollector.add(executionId, 'log', ['[emit]', eventType, payload], agentAlias, taskAlias);
|
|
28
|
-
};
|
|
29
|
-
// Agents proxy: context.agents.{alias}.{task}(payload)
|
|
30
|
-
// Wrapped with trace events for execution flow tracking
|
|
31
|
-
const agents = new Proxy({}, {
|
|
32
|
-
get(_, targetAgentAlias) {
|
|
33
|
-
return new Proxy({}, {
|
|
34
|
-
get(_, targetTaskAlias) {
|
|
35
|
-
return async (payload) => {
|
|
36
|
-
const calleeLabel = `${targetAgentAlias}.${targetTaskAlias}`;
|
|
37
|
-
logCollector.emitTrace({
|
|
38
|
-
timestamp: Date.now(),
|
|
39
|
-
executionId,
|
|
40
|
-
type: 'agent:call',
|
|
41
|
-
caller: currentLabel,
|
|
42
|
-
callee: calleeLabel,
|
|
43
|
-
});
|
|
44
|
-
const start = performance.now();
|
|
45
|
-
try {
|
|
46
|
-
const childContext = buildContext({
|
|
47
|
-
...opts,
|
|
48
|
-
agentAlias: targetAgentAlias,
|
|
49
|
-
taskAlias: targetTaskAlias,
|
|
50
|
-
callerLabel: currentLabel,
|
|
51
|
-
});
|
|
52
|
-
const result = await agentRouter.call(targetAgentAlias, targetTaskAlias, payload, childContext);
|
|
53
|
-
logCollector.emitTrace({
|
|
54
|
-
timestamp: Date.now(),
|
|
55
|
-
executionId,
|
|
56
|
-
type: 'agent:return',
|
|
57
|
-
caller: currentLabel,
|
|
58
|
-
callee: calleeLabel,
|
|
59
|
-
durationMs: performance.now() - start,
|
|
60
|
-
success: true,
|
|
61
|
-
});
|
|
62
|
-
return result;
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
logCollector.emitTrace({
|
|
66
|
-
timestamp: Date.now(),
|
|
67
|
-
executionId,
|
|
68
|
-
type: 'agent:return',
|
|
69
|
-
caller: currentLabel,
|
|
70
|
-
callee: calleeLabel,
|
|
71
|
-
durationMs: performance.now() - start,
|
|
72
|
-
success: false,
|
|
73
|
-
error: err.message,
|
|
74
|
-
});
|
|
75
|
-
throw err;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
// Cubbies proxy: context.cubbies.{alias}.query/exec
|
|
83
|
-
// Wrapped with trace events
|
|
84
|
-
const cubbies = new Proxy({}, {
|
|
85
|
-
get(_, alias) {
|
|
86
|
-
return {
|
|
87
|
-
query: async (...args) => {
|
|
88
|
-
const resolved = resolveOverloadedArgs(args);
|
|
89
|
-
logCollector.emitTrace({
|
|
90
|
-
timestamp: Date.now(),
|
|
91
|
-
executionId,
|
|
92
|
-
type: 'cubby:query',
|
|
93
|
-
caller: currentLabel,
|
|
94
|
-
cubbyAlias: alias,
|
|
95
|
-
sql: truncate(resolved.sql, 100),
|
|
96
|
-
});
|
|
97
|
-
const result = await cubbyManager.queryOverloaded(alias, args);
|
|
98
|
-
return result;
|
|
99
|
-
},
|
|
100
|
-
exec: async (...args) => {
|
|
101
|
-
const resolved = resolveOverloadedArgs(args);
|
|
102
|
-
const result = await cubbyManager.execOverloaded(alias, args);
|
|
103
|
-
logCollector.emitTrace({
|
|
104
|
-
timestamp: Date.now(),
|
|
105
|
-
executionId,
|
|
106
|
-
type: 'cubby:exec',
|
|
107
|
-
caller: currentLabel,
|
|
108
|
-
cubbyAlias: alias,
|
|
109
|
-
sql: truncate(resolved.sql, 100),
|
|
110
|
-
rowsAffected: result.rowsAffected,
|
|
111
|
-
});
|
|
112
|
-
return result;
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
},
|
|
116
|
-
});
|
|
117
|
-
// Streams
|
|
118
|
-
const streams = {
|
|
119
|
-
subscribe: async (streamId) => {
|
|
120
|
-
return streamManager.getStream(streamId);
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
// Rafts stub
|
|
124
|
-
const rafts = new Proxy({}, {
|
|
125
|
-
get(_, alias) {
|
|
126
|
-
return {
|
|
127
|
-
query: async () => {
|
|
128
|
-
throw new Error(`Raft queries not available in local dev mode (raft alias: "${alias}")`);
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
// ─── Non-typed extensions (platform docs, not in typecheck.ts) ────────
|
|
134
|
-
const workspace = {
|
|
135
|
-
id: workspaceId,
|
|
136
|
-
agentServiceId,
|
|
137
|
-
};
|
|
138
|
-
return {
|
|
139
|
-
// Typed properties (must match typecheck.ts Context interface)
|
|
140
|
-
fetch: globalThis.fetch,
|
|
141
|
-
emit,
|
|
142
|
-
log,
|
|
143
|
-
warn,
|
|
144
|
-
error,
|
|
145
|
-
streams,
|
|
146
|
-
cubbies,
|
|
147
|
-
agents,
|
|
148
|
-
rafts,
|
|
149
|
-
// Non-typed extensions
|
|
150
|
-
workspace,
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
// Extract SQL from overloaded cubby args for trace display
|
|
154
|
-
function resolveOverloadedArgs(args) {
|
|
155
|
-
const first = args[0];
|
|
156
|
-
if (typeof first === 'string' && first.includes(' ')) {
|
|
157
|
-
return { sql: first };
|
|
158
|
-
}
|
|
159
|
-
if (typeof args[1] === 'string') {
|
|
160
|
-
return { sql: args[1] };
|
|
161
|
-
}
|
|
162
|
-
return { sql: '(unknown)' };
|
|
163
|
-
}
|
|
164
|
-
function truncate(s, max) {
|
|
165
|
-
return s.length > max ? s.slice(0, max) + '...' : s;
|
|
166
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { CubbyConfig } from '../types.js';
|
|
2
|
-
import type { QueryResult, ExecResult } from './types.js';
|
|
3
|
-
export declare class CubbyManager {
|
|
4
|
-
private dataDir;
|
|
5
|
-
private definitions;
|
|
6
|
-
private instances;
|
|
7
|
-
constructor(dataDir: string);
|
|
8
|
-
initialize(cubbies: CubbyConfig[]): Promise<void>;
|
|
9
|
-
getAliases(): string[];
|
|
10
|
-
query(alias: string, instanceId: string, sql: string, params: unknown[]): Promise<QueryResult>;
|
|
11
|
-
exec(alias: string, instanceId: string, sql: string, params: unknown[]): Promise<ExecResult>;
|
|
12
|
-
queryOverloaded(alias: string, args: unknown[]): Promise<QueryResult>;
|
|
13
|
-
execOverloaded(alias: string, args: unknown[]): Promise<ExecResult>;
|
|
14
|
-
listInstances(alias: string): string[];
|
|
15
|
-
shutdown(): void;
|
|
16
|
-
private resolveOverload;
|
|
17
|
-
private getOrCreateInstance;
|
|
18
|
-
private applyMigrations;
|
|
19
|
-
private getDbPath;
|
|
20
|
-
}
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import Database from 'better-sqlite3';
|
|
2
|
-
import * as sqliteVec from 'sqlite-vec';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
export class CubbyManager {
|
|
6
|
-
dataDir;
|
|
7
|
-
definitions = new Map();
|
|
8
|
-
instances = new Map(); // key: alias/instanceId
|
|
9
|
-
constructor(dataDir) {
|
|
10
|
-
this.dataDir = dataDir;
|
|
11
|
-
}
|
|
12
|
-
async initialize(cubbies) {
|
|
13
|
-
for (const cubby of cubbies) {
|
|
14
|
-
this.definitions.set(cubby.alias, {
|
|
15
|
-
alias: cubby.alias,
|
|
16
|
-
migrations: cubby.migrations ?? [],
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
getAliases() {
|
|
21
|
-
return [...this.definitions.keys()];
|
|
22
|
-
}
|
|
23
|
-
async query(alias, instanceId, sql, params) {
|
|
24
|
-
const db = this.getOrCreateInstance(alias, instanceId);
|
|
25
|
-
const start = performance.now();
|
|
26
|
-
try {
|
|
27
|
-
const stmt = db.prepare(sql);
|
|
28
|
-
const columns = stmt.columns().map(c => c.name);
|
|
29
|
-
const rawRows = stmt.raw().all(...params);
|
|
30
|
-
const rows = rawRows.length === 0 ? null : rawRows;
|
|
31
|
-
const duration = (performance.now() - start) / 1000;
|
|
32
|
-
return { columns, rows, meta: { duration, rowsRead: rawRows.length } };
|
|
33
|
-
}
|
|
34
|
-
catch (err) {
|
|
35
|
-
throw new Error(`Cubby "${alias}" query error: ${err.message}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async exec(alias, instanceId, sql, params) {
|
|
39
|
-
const db = this.getOrCreateInstance(alias, instanceId);
|
|
40
|
-
const start = performance.now();
|
|
41
|
-
try {
|
|
42
|
-
const result = db.prepare(sql).run(...params);
|
|
43
|
-
const duration = (performance.now() - start) / 1000;
|
|
44
|
-
return {
|
|
45
|
-
rowsAffected: result.changes,
|
|
46
|
-
lastInsertId: Number(result.lastInsertRowid),
|
|
47
|
-
meta: { duration, rowsRead: 0 },
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
throw new Error(`Cubby "${alias}" exec error: ${err.message}`);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// Overloaded signature resolver matching production heuristic
|
|
55
|
-
async queryOverloaded(alias, args) {
|
|
56
|
-
const { instanceId, sql, params } = this.resolveOverload(args);
|
|
57
|
-
return this.query(alias, instanceId, sql, params);
|
|
58
|
-
}
|
|
59
|
-
async execOverloaded(alias, args) {
|
|
60
|
-
const { instanceId, sql, params } = this.resolveOverload(args);
|
|
61
|
-
return this.exec(alias, instanceId, sql, params);
|
|
62
|
-
}
|
|
63
|
-
listInstances(alias) {
|
|
64
|
-
const prefix = `${alias}/`;
|
|
65
|
-
const instances = [];
|
|
66
|
-
for (const key of this.instances.keys()) {
|
|
67
|
-
if (key.startsWith(prefix)) {
|
|
68
|
-
instances.push(key.slice(prefix.length));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return instances;
|
|
72
|
-
}
|
|
73
|
-
shutdown() {
|
|
74
|
-
for (const db of this.instances.values()) {
|
|
75
|
-
try {
|
|
76
|
-
db.close();
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
// best effort
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
this.instances.clear();
|
|
83
|
-
}
|
|
84
|
-
resolveOverload(args) {
|
|
85
|
-
const first = args[0];
|
|
86
|
-
if (typeof first !== 'string') {
|
|
87
|
-
throw new Error('First argument must be a string (SQL or instanceId)');
|
|
88
|
-
}
|
|
89
|
-
// Heuristic: if first arg contains a space, it is SQL
|
|
90
|
-
if (first.includes(' ')) {
|
|
91
|
-
const sql = first;
|
|
92
|
-
const params = Array.isArray(args[1]) ? args[1] : [];
|
|
93
|
-
return { instanceId: 'default', sql, params };
|
|
94
|
-
}
|
|
95
|
-
// First arg is instanceId
|
|
96
|
-
const instanceId = first;
|
|
97
|
-
const sql = args[1];
|
|
98
|
-
if (typeof sql !== 'string') {
|
|
99
|
-
throw new Error('Second argument must be SQL string when first is instanceId');
|
|
100
|
-
}
|
|
101
|
-
const params = Array.isArray(args[2]) ? args[2] : [];
|
|
102
|
-
return { instanceId, sql, params };
|
|
103
|
-
}
|
|
104
|
-
getOrCreateInstance(alias, instanceId) {
|
|
105
|
-
const def = this.definitions.get(alias);
|
|
106
|
-
if (!def) {
|
|
107
|
-
throw new Error(`Cubby "${alias}" not defined in config`);
|
|
108
|
-
}
|
|
109
|
-
const key = `${alias}/${instanceId}`;
|
|
110
|
-
if (this.instances.has(key)) {
|
|
111
|
-
return this.instances.get(key);
|
|
112
|
-
}
|
|
113
|
-
const dbPath = this.getDbPath(alias, instanceId);
|
|
114
|
-
const dbDir = path.dirname(dbPath);
|
|
115
|
-
fs.mkdirSync(dbDir, { recursive: true });
|
|
116
|
-
const db = new Database(dbPath);
|
|
117
|
-
// Load sqlite-vec extension for vector operations
|
|
118
|
-
sqliteVec.load(db);
|
|
119
|
-
// Apply PRAGMAs
|
|
120
|
-
db.pragma('cache_size = -64000');
|
|
121
|
-
db.pragma('temp_store = MEMORY');
|
|
122
|
-
db.pragma('busy_timeout = 5000');
|
|
123
|
-
db.pragma('journal_mode = WAL');
|
|
124
|
-
db.pragma('synchronous = NORMAL');
|
|
125
|
-
// Apply migrations
|
|
126
|
-
this.applyMigrations(db, def.migrations);
|
|
127
|
-
this.instances.set(key, db);
|
|
128
|
-
return db;
|
|
129
|
-
}
|
|
130
|
-
applyMigrations(db, migrations) {
|
|
131
|
-
// Create tracking table
|
|
132
|
-
db.exec(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
133
|
-
version INTEGER PRIMARY KEY,
|
|
134
|
-
applied_at TEXT DEFAULT (datetime('now'))
|
|
135
|
-
)`);
|
|
136
|
-
// Get applied versions
|
|
137
|
-
const applied = new Set();
|
|
138
|
-
const rows = db.prepare('SELECT version FROM schema_migrations').all();
|
|
139
|
-
for (const row of rows) {
|
|
140
|
-
applied.add(row.version);
|
|
141
|
-
}
|
|
142
|
-
// Apply pending migrations in order
|
|
143
|
-
const sorted = [...migrations].sort((a, b) => a.version - b.version);
|
|
144
|
-
for (const migration of sorted) {
|
|
145
|
-
if (applied.has(migration.version))
|
|
146
|
-
continue;
|
|
147
|
-
const transaction = db.transaction(() => {
|
|
148
|
-
db.exec(migration.up);
|
|
149
|
-
db.prepare('INSERT INTO schema_migrations (version) VALUES (?)').run(migration.version);
|
|
150
|
-
});
|
|
151
|
-
try {
|
|
152
|
-
transaction();
|
|
153
|
-
}
|
|
154
|
-
catch (err) {
|
|
155
|
-
throw new Error(`Migration v${migration.version} failed for cubby: ${err.message}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
getDbPath(alias, instanceId) {
|
|
160
|
-
return path.join(this.dataDir, alias, `${instanceId}.db`);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { CefConfig } from '../types.js';
|
|
2
|
-
import type { LogEntry, AgentCallResult, QueryResult, ExecResult, EngagementHandle } from './types.js';
|
|
3
|
-
import { LogCollector } from './log-collector.js';
|
|
4
|
-
export declare class LocalRuntime {
|
|
5
|
-
private config;
|
|
6
|
-
private logCollector;
|
|
7
|
-
private agentRouter;
|
|
8
|
-
private cubbyManager;
|
|
9
|
-
private streamManager;
|
|
10
|
-
private activeEngagements;
|
|
11
|
-
constructor(dataDir: string);
|
|
12
|
-
initialize(config: CefConfig): Promise<void>;
|
|
13
|
-
callAgentTask(agentAlias: string, taskAlias: string, payload: unknown): Promise<AgentCallResult>;
|
|
14
|
-
startEngagement(name: string, payload: Record<string, unknown>): Promise<EngagementHandle>;
|
|
15
|
-
pushToStream(streamId: string, packet: import('./types.js').StreamPacket): void;
|
|
16
|
-
queryCubby(alias: string, instanceId: string, sql: string, params: unknown[]): Promise<QueryResult>;
|
|
17
|
-
execCubby(alias: string, instanceId: string, sql: string, params: unknown[]): Promise<ExecResult>;
|
|
18
|
-
listCubbyInstances(alias: string): string[];
|
|
19
|
-
getLogs(executionId?: string): LogEntry[];
|
|
20
|
-
getTopology(): {
|
|
21
|
-
agents: {
|
|
22
|
-
name: string;
|
|
23
|
-
alias: string;
|
|
24
|
-
tasks: {
|
|
25
|
-
name: string;
|
|
26
|
-
alias: string;
|
|
27
|
-
parameters: Record<string, unknown> | undefined;
|
|
28
|
-
returns: Record<string, unknown> | undefined;
|
|
29
|
-
batchSql: string | null;
|
|
30
|
-
batchCubby: string | null;
|
|
31
|
-
}[];
|
|
32
|
-
}[];
|
|
33
|
-
cubbies: {
|
|
34
|
-
alias: string;
|
|
35
|
-
name: string;
|
|
36
|
-
migrations: number;
|
|
37
|
-
}[];
|
|
38
|
-
engagements: {
|
|
39
|
-
name: string;
|
|
40
|
-
parameters: Record<string, unknown> | undefined;
|
|
41
|
-
}[];
|
|
42
|
-
workspaces: {
|
|
43
|
-
name: string;
|
|
44
|
-
workspaceId: string | undefined;
|
|
45
|
-
}[];
|
|
46
|
-
};
|
|
47
|
-
reloadFile(agentAlias: string, taskAlias: string, tsCode: string): void;
|
|
48
|
-
get logEmitter(): LogCollector;
|
|
49
|
-
shutdown(): void;
|
|
50
|
-
private buildContextForExecution;
|
|
51
|
-
}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import vm from 'vm';
|
|
2
|
-
import { transpileTypeScript } from '../transpile.js';
|
|
3
|
-
import { LogCollector } from './log-collector.js';
|
|
4
|
-
import { AgentRouter } from './agent-router.js';
|
|
5
|
-
import { CubbyManager } from './cubby-manager.js';
|
|
6
|
-
import { StreamManager } from './stream-manager.js';
|
|
7
|
-
import { buildContext } from './context-builder.js';
|
|
8
|
-
let executionCounter = 0;
|
|
9
|
-
function nextExecutionId() {
|
|
10
|
-
return `exec-${++executionCounter}-${Date.now()}`;
|
|
11
|
-
}
|
|
12
|
-
export class LocalRuntime {
|
|
13
|
-
config;
|
|
14
|
-
logCollector;
|
|
15
|
-
agentRouter;
|
|
16
|
-
cubbyManager;
|
|
17
|
-
streamManager;
|
|
18
|
-
activeEngagements = new Map();
|
|
19
|
-
constructor(dataDir) {
|
|
20
|
-
this.logCollector = new LogCollector();
|
|
21
|
-
this.agentRouter = new AgentRouter();
|
|
22
|
-
this.cubbyManager = new CubbyManager(dataDir);
|
|
23
|
-
this.streamManager = new StreamManager();
|
|
24
|
-
}
|
|
25
|
-
async initialize(config) {
|
|
26
|
-
this.config = config;
|
|
27
|
-
if (config.agents) {
|
|
28
|
-
this.agentRouter.loadAgents(config.agents);
|
|
29
|
-
}
|
|
30
|
-
if (config.cubbies) {
|
|
31
|
-
await this.cubbyManager.initialize(config.cubbies);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
async callAgentTask(agentAlias, taskAlias, payload) {
|
|
35
|
-
const executionId = nextExecutionId();
|
|
36
|
-
const start = performance.now();
|
|
37
|
-
try {
|
|
38
|
-
const context = this.buildContextForExecution(executionId, agentAlias, taskAlias);
|
|
39
|
-
const result = await this.agentRouter.call(agentAlias, taskAlias, payload, context);
|
|
40
|
-
return {
|
|
41
|
-
success: true,
|
|
42
|
-
result,
|
|
43
|
-
durationMs: performance.now() - start,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
catch (err) {
|
|
47
|
-
return {
|
|
48
|
-
success: false,
|
|
49
|
-
error: err.message,
|
|
50
|
-
durationMs: performance.now() - start,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
async startEngagement(name, payload) {
|
|
55
|
-
const engagement = this.config.engagements?.find(e => e.name === name);
|
|
56
|
-
if (!engagement) {
|
|
57
|
-
throw new Error(`Engagement "${name}" not found`);
|
|
58
|
-
}
|
|
59
|
-
const executionId = nextExecutionId();
|
|
60
|
-
const streamId = payload.streamId ?? `local-stream-${executionId}`;
|
|
61
|
-
// Create a stream for this engagement
|
|
62
|
-
const stream = this.streamManager.createStream(streamId);
|
|
63
|
-
this.logCollector.emitTrace({
|
|
64
|
-
timestamp: Date.now(),
|
|
65
|
-
executionId,
|
|
66
|
-
type: 'engagement:start',
|
|
67
|
-
callee: name,
|
|
68
|
-
});
|
|
69
|
-
const context = this.buildContextForExecution(executionId, undefined, undefined);
|
|
70
|
-
// Transpile and run engagement code in the background
|
|
71
|
-
const jsCode = transpileTypeScript(engagement.tsCode ?? '');
|
|
72
|
-
const event = { payload: { ...payload, streamId } };
|
|
73
|
-
const sandbox = {
|
|
74
|
-
event,
|
|
75
|
-
context,
|
|
76
|
-
console: { log: context.log, warn: context.warn, error: context.error },
|
|
77
|
-
TextDecoder,
|
|
78
|
-
TextEncoder,
|
|
79
|
-
JSON,
|
|
80
|
-
Promise,
|
|
81
|
-
Uint8Array,
|
|
82
|
-
};
|
|
83
|
-
const wrappedCode = `
|
|
84
|
-
${jsCode}
|
|
85
|
-
__result__ = handle(event, context);
|
|
86
|
-
`;
|
|
87
|
-
const vmContext = vm.createContext(sandbox);
|
|
88
|
-
vm.runInContext(wrappedCode, vmContext);
|
|
89
|
-
// The handle function is now running asynchronously (processing the stream)
|
|
90
|
-
const handlePromise = sandbox.__result__;
|
|
91
|
-
// Catch errors from the engagement
|
|
92
|
-
handlePromise.catch((err) => {
|
|
93
|
-
this.logCollector.add(executionId, 'error', [`Engagement "${name}" error: ${err.message}`]);
|
|
94
|
-
});
|
|
95
|
-
const handle = {
|
|
96
|
-
executionId,
|
|
97
|
-
pushPacket: (data) => {
|
|
98
|
-
stream.push(data);
|
|
99
|
-
},
|
|
100
|
-
stop: () => {
|
|
101
|
-
stream.end();
|
|
102
|
-
this.streamManager.removeStream(streamId);
|
|
103
|
-
this.activeEngagements.delete(executionId);
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
this.activeEngagements.set(executionId, handle);
|
|
107
|
-
return handle;
|
|
108
|
-
}
|
|
109
|
-
pushToStream(streamId, packet) {
|
|
110
|
-
this.streamManager.pushToStream(streamId, packet);
|
|
111
|
-
}
|
|
112
|
-
async queryCubby(alias, instanceId, sql, params) {
|
|
113
|
-
return this.cubbyManager.query(alias, instanceId, sql, params);
|
|
114
|
-
}
|
|
115
|
-
async execCubby(alias, instanceId, sql, params) {
|
|
116
|
-
return this.cubbyManager.exec(alias, instanceId, sql, params);
|
|
117
|
-
}
|
|
118
|
-
listCubbyInstances(alias) {
|
|
119
|
-
return this.cubbyManager.listInstances(alias);
|
|
120
|
-
}
|
|
121
|
-
getLogs(executionId) {
|
|
122
|
-
if (executionId) {
|
|
123
|
-
return this.logCollector.getLogs(executionId);
|
|
124
|
-
}
|
|
125
|
-
// Return all logs from all executions
|
|
126
|
-
const all = [];
|
|
127
|
-
for (const id of this.logCollector.getRecentExecutions()) {
|
|
128
|
-
all.push(...this.logCollector.getLogs(id));
|
|
129
|
-
}
|
|
130
|
-
return all;
|
|
131
|
-
}
|
|
132
|
-
getTopology() {
|
|
133
|
-
return {
|
|
134
|
-
agents: (this.config.agents ?? []).map(a => ({
|
|
135
|
-
name: a.name,
|
|
136
|
-
alias: a.alias,
|
|
137
|
-
tasks: a.tasks.map(t => ({ name: t.name, alias: t.alias, parameters: t.parameters, returns: t.returns, batchSql: t.batchSql ?? null, batchCubby: t.batch_cubby ?? null })),
|
|
138
|
-
})),
|
|
139
|
-
cubbies: (this.config.cubbies ?? []).map(c => ({
|
|
140
|
-
alias: c.alias,
|
|
141
|
-
name: c.name,
|
|
142
|
-
migrations: c.migrations?.length ?? 0,
|
|
143
|
-
})),
|
|
144
|
-
engagements: (this.config.engagements ?? []).map(e => ({
|
|
145
|
-
name: e.name,
|
|
146
|
-
parameters: e.parameters,
|
|
147
|
-
})),
|
|
148
|
-
workspaces: (this.config.workspaces ?? []).map(w => ({
|
|
149
|
-
name: w.name,
|
|
150
|
-
workspaceId: w.workspaceId,
|
|
151
|
-
})),
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
reloadFile(agentAlias, taskAlias, tsCode) {
|
|
155
|
-
this.agentRouter.reloadTask(agentAlias, taskAlias, tsCode);
|
|
156
|
-
}
|
|
157
|
-
get logEmitter() {
|
|
158
|
-
return this.logCollector;
|
|
159
|
-
}
|
|
160
|
-
shutdown() {
|
|
161
|
-
for (const handle of this.activeEngagements.values()) {
|
|
162
|
-
handle.stop();
|
|
163
|
-
}
|
|
164
|
-
this.activeEngagements.clear();
|
|
165
|
-
this.streamManager.shutdown();
|
|
166
|
-
this.cubbyManager.shutdown();
|
|
167
|
-
}
|
|
168
|
-
buildContextForExecution(executionId, agentAlias, taskAlias) {
|
|
169
|
-
return buildContext({
|
|
170
|
-
executionId,
|
|
171
|
-
logCollector: this.logCollector,
|
|
172
|
-
agentRouter: this.agentRouter,
|
|
173
|
-
cubbyManager: this.cubbyManager,
|
|
174
|
-
streamManager: this.streamManager,
|
|
175
|
-
workspaceId: this.config.workspaces?.[0]?.workspaceId ?? 'local-ws',
|
|
176
|
-
agentServiceId: this.config.agentServicePubKey,
|
|
177
|
-
agentAlias,
|
|
178
|
-
taskAlias,
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'events';
|
|
2
|
-
import type { LogEntry, TraceEvent } from './types.js';
|
|
3
|
-
export declare class LogCollector extends EventEmitter {
|
|
4
|
-
private logs;
|
|
5
|
-
private traces;
|
|
6
|
-
private executionOrder;
|
|
7
|
-
private maxExecutions;
|
|
8
|
-
constructor(maxExecutions?: number);
|
|
9
|
-
add(executionId: string, level: LogEntry['level'], args: unknown[], agentAlias?: string, taskAlias?: string): void;
|
|
10
|
-
getLogs(executionId: string): LogEntry[];
|
|
11
|
-
getRecentExecutions(): string[];
|
|
12
|
-
emitTrace(event: TraceEvent): void;
|
|
13
|
-
getTraces(executionId: string): TraceEvent[];
|
|
14
|
-
clear(executionId: string): void;
|
|
15
|
-
clearAll(): void;
|
|
16
|
-
private evict;
|
|
17
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from 'events';
|
|
2
|
-
export class LogCollector extends EventEmitter {
|
|
3
|
-
logs = new Map();
|
|
4
|
-
traces = new Map();
|
|
5
|
-
executionOrder = [];
|
|
6
|
-
maxExecutions;
|
|
7
|
-
constructor(maxExecutions = 100) {
|
|
8
|
-
super();
|
|
9
|
-
this.maxExecutions = maxExecutions;
|
|
10
|
-
}
|
|
11
|
-
add(executionId, level, args, agentAlias, taskAlias) {
|
|
12
|
-
const entry = {
|
|
13
|
-
timestamp: Date.now(),
|
|
14
|
-
executionId,
|
|
15
|
-
level,
|
|
16
|
-
args,
|
|
17
|
-
agentAlias,
|
|
18
|
-
taskAlias,
|
|
19
|
-
};
|
|
20
|
-
if (!this.logs.has(executionId)) {
|
|
21
|
-
this.logs.set(executionId, []);
|
|
22
|
-
this.executionOrder.push(executionId);
|
|
23
|
-
this.evict();
|
|
24
|
-
}
|
|
25
|
-
this.logs.get(executionId).push(entry);
|
|
26
|
-
this.emit('log', entry);
|
|
27
|
-
}
|
|
28
|
-
getLogs(executionId) {
|
|
29
|
-
return this.logs.get(executionId) ?? [];
|
|
30
|
-
}
|
|
31
|
-
getRecentExecutions() {
|
|
32
|
-
return [...this.executionOrder];
|
|
33
|
-
}
|
|
34
|
-
emitTrace(event) {
|
|
35
|
-
const { executionId } = event;
|
|
36
|
-
if (!this.traces.has(executionId)) {
|
|
37
|
-
this.traces.set(executionId, []);
|
|
38
|
-
}
|
|
39
|
-
this.traces.get(executionId).push(event);
|
|
40
|
-
this.emit('trace', event);
|
|
41
|
-
}
|
|
42
|
-
getTraces(executionId) {
|
|
43
|
-
return this.traces.get(executionId) ?? [];
|
|
44
|
-
}
|
|
45
|
-
clear(executionId) {
|
|
46
|
-
this.logs.delete(executionId);
|
|
47
|
-
this.traces.delete(executionId);
|
|
48
|
-
this.executionOrder = this.executionOrder.filter(id => id !== executionId);
|
|
49
|
-
}
|
|
50
|
-
clearAll() {
|
|
51
|
-
this.logs.clear();
|
|
52
|
-
this.traces.clear();
|
|
53
|
-
this.executionOrder = [];
|
|
54
|
-
}
|
|
55
|
-
evict() {
|
|
56
|
-
while (this.executionOrder.length > this.maxExecutions) {
|
|
57
|
-
const oldest = this.executionOrder.shift();
|
|
58
|
-
this.logs.delete(oldest);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { StreamPacket, PushableStream } from './types.js';
|
|
2
|
-
export declare class StreamManager {
|
|
3
|
-
private streams;
|
|
4
|
-
createStream(streamId: string): PushableStream;
|
|
5
|
-
getStream(streamId: string): PushableStream;
|
|
6
|
-
pushToStream(streamId: string, packet: StreamPacket): void;
|
|
7
|
-
hasStream(streamId: string): boolean;
|
|
8
|
-
removeStream(streamId: string): void;
|
|
9
|
-
shutdown(): void;
|
|
10
|
-
}
|