agentenkit 0.3.0 → 0.5.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 +82 -15
- package/dist/adapters/brave.d.ts +21 -0
- package/dist/adapters/brave.d.ts.map +1 -0
- package/dist/adapters/brave.js +52 -0
- package/dist/adapters/brave.js.map +1 -0
- package/dist/adapters/computesdk.d.ts +71 -0
- package/dist/adapters/computesdk.d.ts.map +1 -0
- package/dist/adapters/computesdk.js +163 -0
- package/dist/adapters/computesdk.js.map +1 -0
- package/dist/adapters/docker.d.ts +35 -0
- package/dist/adapters/docker.d.ts.map +1 -0
- package/dist/adapters/docker.js +246 -0
- package/dist/adapters/docker.js.map +1 -0
- package/dist/adapters/e2b.d.ts +44 -0
- package/dist/adapters/e2b.d.ts.map +1 -0
- package/dist/adapters/e2b.js +349 -0
- package/dist/adapters/e2b.js.map +1 -0
- package/dist/adapters/inline.d.ts +19 -5
- package/dist/adapters/inline.d.ts.map +1 -1
- package/dist/adapters/inline.js +87 -14
- package/dist/adapters/inline.js.map +1 -1
- package/dist/adapters/jina.d.ts +34 -0
- package/dist/adapters/jina.d.ts.map +1 -0
- package/dist/adapters/jina.js +99 -0
- package/dist/adapters/jina.js.map +1 -0
- package/dist/adapters/local-sandbox.d.ts +32 -0
- package/dist/adapters/local-sandbox.d.ts.map +1 -0
- package/dist/adapters/local-sandbox.js +257 -0
- package/dist/adapters/local-sandbox.js.map +1 -0
- package/dist/adapters/memory.d.ts +146 -3
- package/dist/adapters/memory.d.ts.map +1 -1
- package/dist/adapters/memory.js +474 -3
- package/dist/adapters/memory.js.map +1 -1
- package/dist/adapters/page-reader.d.ts +39 -0
- package/dist/adapters/page-reader.d.ts.map +1 -0
- package/dist/adapters/page-reader.js +165 -0
- package/dist/adapters/page-reader.js.map +1 -0
- package/dist/adapters/prisma.d.ts +125 -18
- package/dist/adapters/prisma.d.ts.map +1 -1
- package/dist/adapters/prisma.js +308 -67
- package/dist/adapters/prisma.js.map +1 -1
- package/dist/adapters/qstash.d.ts +15 -2
- package/dist/adapters/qstash.d.ts.map +1 -1
- package/dist/adapters/qstash.js +31 -14
- package/dist/adapters/qstash.js.map +1 -1
- package/dist/adapters/redis.d.ts +40 -4
- package/dist/adapters/redis.d.ts.map +1 -1
- package/dist/adapters/redis.js +265 -20
- package/dist/adapters/redis.js.map +1 -1
- package/dist/adapters/sandbox-shell.d.ts +60 -0
- package/dist/adapters/sandbox-shell.d.ts.map +1 -0
- package/dist/adapters/sandbox-shell.js +129 -0
- package/dist/adapters/sandbox-shell.js.map +1 -0
- package/dist/adapters/sqlite.d.ts +88 -2
- package/dist/adapters/sqlite.d.ts.map +1 -1
- package/dist/adapters/sqlite.js +443 -37
- package/dist/adapters/sqlite.js.map +1 -1
- package/dist/adapters/stream-scripts.d.ts +49 -0
- package/dist/adapters/stream-scripts.d.ts.map +1 -0
- package/dist/adapters/stream-scripts.js +150 -0
- package/dist/adapters/stream-scripts.js.map +1 -0
- package/dist/adapters/upstash.d.ts +20 -0
- package/dist/adapters/upstash.d.ts.map +1 -1
- package/dist/adapters/upstash.js +29 -0
- package/dist/adapters/upstash.js.map +1 -1
- package/dist/adapters/web-search-shared.d.ts +11 -0
- package/dist/adapters/web-search-shared.d.ts.map +1 -0
- package/dist/adapters/web-search-shared.js +40 -0
- package/dist/adapters/web-search-shared.js.map +1 -0
- package/dist/admin/memory.d.ts +11 -1
- package/dist/admin/memory.d.ts.map +1 -1
- package/dist/admin/memory.js +83 -14
- package/dist/admin/memory.js.map +1 -1
- package/dist/admin/migrations/postgres/0002-run-settled-at.d.ts +5 -0
- package/dist/admin/migrations/postgres/0002-run-settled-at.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0002-run-settled-at.js +11 -0
- package/dist/admin/migrations/postgres/0002-run-settled-at.js.map +1 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.d.ts +5 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.js +15 -0
- package/dist/admin/migrations/postgres/0003-run-enqueued-at.js.map +1 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.d.ts +5 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.js +15 -0
- package/dist/admin/migrations/postgres/0004-run-settle-claim.js.map +1 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.d.ts +5 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.d.ts.map +1 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.js +12 -0
- package/dist/admin/migrations/postgres/0005-bigint-counters.js.map +1 -0
- package/dist/admin/migrations/postgres/index.d.ts.map +1 -1
- package/dist/admin/migrations/postgres/index.js +16 -1
- package/dist/admin/migrations/postgres/index.js.map +1 -1
- package/dist/admin/migrations/runner.d.ts +21 -1
- package/dist/admin/migrations/runner.d.ts.map +1 -1
- package/dist/admin/migrations/runner.js +41 -4
- package/dist/admin/migrations/runner.js.map +1 -1
- package/dist/admin/migrations/sqlite/0002-run-settled-at.d.ts +5 -0
- package/dist/admin/migrations/sqlite/0002-run-settled-at.d.ts.map +1 -0
- package/dist/admin/migrations/sqlite/0002-run-settled-at.js +11 -0
- package/dist/admin/migrations/sqlite/0002-run-settled-at.js.map +1 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.d.ts +5 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.d.ts.map +1 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.js +15 -0
- package/dist/admin/migrations/sqlite/0003-run-enqueued-at.js.map +1 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.d.ts +5 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.d.ts.map +1 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.js +15 -0
- package/dist/admin/migrations/sqlite/0004-run-settle-claim.js.map +1 -0
- package/dist/admin/migrations/sqlite/index.d.ts +2 -2
- package/dist/admin/migrations/sqlite/index.d.ts.map +1 -1
- package/dist/admin/migrations/sqlite/index.js +17 -3
- package/dist/admin/migrations/sqlite/index.js.map +1 -1
- package/dist/admin/postgres.d.ts +14 -4
- package/dist/admin/postgres.d.ts.map +1 -1
- package/dist/admin/postgres.js +131 -36
- package/dist/admin/postgres.js.map +1 -1
- package/dist/admin/shared.d.ts +19 -0
- package/dist/admin/shared.d.ts.map +1 -0
- package/dist/admin/shared.js +28 -0
- package/dist/admin/shared.js.map +1 -0
- package/dist/admin/sqlite.d.ts +9 -1
- package/dist/admin/sqlite.d.ts.map +1 -1
- package/dist/admin/sqlite.js +112 -29
- package/dist/admin/sqlite.js.map +1 -1
- package/dist/core/admin.d.ts +28 -6
- package/dist/core/admin.d.ts.map +1 -1
- package/dist/core/admin.js +92 -23
- package/dist/core/admin.js.map +1 -1
- package/dist/core/agent.d.ts +7 -4
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +15 -11
- package/dist/core/agent.js.map +1 -1
- package/dist/core/agui.d.ts +17 -0
- package/dist/core/agui.d.ts.map +1 -0
- package/dist/core/agui.js +69 -0
- package/dist/core/agui.js.map +1 -0
- package/dist/core/builtin/definitions.d.ts +12 -0
- package/dist/core/builtin/definitions.d.ts.map +1 -0
- package/dist/core/builtin/definitions.js +149 -0
- package/dist/core/builtin/definitions.js.map +1 -0
- package/dist/core/builtin/html.d.ts +13 -0
- package/dist/core/builtin/html.d.ts.map +1 -0
- package/dist/core/builtin/html.js +96 -0
- package/dist/core/builtin/html.js.map +1 -0
- package/dist/core/builtin/index.d.ts +21 -0
- package/dist/core/builtin/index.d.ts.map +1 -0
- package/dist/core/builtin/index.js +55 -0
- package/dist/core/builtin/index.js.map +1 -0
- package/dist/core/builtin/run.d.ts +37 -0
- package/dist/core/builtin/run.d.ts.map +1 -0
- package/dist/core/builtin/run.js +55 -0
- package/dist/core/builtin/run.js.map +1 -0
- package/dist/core/builtin/sandbox-tools.d.ts +69 -0
- package/dist/core/builtin/sandbox-tools.d.ts.map +1 -0
- package/dist/core/builtin/sandbox-tools.js +389 -0
- package/dist/core/builtin/sandbox-tools.js.map +1 -0
- package/dist/core/builtin/sandbox.d.ts +52 -0
- package/dist/core/builtin/sandbox.d.ts.map +1 -0
- package/dist/core/builtin/sandbox.js +174 -0
- package/dist/core/builtin/sandbox.js.map +1 -0
- package/dist/core/builtin/web.d.ts +54 -0
- package/dist/core/builtin/web.d.ts.map +1 -0
- package/dist/core/builtin/web.js +167 -0
- package/dist/core/builtin/web.js.map +1 -0
- package/dist/core/context.d.ts +13 -1
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +70 -19
- package/dist/core/context.js.map +1 -1
- package/dist/core/deleteThread.d.ts.map +1 -1
- package/dist/core/deleteThread.js +36 -4
- package/dist/core/deleteThread.js.map +1 -1
- package/dist/core/engine.d.ts +41 -11
- package/dist/core/engine.d.ts.map +1 -1
- package/dist/core/engine.js +880 -353
- package/dist/core/engine.js.map +1 -1
- package/dist/core/follow.d.ts +63 -1
- package/dist/core/follow.d.ts.map +1 -1
- package/dist/core/follow.js +293 -16
- package/dist/core/follow.js.map +1 -1
- package/dist/core/hitl.d.ts +43 -0
- package/dist/core/hitl.d.ts.map +1 -1
- package/dist/core/hitl.js +163 -35
- package/dist/core/hitl.js.map +1 -1
- package/dist/core/keys.d.ts +22 -4
- package/dist/core/keys.d.ts.map +1 -1
- package/dist/core/keys.js +23 -5
- package/dist/core/keys.js.map +1 -1
- package/dist/core/lease.d.ts +46 -0
- package/dist/core/lease.d.ts.map +1 -0
- package/dist/core/lease.js +142 -0
- package/dist/core/lease.js.map +1 -0
- package/dist/core/loop.d.ts +27 -7
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +140 -55
- package/dist/core/loop.js.map +1 -1
- package/dist/core/messages.d.ts +21 -2
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +61 -2
- package/dist/core/messages.js.map +1 -1
- package/dist/core/permanent.d.ts +11 -0
- package/dist/core/permanent.d.ts.map +1 -0
- package/dist/core/permanent.js +37 -0
- package/dist/core/permanent.js.map +1 -0
- package/dist/core/prune.d.ts +24 -0
- package/dist/core/prune.d.ts.map +1 -0
- package/dist/core/prune.js +43 -0
- package/dist/core/prune.js.map +1 -0
- package/dist/core/publish.d.ts +38 -10
- package/dist/core/publish.d.ts.map +1 -1
- package/dist/core/publish.js +126 -12
- package/dist/core/publish.js.map +1 -1
- package/dist/core/reclaim.d.ts +8 -1
- package/dist/core/reclaim.d.ts.map +1 -1
- package/dist/core/reclaim.js +149 -18
- package/dist/core/reclaim.js.map +1 -1
- package/dist/core/run.d.ts +7 -3
- package/dist/core/run.d.ts.map +1 -1
- package/dist/core/run.js +95 -35
- package/dist/core/run.js.map +1 -1
- package/dist/core/segment.d.ts +62 -0
- package/dist/core/segment.d.ts.map +1 -0
- package/dist/core/segment.js +318 -0
- package/dist/core/segment.js.map +1 -0
- package/dist/core/settle.d.ts +57 -0
- package/dist/core/settle.d.ts.map +1 -0
- package/dist/core/settle.js +181 -0
- package/dist/core/settle.js.map +1 -0
- package/dist/core/snapshot.d.ts +36 -0
- package/dist/core/snapshot.d.ts.map +1 -0
- package/dist/core/snapshot.js +87 -0
- package/dist/core/snapshot.js.map +1 -0
- package/dist/core/stop.d.ts +16 -1
- package/dist/core/stop.d.ts.map +1 -1
- package/dist/core/stop.js +69 -15
- package/dist/core/stop.js.map +1 -1
- package/dist/core/stream-events.d.ts +184 -0
- package/dist/core/stream-events.d.ts.map +1 -0
- package/dist/core/stream-events.js +26 -0
- package/dist/core/stream-events.js.map +1 -0
- package/dist/core/stream.d.ts +29 -0
- package/dist/core/stream.d.ts.map +1 -1
- package/dist/core/stream.js +79 -0
- package/dist/core/stream.js.map +1 -1
- package/dist/core/subagent.d.ts +36 -5
- package/dist/core/subagent.d.ts.map +1 -1
- package/dist/core/subagent.js +130 -25
- package/dist/core/subagent.js.map +1 -1
- package/dist/core/tools.d.ts +9 -3
- package/dist/core/tools.d.ts.map +1 -1
- package/dist/core/tools.js.map +1 -1
- package/dist/core/types.d.ts +212 -13
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +29 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/usage.d.ts +53 -5
- package/dist/core/usage.d.ts.map +1 -1
- package/dist/core/usage.js +170 -47
- package/dist/core/usage.js.map +1 -1
- package/dist/index.d.ts +29 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -7
- package/dist/index.js.map +1 -1
- package/dist/ports/admin.d.ts +59 -0
- package/dist/ports/admin.d.ts.map +1 -1
- package/dist/ports/kv.d.ts +17 -0
- package/dist/ports/kv.d.ts.map +1 -1
- package/dist/ports/queue.d.ts +87 -7
- package/dist/ports/queue.d.ts.map +1 -1
- package/dist/ports/queue.js +36 -1
- package/dist/ports/queue.js.map +1 -1
- package/dist/ports/runtime.d.ts +188 -20
- package/dist/ports/runtime.d.ts.map +1 -1
- package/dist/ports/sandbox.d.ts +159 -0
- package/dist/ports/sandbox.d.ts.map +1 -0
- package/dist/ports/sandbox.js +44 -0
- package/dist/ports/sandbox.js.map +1 -0
- package/dist/ports/storage.d.ts +26 -5
- package/dist/ports/storage.d.ts.map +1 -1
- package/dist/ports/streams.d.ts +60 -0
- package/dist/ports/streams.d.ts.map +1 -0
- package/dist/ports/streams.js +20 -0
- package/dist/ports/streams.js.map +1 -0
- package/dist/ports/tools.d.ts +60 -0
- package/dist/ports/tools.d.ts.map +1 -0
- package/dist/ports/tools.js +5 -0
- package/dist/ports/tools.js.map +1 -0
- package/dist/pricing.d.ts +29 -0
- package/dist/pricing.d.ts.map +1 -1
- package/dist/pricing.js +64 -10
- package/dist/pricing.js.map +1 -1
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +147 -46
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
package/dist/adapters/redis.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AgentEvent } from '../core/types.js';
|
|
2
2
|
import type { Kv } from '../ports/kv.js';
|
|
3
3
|
import type { EventBus } from '../ports/bus.js';
|
|
4
|
+
import { ScriptedRunStreams } from './stream-scripts.js';
|
|
4
5
|
/** Minimal structural type of a node-redis (v4) client — the real client
|
|
5
6
|
* satisfies it without importing the SDK here. Works against any Redis:
|
|
6
7
|
* local Docker, self-hosted, or managed. */
|
|
@@ -11,6 +12,10 @@ export interface RedisClientLike {
|
|
|
11
12
|
del: any;
|
|
12
13
|
incr: any;
|
|
13
14
|
publish: any;
|
|
15
|
+
/** node-redis v4: `eval(script, { keys, arguments })`. */
|
|
16
|
+
eval: any;
|
|
17
|
+
/** Any command, raw: `sendCommand(['XREAD', ...])`. */
|
|
18
|
+
sendCommand?: any;
|
|
14
19
|
duplicate(): any;
|
|
15
20
|
}
|
|
16
21
|
/** A dedicated connection for subscriptions (node-redis `client.duplicate()`). */
|
|
@@ -32,18 +37,49 @@ export declare class RedisKv implements Kv {
|
|
|
32
37
|
}): Promise<boolean>;
|
|
33
38
|
del(key: string): any;
|
|
34
39
|
incr(key: string): any;
|
|
40
|
+
setIfValue(key: string, expected: string, value: string, opts?: {
|
|
41
|
+
exSeconds?: number;
|
|
42
|
+
}): Promise<boolean>;
|
|
43
|
+
delIfValue(key: string, expected: string): Promise<boolean>;
|
|
44
|
+
incrWithExpiry(key: string, exSeconds: number): Promise<number>;
|
|
35
45
|
}
|
|
36
46
|
/** Reference EventBus adapter over plain Redis Pub/Sub (node-redis).
|
|
37
47
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
48
|
+
* One subscriber connection per process, shared by every subscription: a
|
|
49
|
+
* channel is subscribed when its first handler arrives and unsubscribed when
|
|
50
|
+
* its last one leaves. A connection per viewer would run a busy deployment
|
|
51
|
+
* into Redis's `maxclients`.
|
|
52
|
+
*
|
|
53
|
+
* While subscribed, a bus-only `HEARTBEAT` notice (seq 0, never persisted)
|
|
54
|
+
* reaches every subscription each `heartbeatMs`, from one timer per process —
|
|
55
|
+
* the §2.5 watchdog pattern: pub/sub is at-most-once, so the SSE distributor
|
|
56
|
+
* treats heartbeats as a trigger to re-check for orphaned HITL waits, and a
|
|
57
|
+
* follower fills any gap from the log. */
|
|
42
58
|
export declare class RedisBus implements EventBus {
|
|
43
59
|
private readonly client;
|
|
44
60
|
private readonly heartbeatMs;
|
|
61
|
+
private sub;
|
|
62
|
+
private readonly handlers;
|
|
63
|
+
private heartbeat?;
|
|
45
64
|
constructor(client: RedisClientLike, heartbeatMs?: number);
|
|
46
65
|
publish(threadId: string, event: AgentEvent): Promise<void>;
|
|
66
|
+
/** The shared subscriber connection, opened on first use. */
|
|
67
|
+
private connection;
|
|
68
|
+
private deliver;
|
|
47
69
|
subscribe(threadId: string, handler: (event: AgentEvent) => void): Promise<() => Promise<void>>;
|
|
70
|
+
private startHeartbeat;
|
|
71
|
+
private stopHeartbeat;
|
|
72
|
+
}
|
|
73
|
+
/** RunStreams over Redis Streams (see stream-scripts.ts for the keys and
|
|
74
|
+
* scripts, the same ones the Go adapter runs). Readers in one process share
|
|
75
|
+
* one blocking connection; `pollMs` is the floor under a missed wake-up. */
|
|
76
|
+
export declare class RedisRunStreams extends ScriptedRunStreams {
|
|
77
|
+
private readonly tail;
|
|
78
|
+
constructor(client: RedisClientLike, opts?: {
|
|
79
|
+
pollMs?: number;
|
|
80
|
+
blockMs?: number;
|
|
81
|
+
});
|
|
82
|
+
/** Closes the shared tail connection. */
|
|
83
|
+
shutdown(): Promise<void>;
|
|
48
84
|
}
|
|
49
85
|
//# sourceMappingURL=redis.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/adapters/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/adapters/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAmB,kBAAkB,EAAS,MAAM,qBAAqB,CAAC;AAGjF;;6CAE6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAG5B,GAAG,EAAE,GAAG,CAAC;IACT,GAAG,EAAE,GAAG,CAAC;IACT,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,GAAG,CAAC;IACV,OAAO,EAAE,GAAG,CAAC;IACb,0DAA0D;IAC1D,IAAI,EAAE,GAAG,CAAC;IACV,uDAAuD;IACvD,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,SAAS,IAAI,GAAG,CAAC;CAClB;AAED,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,SAAS,EAAE,GAAG,CAAC;IACf,WAAW,EAAE,GAAG,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;IACV,EAAE,EAAE,GAAG,CAAC;CACT;AAED,0DAA0D;AAC1D,qBAAa,OAAQ,YAAW,EAAE;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,eAAe;IAEnD,GAAG,CAAC,GAAG,EAAE,MAAM;IACT,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACvD,OAAO,CAAC,OAAO,CAAC;IAanB,GAAG,CAAC,GAAG,EAAE,MAAM;IACf,IAAI,CAAC,GAAG,EAAE,MAAM;IACV,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAQtF,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAIxC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAOpD;AAED;;;;;;;;;;;2CAW2C;AAC3C,qBAAa,QAAS,YAAW,QAAQ;IAMrC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAN9B,OAAO,CAAC,GAAG,CAA6C;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuD;IAChF,OAAO,CAAC,SAAS,CAAC,CAAiC;gBAGhC,MAAM,EAAE,eAAe,EACvB,WAAW,SAAS;IAGjC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU;IAIjD,6DAA6D;IAC7D,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,OAAO;IAUT,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;IAyCtE,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,aAAa;CAItB;AAmID;;6EAE6E;AAC7E,qBAAa,eAAgB,SAAQ,kBAAkB;IACrD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,MAAM,EAAE,eAAe,EAAE,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO;IAUrF,yCAAyC;IACnC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
package/dist/adapters/redis.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { compareEntryIds, ScriptedRunStreams, sleep } from './stream-scripts.js';
|
|
2
|
+
import { DEL_IF_VALUE_SCRIPT, INCR_WITH_EXPIRY_SCRIPT, SET_IF_VALUE_SCRIPT, THREAD_CHANNEL } from './upstash.js';
|
|
2
3
|
/** Reference Kv adapter over plain Redis (node-redis). */
|
|
3
4
|
export class RedisKv {
|
|
4
5
|
redis;
|
|
@@ -17,16 +18,44 @@ export class RedisKv {
|
|
|
17
18
|
}
|
|
18
19
|
del(key) { return this.redis.del(key).then(() => undefined); }
|
|
19
20
|
incr(key) { return this.redis.incr(key); }
|
|
21
|
+
async setIfValue(key, expected, value, opts) {
|
|
22
|
+
const ms = Math.round((opts?.exSeconds ?? 0) * 1000);
|
|
23
|
+
const n = await this.redis.eval(SET_IF_VALUE_SCRIPT, {
|
|
24
|
+
keys: [key],
|
|
25
|
+
arguments: [expected, value, String(ms)],
|
|
26
|
+
});
|
|
27
|
+
return Number(n) === 1;
|
|
28
|
+
}
|
|
29
|
+
async delIfValue(key, expected) {
|
|
30
|
+
const n = await this.redis.eval(DEL_IF_VALUE_SCRIPT, { keys: [key], arguments: [expected] });
|
|
31
|
+
return Number(n) === 1;
|
|
32
|
+
}
|
|
33
|
+
async incrWithExpiry(key, exSeconds) {
|
|
34
|
+
const n = await this.redis.eval(INCR_WITH_EXPIRY_SCRIPT, {
|
|
35
|
+
keys: [key],
|
|
36
|
+
arguments: [String(Math.round(exSeconds * 1000))],
|
|
37
|
+
});
|
|
38
|
+
return Number(n);
|
|
39
|
+
}
|
|
20
40
|
}
|
|
21
41
|
/** Reference EventBus adapter over plain Redis Pub/Sub (node-redis).
|
|
22
42
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
43
|
+
* One subscriber connection per process, shared by every subscription: a
|
|
44
|
+
* channel is subscribed when its first handler arrives and unsubscribed when
|
|
45
|
+
* its last one leaves. A connection per viewer would run a busy deployment
|
|
46
|
+
* into Redis's `maxclients`.
|
|
47
|
+
*
|
|
48
|
+
* While subscribed, a bus-only `HEARTBEAT` notice (seq 0, never persisted)
|
|
49
|
+
* reaches every subscription each `heartbeatMs`, from one timer per process —
|
|
50
|
+
* the §2.5 watchdog pattern: pub/sub is at-most-once, so the SSE distributor
|
|
51
|
+
* treats heartbeats as a trigger to re-check for orphaned HITL waits, and a
|
|
52
|
+
* follower fills any gap from the log. */
|
|
27
53
|
export class RedisBus {
|
|
28
54
|
client;
|
|
29
55
|
heartbeatMs;
|
|
56
|
+
sub = null;
|
|
57
|
+
handlers = new Map();
|
|
58
|
+
heartbeat;
|
|
30
59
|
constructor(client, heartbeatMs = 60_000) {
|
|
31
60
|
this.client = client;
|
|
32
61
|
this.heartbeatMs = heartbeatMs;
|
|
@@ -34,27 +63,243 @@ export class RedisBus {
|
|
|
34
63
|
async publish(threadId, event) {
|
|
35
64
|
await this.client.publish(THREAD_CHANNEL(threadId), JSON.stringify(event));
|
|
36
65
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
/** The shared subscriber connection, opened on first use. */
|
|
67
|
+
connection() {
|
|
68
|
+
if (!this.sub) {
|
|
69
|
+
const sub = this.client.duplicate();
|
|
70
|
+
// node-redis emits 'error' on a dropped connection and reconnects by
|
|
71
|
+
// itself. With no listener, the emit throws and ends the process, so one
|
|
72
|
+
// Redis failover would take down every worker and SSE server.
|
|
73
|
+
sub.on('error', (err) => console.error('redis subscriber error', err));
|
|
74
|
+
this.sub = Promise.resolve(sub.connect()).then(() => sub, (err) => {
|
|
75
|
+
this.sub = null; // a later subscribe tries again
|
|
76
|
+
void Promise.resolve(sub.quit()).catch(() => undefined);
|
|
77
|
+
throw err;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return this.sub;
|
|
81
|
+
}
|
|
82
|
+
deliver(handlers, event) {
|
|
83
|
+
for (const handler of handlers) {
|
|
41
84
|
try {
|
|
42
|
-
handler(
|
|
85
|
+
handler(event);
|
|
43
86
|
}
|
|
44
87
|
catch {
|
|
45
|
-
//
|
|
88
|
+
// one throwing handler must not stop the others
|
|
46
89
|
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async subscribe(threadId, handler) {
|
|
93
|
+
const channel = THREAD_CHANNEL(threadId);
|
|
94
|
+
const sub = await this.connection();
|
|
95
|
+
let set = this.handlers.get(channel);
|
|
96
|
+
if (!set) {
|
|
97
|
+
set = new Set();
|
|
98
|
+
this.handlers.set(channel, set);
|
|
99
|
+
const mine = set;
|
|
100
|
+
try {
|
|
101
|
+
await sub.subscribe(channel, (message) => {
|
|
102
|
+
let event;
|
|
103
|
+
try {
|
|
104
|
+
event = JSON.parse(message);
|
|
105
|
+
event.createdAt = new Date(event.createdAt);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return; // malformed frame — never kill the subscription
|
|
109
|
+
}
|
|
110
|
+
this.deliver([...mine], event);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
this.handlers.delete(channel);
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
set.add(handler);
|
|
119
|
+
this.startHeartbeat();
|
|
120
|
+
let done = false;
|
|
53
121
|
return async () => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
122
|
+
if (done)
|
|
123
|
+
return;
|
|
124
|
+
done = true;
|
|
125
|
+
const current = this.handlers.get(channel);
|
|
126
|
+
current?.delete(handler);
|
|
127
|
+
if (current && current.size === 0) {
|
|
128
|
+
this.handlers.delete(channel);
|
|
129
|
+
await sub.unsubscribe(channel).catch(() => undefined);
|
|
130
|
+
}
|
|
131
|
+
if (this.handlers.size === 0)
|
|
132
|
+
this.stopHeartbeat();
|
|
57
133
|
};
|
|
58
134
|
}
|
|
135
|
+
startHeartbeat() {
|
|
136
|
+
if (this.heartbeat)
|
|
137
|
+
return;
|
|
138
|
+
this.heartbeat = setInterval(() => {
|
|
139
|
+
for (const [channel, set] of this.handlers) {
|
|
140
|
+
const threadId = channel.slice('thread:'.length, -':events'.length);
|
|
141
|
+
this.deliver([...set], {
|
|
142
|
+
threadId, seq: 0, type: 'HEARTBEAT', payload: null, createdAt: new Date(),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}, this.heartbeatMs);
|
|
146
|
+
this.heartbeat.unref?.();
|
|
147
|
+
}
|
|
148
|
+
stopHeartbeat() {
|
|
149
|
+
if (this.heartbeat)
|
|
150
|
+
clearInterval(this.heartbeat);
|
|
151
|
+
this.heartbeat = undefined;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** How long a stream key with no reader stays watched. */
|
|
155
|
+
const TAIL_IDLE_MS = 10_000;
|
|
156
|
+
/** An XREAD reply as [key, entries] pairs. RESP2 gives an array of pairs;
|
|
157
|
+
* RESP3 clients give a map, as a Map or a plain object. */
|
|
158
|
+
function xreadPairs(reply) {
|
|
159
|
+
if (!reply)
|
|
160
|
+
return [];
|
|
161
|
+
if (Array.isArray(reply))
|
|
162
|
+
return reply;
|
|
163
|
+
if (reply instanceof Map)
|
|
164
|
+
return [...reply.entries()];
|
|
165
|
+
return Object.entries(reply);
|
|
166
|
+
}
|
|
167
|
+
/** One blocking `XREAD` per process, shared by every reader of every stream
|
|
168
|
+
* here: a connection per reader would run a busy deployment into Redis's
|
|
169
|
+
* `maxclients`, like a subscriber per viewer would. A reader registers the
|
|
170
|
+
* stream key and the last id it has; the tail wakes it when an entry past
|
|
171
|
+
* that id lands. When a key it does not watch yet arrives, the tail breaks
|
|
172
|
+
* its own block with `CLIENT UNBLOCK` and starts again with the new key. */
|
|
173
|
+
class StreamTail {
|
|
174
|
+
client;
|
|
175
|
+
blockMs;
|
|
176
|
+
conn = null;
|
|
177
|
+
/** Per key: the newest entry id the tail has seen, who waits, and when a
|
|
178
|
+
* reader last waited. A key stays watched a while after its last reader
|
|
179
|
+
* leaves, so a reader that waits again after each event does not break
|
|
180
|
+
* the block every time. */
|
|
181
|
+
keys = new Map();
|
|
182
|
+
running = false;
|
|
183
|
+
constructor(client, blockMs) {
|
|
184
|
+
this.client = client;
|
|
185
|
+
this.blockMs = blockMs;
|
|
186
|
+
}
|
|
187
|
+
connection() {
|
|
188
|
+
if (!this.conn) {
|
|
189
|
+
const conn = this.client.duplicate();
|
|
190
|
+
conn.on?.('error', (err) => console.error('redis stream tail error', err));
|
|
191
|
+
this.conn = Promise.resolve(conn.connect())
|
|
192
|
+
.then(async () => ({ client: conn, id: String(await conn.sendCommand(['CLIENT', 'ID'])) }))
|
|
193
|
+
.catch((err) => {
|
|
194
|
+
this.conn = null;
|
|
195
|
+
void Promise.resolve(conn.quit?.()).catch(() => undefined);
|
|
196
|
+
throw err;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return this.conn;
|
|
200
|
+
}
|
|
201
|
+
/** Resolves when `key` may have an entry past `after`. */
|
|
202
|
+
wait(key, after, maxMs, signal) {
|
|
203
|
+
return new Promise((resolve) => {
|
|
204
|
+
let entry = this.keys.get(key);
|
|
205
|
+
// The tail already saw something past this reader: wake at once.
|
|
206
|
+
if (entry && compareEntryIds(entry.seen, after) > 0)
|
|
207
|
+
return resolve();
|
|
208
|
+
let timer;
|
|
209
|
+
const done = () => {
|
|
210
|
+
clearTimeout(timer);
|
|
211
|
+
signal?.removeEventListener('abort', done);
|
|
212
|
+
const e = this.keys.get(key);
|
|
213
|
+
if (e?.waiters.delete(done))
|
|
214
|
+
e.used = Date.now();
|
|
215
|
+
resolve();
|
|
216
|
+
};
|
|
217
|
+
timer = setTimeout(done, maxMs);
|
|
218
|
+
signal?.addEventListener('abort', done, { once: true });
|
|
219
|
+
const fresh = !entry;
|
|
220
|
+
if (!entry) {
|
|
221
|
+
entry = { seen: after, waiters: new Set(), used: Date.now() };
|
|
222
|
+
this.keys.set(key, entry);
|
|
223
|
+
}
|
|
224
|
+
entry.waiters.add(done);
|
|
225
|
+
entry.used = Date.now();
|
|
226
|
+
if (fresh)
|
|
227
|
+
void this.restart();
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
/** Runs the loop, or breaks its current block so it takes the new keys. */
|
|
231
|
+
async restart() {
|
|
232
|
+
if (!this.running) {
|
|
233
|
+
this.running = true;
|
|
234
|
+
void this.loop().finally(() => {
|
|
235
|
+
this.running = false;
|
|
236
|
+
// A key that came in while the loop was on its way out.
|
|
237
|
+
if (this.keys.size > 0)
|
|
238
|
+
void this.restart();
|
|
239
|
+
});
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const { id } = await this.connection();
|
|
244
|
+
await this.client.sendCommand?.(['CLIENT', 'UNBLOCK', id]);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// The loop's own timeout picks the key up.
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async loop() {
|
|
251
|
+
for (;;) {
|
|
252
|
+
const now = Date.now();
|
|
253
|
+
for (const [key, e] of this.keys) {
|
|
254
|
+
if (e.waiters.size === 0 && now - e.used > TAIL_IDLE_MS)
|
|
255
|
+
this.keys.delete(key);
|
|
256
|
+
}
|
|
257
|
+
if (this.keys.size === 0)
|
|
258
|
+
return;
|
|
259
|
+
const keys = [...this.keys.keys()];
|
|
260
|
+
const ids = keys.map((k) => this.keys.get(k).seen);
|
|
261
|
+
let reply;
|
|
262
|
+
try {
|
|
263
|
+
const { client } = await this.connection();
|
|
264
|
+
reply = await client.sendCommand(['XREAD', 'BLOCK', String(this.blockMs), 'STREAMS', ...keys, ...ids]);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// A dropped connection: readers fall back on their own poll until
|
|
268
|
+
// the next pass reconnects.
|
|
269
|
+
await sleep(200);
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
for (const [key, entries] of xreadPairs(reply)) {
|
|
273
|
+
const entry = this.keys.get(String(key));
|
|
274
|
+
const last = entries.at(-1)?.[0];
|
|
275
|
+
if (!entry || !last)
|
|
276
|
+
continue;
|
|
277
|
+
entry.seen = String(last);
|
|
278
|
+
for (const wake of [...entry.waiters])
|
|
279
|
+
wake();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
async close() {
|
|
284
|
+
const conn = this.conn;
|
|
285
|
+
this.conn = null;
|
|
286
|
+
if (conn)
|
|
287
|
+
await conn.then(({ client }) => client.quit()).catch(() => undefined);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/** RunStreams over Redis Streams (see stream-scripts.ts for the keys and
|
|
291
|
+
* scripts, the same ones the Go adapter runs). Readers in one process share
|
|
292
|
+
* one blocking connection; `pollMs` is the floor under a missed wake-up. */
|
|
293
|
+
export class RedisRunStreams extends ScriptedRunStreams {
|
|
294
|
+
tail;
|
|
295
|
+
constructor(client, opts = {}) {
|
|
296
|
+
const tail = new StreamTail(client, opts.blockMs ?? 5_000);
|
|
297
|
+
super((script, keys, args) => client.eval(script, { keys, arguments: args }), (key, after, maxMs, signal) => tail.wait(key, after, maxMs, signal), opts.pollMs ?? 1_000);
|
|
298
|
+
this.tail = tail;
|
|
299
|
+
}
|
|
300
|
+
/** Closes the shared tail connection. */
|
|
301
|
+
async shutdown() {
|
|
302
|
+
await this.tail.close();
|
|
303
|
+
}
|
|
59
304
|
}
|
|
60
305
|
//# sourceMappingURL=redis.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/adapters/redis.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/adapters/redis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type FileEntry } from '../ports/sandbox.js';
|
|
2
|
+
/** Pieces the sandbox adapters share. The Go adapters use the same scripts
|
|
3
|
+
* (adapters/internal/sandboxsh), so a command behaves the same in both. */
|
|
4
|
+
/** Runs `$1` in bash (sh where there is no bash), under `timeout` for `$2`
|
|
5
|
+
* seconds when that is given and the sandbox has `timeout`. `$3` is `-l`
|
|
6
|
+
* for a login shell. Called as `sh -c RUN_SCRIPT sandbox <command> <secs> <-l>`. */
|
|
7
|
+
export declare const RUN_SCRIPT: string;
|
|
8
|
+
/** The argv that runs `command` through RUN_SCRIPT. */
|
|
9
|
+
export declare function runArgv(command: string, timeoutSeconds?: number, login?: boolean): string[];
|
|
10
|
+
/** Starts `command` apart from the caller and returns at once. */
|
|
11
|
+
export declare function backgroundCommand(command: string): string;
|
|
12
|
+
/** Whole seconds for `timeout(1)`, never less than one. */
|
|
13
|
+
export declare function timeoutSeconds(ms: number): number;
|
|
14
|
+
/** `timeout` stops a command with 124 (TERM) or 137 (KILL after -k). */
|
|
15
|
+
export declare function looksTimedOut(exitCode: number, elapsedMs: number, limitMs: number): boolean;
|
|
16
|
+
export declare function shellQuote(s: string): string;
|
|
17
|
+
/** A relative path is taken from the work folder. */
|
|
18
|
+
export declare function resolveIn(workdir: string, path: string): string;
|
|
19
|
+
/** The exit code the file scripts give for "no such file or folder". */
|
|
20
|
+
export declare const NOT_FOUND_EXIT = 44;
|
|
21
|
+
/** `sh -c <script> sandbox <path>` scripts for adapters that reach files
|
|
22
|
+
* only through commands. Each exits 44 when the path is not there. */
|
|
23
|
+
export declare const FILE_SCRIPTS: {
|
|
24
|
+
readonly read: "[ -f \"$1\" ] || exit 44; cat -- \"$1\"";
|
|
25
|
+
readonly readBase64: "[ -f \"$1\" ] || exit 44; base64 < \"$1\"";
|
|
26
|
+
readonly write: "mkdir -p -- \"$(dirname -- \"$1\")\" && cat > \"$1\"";
|
|
27
|
+
readonly list: string;
|
|
28
|
+
readonly mkdir: "mkdir -p -- \"$1\"";
|
|
29
|
+
readonly exists: "[ -e \"$1\" ] || [ -L \"$1\" ]";
|
|
30
|
+
readonly remove: "rm -rf -- \"$1\"";
|
|
31
|
+
};
|
|
32
|
+
/** Reads what FILE_SCRIPTS.list printed. */
|
|
33
|
+
export declare function parseListing(out: string): FileEntry[];
|
|
34
|
+
export declare function sortEntries(entries: FileEntry[]): FileEntry[];
|
|
35
|
+
/** Collects one output stream: keeps up to MAX_COMMAND_OUTPUT_BYTES, hands
|
|
36
|
+
* each piece on as text as it comes, never splitting a character. */
|
|
37
|
+
export declare class OutputCollector {
|
|
38
|
+
private readonly onText?;
|
|
39
|
+
private readonly decoder;
|
|
40
|
+
private readonly parts;
|
|
41
|
+
private kept;
|
|
42
|
+
truncated: boolean;
|
|
43
|
+
constructor(onText?: ((chunk: string) => void) | undefined);
|
|
44
|
+
push(chunk: Uint8Array): void;
|
|
45
|
+
end(): string;
|
|
46
|
+
private add;
|
|
47
|
+
}
|
|
48
|
+
/** Output from an adapter that hands it over whole, cut to
|
|
49
|
+
* MAX_COMMAND_OUTPUT_BYTES the way OutputCollector cuts a stream. */
|
|
50
|
+
export declare function capOutput(text: string): {
|
|
51
|
+
text: string;
|
|
52
|
+
truncated: boolean;
|
|
53
|
+
};
|
|
54
|
+
/** Random lowercase letters and digits, for sandbox names. */
|
|
55
|
+
export declare function randomId(length?: number): string;
|
|
56
|
+
/** Base64 without the line breaks some `base64` tools add. */
|
|
57
|
+
export declare function decodeBase64(text: string): Uint8Array;
|
|
58
|
+
export declare function encodeBase64(bytes: Uint8Array): string;
|
|
59
|
+
export declare function toBytes(content: string | Uint8Array): Uint8Array;
|
|
60
|
+
//# sourceMappingURL=sandbox-shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-shell.d.ts","sourceRoot":"","sources":["../../src/adapters/sandbox-shell.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE/E;4EAC4E;AAE5E;;qFAEqF;AACrF,eAAO,MAAM,UAAU,QAGC,CAAC;AAEzB,uDAAuD;AACvD,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,MAAM,EAAE,CAEzF;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3F;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wEAAwE;AACxE,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC;uEACuE;AACvE,eAAO,MAAM,YAAY;;;;;;;;CAYf,CAAC;AAEX,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CASrD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAE7D;AAED;sEACsE;AACtE,qBAAa,eAAe;IAMd,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IALpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,IAAI,CAAK;IACjB,SAAS,UAAS;gBAEW,MAAM,CAAC,GAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,aAAA;IAE7D,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAY7B,GAAG,IAAI,MAAM;IAQb,OAAO,CAAC,GAAG;CAIZ;AAED;sEACsE;AACtE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAI5E;AAED,8DAA8D;AAC9D,wBAAgB,QAAQ,CAAC,MAAM,SAAK,GAAG,MAAM,CAM5C;AAED,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAErD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEtD;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,CAEhE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { posix } from 'node:path';
|
|
2
|
+
import { MAX_COMMAND_OUTPUT_BYTES } from '../ports/sandbox.js';
|
|
3
|
+
/** Pieces the sandbox adapters share. The Go adapters use the same scripts
|
|
4
|
+
* (adapters/internal/sandboxsh), so a command behaves the same in both. */
|
|
5
|
+
/** Runs `$1` in bash (sh where there is no bash), under `timeout` for `$2`
|
|
6
|
+
* seconds when that is given and the sandbox has `timeout`. `$3` is `-l`
|
|
7
|
+
* for a login shell. Called as `sh -c RUN_SCRIPT sandbox <command> <secs> <-l>`. */
|
|
8
|
+
export const RUN_SCRIPT = 'if command -v bash >/dev/null 2>&1; then s=bash; else s=sh; fi; ' +
|
|
9
|
+
'if [ -n "$2" ] && command -v timeout >/dev/null 2>&1; then exec timeout -k 2 "$2" "$s" $3 -c "$1"; fi; ' +
|
|
10
|
+
'exec "$s" $3 -c "$1"';
|
|
11
|
+
/** The argv that runs `command` through RUN_SCRIPT. */
|
|
12
|
+
export function runArgv(command, timeoutSeconds, login = false) {
|
|
13
|
+
return ['sh', '-c', RUN_SCRIPT, 'sandbox', command, timeoutSeconds ? String(timeoutSeconds) : '', login ? '-l' : ''];
|
|
14
|
+
}
|
|
15
|
+
/** Starts `command` apart from the caller and returns at once. */
|
|
16
|
+
export function backgroundCommand(command) {
|
|
17
|
+
return `nohup sh -c ${shellQuote(command)} >/dev/null 2>&1 &`;
|
|
18
|
+
}
|
|
19
|
+
/** Whole seconds for `timeout(1)`, never less than one. */
|
|
20
|
+
export function timeoutSeconds(ms) {
|
|
21
|
+
return Math.max(1, Math.ceil(ms / 1000));
|
|
22
|
+
}
|
|
23
|
+
/** `timeout` stops a command with 124 (TERM) or 137 (KILL after -k). */
|
|
24
|
+
export function looksTimedOut(exitCode, elapsedMs, limitMs) {
|
|
25
|
+
return (exitCode === 124 || exitCode === 137) && elapsedMs >= limitMs - 250;
|
|
26
|
+
}
|
|
27
|
+
export function shellQuote(s) {
|
|
28
|
+
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
29
|
+
}
|
|
30
|
+
/** A relative path is taken from the work folder. */
|
|
31
|
+
export function resolveIn(workdir, path) {
|
|
32
|
+
return path.startsWith('/') ? posix.normalize(path) : posix.join(workdir, path);
|
|
33
|
+
}
|
|
34
|
+
/** The exit code the file scripts give for "no such file or folder". */
|
|
35
|
+
export const NOT_FOUND_EXIT = 44;
|
|
36
|
+
/** `sh -c <script> sandbox <path>` scripts for adapters that reach files
|
|
37
|
+
* only through commands. Each exits 44 when the path is not there. */
|
|
38
|
+
export const FILE_SCRIPTS = {
|
|
39
|
+
read: '[ -f "$1" ] || exit 44; cat -- "$1"',
|
|
40
|
+
readBase64: '[ -f "$1" ] || exit 44; base64 < "$1"',
|
|
41
|
+
write: 'mkdir -p -- "$(dirname -- "$1")" && cat > "$1"',
|
|
42
|
+
list: '[ -d "$1" ] || exit 44; cd -- "$1" || exit 44; ' +
|
|
43
|
+
'for f in * .[!.]* ..?*; do [ -e "$f" ] || [ -L "$f" ] || continue; ' +
|
|
44
|
+
'if [ -d "$f" ]; then printf \'d\\t0\\t%s\\n\' "$f"; ' +
|
|
45
|
+
'else printf \'f\\t%s\\t%s\\n\' "$(wc -c < "$f" | tr -d \' \')" "$f"; fi; done',
|
|
46
|
+
mkdir: 'mkdir -p -- "$1"',
|
|
47
|
+
exists: '[ -e "$1" ] || [ -L "$1" ]',
|
|
48
|
+
remove: 'rm -rf -- "$1"',
|
|
49
|
+
};
|
|
50
|
+
/** Reads what FILE_SCRIPTS.list printed. */
|
|
51
|
+
export function parseListing(out) {
|
|
52
|
+
const entries = [];
|
|
53
|
+
for (const line of out.split('\n')) {
|
|
54
|
+
if (!line)
|
|
55
|
+
continue;
|
|
56
|
+
const [kind, size, ...rest] = line.split('\t');
|
|
57
|
+
const name = rest.join('\t');
|
|
58
|
+
entries.push(kind === 'd' ? { name, type: 'directory' } : { name, type: 'file', size: Number(size) || 0 });
|
|
59
|
+
}
|
|
60
|
+
return sortEntries(entries);
|
|
61
|
+
}
|
|
62
|
+
export function sortEntries(entries) {
|
|
63
|
+
return entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
64
|
+
}
|
|
65
|
+
/** Collects one output stream: keeps up to MAX_COMMAND_OUTPUT_BYTES, hands
|
|
66
|
+
* each piece on as text as it comes, never splitting a character. */
|
|
67
|
+
export class OutputCollector {
|
|
68
|
+
onText;
|
|
69
|
+
decoder = new TextDecoder();
|
|
70
|
+
parts = [];
|
|
71
|
+
kept = 0;
|
|
72
|
+
truncated = false;
|
|
73
|
+
constructor(onText) {
|
|
74
|
+
this.onText = onText;
|
|
75
|
+
}
|
|
76
|
+
push(chunk) {
|
|
77
|
+
let bytes = chunk;
|
|
78
|
+
if (this.kept + bytes.length > MAX_COMMAND_OUTPUT_BYTES) {
|
|
79
|
+
bytes = bytes.subarray(0, Math.max(0, MAX_COMMAND_OUTPUT_BYTES - this.kept));
|
|
80
|
+
this.truncated = true;
|
|
81
|
+
}
|
|
82
|
+
this.kept += bytes.length;
|
|
83
|
+
if (bytes.length === 0)
|
|
84
|
+
return;
|
|
85
|
+
const text = this.decoder.decode(bytes, { stream: true });
|
|
86
|
+
if (text)
|
|
87
|
+
this.add(text);
|
|
88
|
+
}
|
|
89
|
+
end() {
|
|
90
|
+
const rest = this.decoder.decode();
|
|
91
|
+
// Past the cap, a character cut in half is dropped rather than shown
|
|
92
|
+
// as a broken one.
|
|
93
|
+
if (rest && !this.truncated)
|
|
94
|
+
this.add(rest);
|
|
95
|
+
return this.parts.join('');
|
|
96
|
+
}
|
|
97
|
+
add(text) {
|
|
98
|
+
this.parts.push(text);
|
|
99
|
+
this.onText?.(text);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Output from an adapter that hands it over whole, cut to
|
|
103
|
+
* MAX_COMMAND_OUTPUT_BYTES the way OutputCollector cuts a stream. */
|
|
104
|
+
export function capOutput(text) {
|
|
105
|
+
const bytes = new TextEncoder().encode(text);
|
|
106
|
+
if (bytes.length <= MAX_COMMAND_OUTPUT_BYTES)
|
|
107
|
+
return { text, truncated: false };
|
|
108
|
+
return { text: new TextDecoder().decode(bytes.subarray(0, MAX_COMMAND_OUTPUT_BYTES)).replace(/\uFFFD$/, ''), truncated: true };
|
|
109
|
+
}
|
|
110
|
+
/** Random lowercase letters and digits, for sandbox names. */
|
|
111
|
+
export function randomId(length = 12) {
|
|
112
|
+
const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
113
|
+
const bytes = crypto.getRandomValues(new Uint8Array(length));
|
|
114
|
+
let out = '';
|
|
115
|
+
for (const b of bytes)
|
|
116
|
+
out += alphabet[b % alphabet.length];
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
/** Base64 without the line breaks some `base64` tools add. */
|
|
120
|
+
export function decodeBase64(text) {
|
|
121
|
+
return Uint8Array.from(Buffer.from(text.replace(/\s+/g, ''), 'base64'));
|
|
122
|
+
}
|
|
123
|
+
export function encodeBase64(bytes) {
|
|
124
|
+
return Buffer.from(bytes).toString('base64');
|
|
125
|
+
}
|
|
126
|
+
export function toBytes(content) {
|
|
127
|
+
return typeof content === 'string' ? new TextEncoder().encode(content) : content;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=sandbox-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-shell.js","sourceRoot":"","sources":["../../src/adapters/sandbox-shell.ts"],"names":[],"mappings":"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"}
|