@haikeilabs/agentware 0.2.1 → 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.
@@ -1,2 +1,3 @@
1
1
  export * from "./runtimeLink.js";
2
+ export * from "./runtimeLinkRuntime.js";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kei/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/kei/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC"}
package/dist/kei/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./runtimeLink.js";
2
+ export * from "./runtimeLinkRuntime.js";
@@ -2,12 +2,11 @@
2
2
  * RuntimeLink contract: the harness → Agentware → kei-connector-runtime heartbeat.
3
3
  *
4
4
  * TypeScript mirror of the Go reference `go/kei/runtimelink` for
5
- * `docs/specs/runtime-heartbeat-liveness.md` (HAI-141). Contract types only:
5
+ * `docs/specs/runtime-heartbeat-liveness.md` (HAI-141). This module defines
6
6
  * configuration, status, identity, failure classes, the child's JSONL wire
7
- * events, and redacted lifecycle events. It never spawns a process, opens a
8
- * network connection, or reads a credential value. The only heartbeat path is
9
- * harness → RuntimeLink → kei-connector-runtime; nothing here talks to the
10
- * catalog.
7
+ * events, and redacted lifecycle events. Process supervision is implemented
8
+ * in `runtimeLinkRuntime.ts`. The only heartbeat path is harness → RuntimeLink
9
+ * → kei-connector-runtime; Agentware does not call the catalog itself.
11
10
  *
12
11
  * All three SDK languages share `testing/contracts/runtime-link`. Durations
13
12
  * are milliseconds here (`intervalMs`), seconds in Python, and
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeLink.d.ts","sourceRoot":"","sources":["../../src/kei/runtimeLink.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtimeLink.d.ts","sourceRoot":"","sources":["../../src/kei/runtimeLink.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,11 @@
2
2
  * RuntimeLink contract: the harness → Agentware → kei-connector-runtime heartbeat.
3
3
  *
4
4
  * TypeScript mirror of the Go reference `go/kei/runtimelink` for
5
- * `docs/specs/runtime-heartbeat-liveness.md` (HAI-141). Contract types only:
5
+ * `docs/specs/runtime-heartbeat-liveness.md` (HAI-141). This module defines
6
6
  * configuration, status, identity, failure classes, the child's JSONL wire
7
- * events, and redacted lifecycle events. It never spawns a process, opens a
8
- * network connection, or reads a credential value. The only heartbeat path is
9
- * harness → RuntimeLink → kei-connector-runtime; nothing here talks to the
10
- * catalog.
7
+ * events, and redacted lifecycle events. Process supervision is implemented
8
+ * in `runtimeLinkRuntime.ts`. The only heartbeat path is harness → RuntimeLink
9
+ * → kei-connector-runtime; Agentware does not call the catalog itself.
11
10
  *
12
11
  * All three SDK languages share `testing/contracts/runtime-link`. Durations
13
12
  * are milliseconds here (`intervalMs`), seconds in Python, and
@@ -0,0 +1,26 @@
1
+ import { type RuntimeLink, type RuntimeLinkConfig } from "./runtimeLink.js";
2
+ export interface RuntimeChild {
3
+ readonly stdout: AsyncIterable<Uint8Array | string>;
4
+ readonly exitCode: Promise<number>;
5
+ kill(signal?: "SIGTERM" | "SIGKILL"): void;
6
+ }
7
+ /** Injectable process boundary for tests and embedders. */
8
+ export interface RuntimeChildFactory {
9
+ start(command: string, args: readonly string[], env: Readonly<Record<string, string>>): RuntimeChild;
10
+ }
11
+ export interface RuntimeLinkOptions {
12
+ env?: Readonly<Record<string, string | undefined>>;
13
+ childFactory?: RuntimeChildFactory;
14
+ now?: () => Date;
15
+ random?: () => number;
16
+ sdkVersion?: string;
17
+ sdkInstanceId?: string;
18
+ audit?: (event: Readonly<Record<string, unknown>>) => void | Promise<void>;
19
+ }
20
+ /** Node process implementation. stderr is drained and discarded; never surfaced to audit or logs. */
21
+ export declare class NodeRuntimeChildFactory implements RuntimeChildFactory {
22
+ start(command: string, args: readonly string[], env: Readonly<Record<string, string>>): RuntimeChild;
23
+ }
24
+ /** Create a supervisor that owns the harness → kei-connector-runtime process and heartbeat boundary. */
25
+ export declare function newRuntimeLink(config: RuntimeLinkConfig, options?: RuntimeLinkOptions): RuntimeLink;
26
+ //# sourceMappingURL=runtimeLinkRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeLinkRuntime.d.ts","sourceRoot":"","sources":["../../src/kei/runtimeLinkRuntime.ts"],"names":[],"mappings":"AAIA,OAAO,EAYL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC;CAC5C;AAED,2DAA2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,KAAK,CACH,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpC,YAAY,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E;AAED,qGAAqG;AACrG,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,KAAK,CACH,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpC,YAAY;CA8BhB;AAWD,wGAAwG;AACxG,wBAAgB,cAAc,CAC5B,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAEb"}
@@ -0,0 +1,400 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { spawn } from "node:child_process";
3
+ import { createReadStream } from "node:fs";
4
+ import { createHash } from "node:crypto";
5
+ import { CHILD_ENV_ALLOWLIST, RUNTIME_LINK_SDK_LANG, linkEventToWire, normalizeRuntimeLinkConfig, parseChildLine, waitBackoff, } from "./runtimeLink.js";
6
+ /** Node process implementation. stderr is drained and discarded; never surfaced to audit or logs. */
7
+ export class NodeRuntimeChildFactory {
8
+ start(command, args, env) {
9
+ const child = spawn(command, [...args], {
10
+ env: { ...env },
11
+ stdio: ["ignore", "pipe", "ignore"],
12
+ detached: process.platform !== "win32",
13
+ });
14
+ const stdout = child.stdout;
15
+ if (!stdout)
16
+ throw new Error("runtime stdout unavailable");
17
+ const exitCode = new Promise((resolve) => {
18
+ child.once("error", () => resolve(1));
19
+ child.once("close", (code) => resolve(code ?? 1));
20
+ });
21
+ return {
22
+ stdout: (async function* () {
23
+ for await (const chunk of stdout)
24
+ yield chunk;
25
+ })(),
26
+ exitCode,
27
+ kill: (signal = "SIGTERM") => {
28
+ if (process.platform !== "win32" && child.pid) {
29
+ try {
30
+ process.kill(-child.pid, signal);
31
+ }
32
+ catch {
33
+ child.kill(signal);
34
+ }
35
+ }
36
+ else {
37
+ child.kill(signal);
38
+ }
39
+ },
40
+ };
41
+ }
42
+ }
43
+ const SDK_VERSION = "0.2.1";
44
+ const OUTCOME_FAILURE = {
45
+ catalog_unreachable: "catalog_unreachable",
46
+ catalog_timeout: "catalog_timeout",
47
+ catalog_error: "catalog_error",
48
+ catalog_backpressure: "catalog_backpressure",
49
+ catalog_rejected: "contract_mismatch",
50
+ };
51
+ /** Create a supervisor that owns the harness → kei-connector-runtime process and heartbeat boundary. */
52
+ export function newRuntimeLink(config, options = {}) {
53
+ return new RuntimeLinkImpl(normalizeRuntimeLinkConfig(config), options);
54
+ }
55
+ class RuntimeLinkImpl {
56
+ config;
57
+ options;
58
+ eventsQueue = [];
59
+ waiters = [];
60
+ controller = new AbortController();
61
+ sdkId;
62
+ state;
63
+ reason;
64
+ identityValue;
65
+ runId = "";
66
+ lastBeatAt;
67
+ lastCatalogOkAt;
68
+ consecutiveFails = 0;
69
+ restarts = 0;
70
+ started = false;
71
+ stopped = false;
72
+ supervisor;
73
+ child;
74
+ constructor(config, options) {
75
+ this.config = config;
76
+ this.options = options;
77
+ this.state = config.enabled ? "disabled" : "disabled";
78
+ this.sdkId = options.sdkInstanceId ?? randomUUID();
79
+ }
80
+ async start(signal) {
81
+ if (this.started || this.stopped || !this.config.enabled)
82
+ return;
83
+ this.started = true;
84
+ if (signal?.aborted) {
85
+ await this.stop();
86
+ return;
87
+ }
88
+ signal?.addEventListener("abort", () => {
89
+ void this.stop();
90
+ }, { once: true });
91
+ this.supervisor = this.supervise();
92
+ // Starting is non-blocking; only config errors can reject.
93
+ }
94
+ async stop() {
95
+ if (this.stopped) {
96
+ await this.withTimeout(this.supervisor);
97
+ return;
98
+ }
99
+ this.stopped = true;
100
+ this.controller.abort(new Error("RuntimeLink stopped"));
101
+ this.transition("stopped");
102
+ this.child?.kill("SIGTERM");
103
+ await this.withTimeout(this.supervisor);
104
+ this.child = undefined;
105
+ for (const resolve of this.waiters.splice(0))
106
+ resolve({ done: true, value: undefined });
107
+ }
108
+ status() {
109
+ return {
110
+ state: this.state,
111
+ reason: this.reason,
112
+ lastBeatAt: this.lastBeatAt,
113
+ lastCatalogOkAt: this.lastCatalogOkAt,
114
+ consecutiveFails: this.consecutiveFails,
115
+ runId: this.runId,
116
+ restarts: this.restarts,
117
+ };
118
+ }
119
+ identity() {
120
+ return this.identityValue && { ...this.identityValue };
121
+ }
122
+ events() {
123
+ const queue = this.eventsQueue;
124
+ const waiters = this.waiters;
125
+ return {
126
+ [Symbol.asyncIterator]() {
127
+ return {
128
+ next: () => queue.length
129
+ ? Promise.resolve({ done: false, value: queue.shift() })
130
+ : new Promise((resolve) => waiters.push(resolve)),
131
+ return: () => Promise.resolve({ done: true, value: undefined }),
132
+ };
133
+ },
134
+ };
135
+ }
136
+ async supervise() {
137
+ while (!this.controller.signal.aborted) {
138
+ if (this.restarts > 0) {
139
+ this.transition("reconnecting");
140
+ try {
141
+ await waitBackoff(this.config.restart, this.restarts - 1, {
142
+ signal: this.controller.signal,
143
+ random: this.options.random,
144
+ });
145
+ }
146
+ catch {
147
+ return;
148
+ }
149
+ }
150
+ if (this.controller.signal.aborted)
151
+ return;
152
+ this.transition("starting");
153
+ let failure = "runtime_unavailable";
154
+ try {
155
+ failure = await this.runChild();
156
+ }
157
+ catch (e) {
158
+ if (this.controller.signal.aborted)
159
+ return;
160
+ failure =
161
+ e instanceof BinaryFailure
162
+ ? "config_invalid"
163
+ : "runtime_unresponsive";
164
+ }
165
+ if (this.controller.signal.aborted || this.state === "terminal")
166
+ return;
167
+ this.restarts++;
168
+ this.consecutiveFails++;
169
+ this.reason = failure;
170
+ if (failure === "config_invalid" ||
171
+ failure === "contract_mismatch" ||
172
+ failure === "installation_unauthorized") {
173
+ this.transition("terminal", failure);
174
+ return;
175
+ }
176
+ this.transition("degraded", failure);
177
+ if (this.restarts >= 5) {
178
+ this.transition("terminal", "runtime_crashloop");
179
+ return;
180
+ }
181
+ }
182
+ }
183
+ async runChild() {
184
+ await this.verifyBinary();
185
+ const env = this.childEnv();
186
+ const factory = this.options.childFactory ?? new NodeRuntimeChildFactory();
187
+ const child = factory.start(this.config.binary.path, ["runtime", "heartbeat", "--output", "jsonl"], env);
188
+ this.child = child;
189
+ let identitySeen = false;
190
+ let heartbeatDeadline = Date.now() + this.config.beatTimeoutMs;
191
+ const lines = this.consume(child.stdout);
192
+ const abortPromise = new Promise((_, reject) => {
193
+ if (this.controller.signal.aborted)
194
+ reject(this.controller.signal.reason);
195
+ else
196
+ this.controller.signal.addEventListener("abort", () => reject(this.controller.signal.reason), { once: true });
197
+ });
198
+ try {
199
+ while (!this.controller.signal.aborted) {
200
+ const remaining = identitySeen
201
+ ? Math.max(1, heartbeatDeadline - Date.now())
202
+ : this.config.graceMs;
203
+ let timer;
204
+ const next = await Promise.race([
205
+ lines.next(),
206
+ new Promise((_, reject) => {
207
+ timer = setTimeout(() => reject(new Error("runtime heartbeat timeout")), remaining);
208
+ }),
209
+ abortPromise,
210
+ ]).finally(() => {
211
+ if (timer)
212
+ clearTimeout(timer);
213
+ });
214
+ if (next.done) {
215
+ const code = await child.exitCode;
216
+ const failure = code === 2
217
+ ? "contract_mismatch"
218
+ : code === 3
219
+ ? "installation_unauthorized"
220
+ : code >= 4
221
+ ? "config_invalid"
222
+ : "runtime_unavailable";
223
+ if (failure === "contract_mismatch" ||
224
+ failure === "installation_unauthorized" ||
225
+ failure === "config_invalid") {
226
+ this.transition("terminal", failure);
227
+ }
228
+ return failure;
229
+ }
230
+ let ev;
231
+ try {
232
+ ev = parseChildLine(next.value);
233
+ }
234
+ catch (error) {
235
+ this.consecutiveFails++;
236
+ if (error instanceof Error &&
237
+ error.message.includes("contract_mismatch"))
238
+ this.reason = "contract_mismatch";
239
+ continue;
240
+ }
241
+ if (ev.kind === "identity") {
242
+ this.identityValue = ev.identity;
243
+ this.runId = ev.identity.runId;
244
+ identitySeen = true;
245
+ heartbeatDeadline = Date.now() + this.config.beatTimeoutMs;
246
+ this.transition("connected");
247
+ }
248
+ else if (ev.kind === "beat") {
249
+ this.runId = ev.beat.runId || this.runId;
250
+ this.lastBeatAt = this.options.now?.() ?? new Date();
251
+ heartbeatDeadline = Date.now() + this.config.beatTimeoutMs;
252
+ if (ev.beat.outcome === "ok") {
253
+ this.lastCatalogOkAt = this.lastBeatAt;
254
+ this.consecutiveFails = 0;
255
+ if (this.state !== "connected")
256
+ this.transition("connected");
257
+ }
258
+ else if (ev.beat.outcome === "unauthorized") {
259
+ this.transition("terminal", "installation_unauthorized");
260
+ return "installation_unauthorized";
261
+ }
262
+ else {
263
+ this.consecutiveFails++;
264
+ this.transition("degraded", OUTCOME_FAILURE[ev.beat.outcome] ?? "runtime_unavailable");
265
+ }
266
+ }
267
+ else if (ev.kind === "terminal") {
268
+ const reason = ev.terminal.reason === "unauthorized"
269
+ ? "installation_unauthorized"
270
+ : ev.terminal.reason === "contract"
271
+ ? "contract_mismatch"
272
+ : "runtime_unavailable";
273
+ this.transition("terminal", reason);
274
+ return reason;
275
+ }
276
+ }
277
+ return "runtime_unavailable";
278
+ }
279
+ finally {
280
+ child.kill("SIGTERM");
281
+ this.child = undefined;
282
+ }
283
+ }
284
+ async *consume(source) {
285
+ const decoder = new TextDecoder();
286
+ let pending = "";
287
+ for await (const chunk of source) {
288
+ if (this.controller.signal.aborted)
289
+ return;
290
+ pending +=
291
+ typeof chunk === "string"
292
+ ? chunk
293
+ : decoder.decode(chunk, { stream: true });
294
+ let idx;
295
+ while ((idx = pending.indexOf("\n")) >= 0) {
296
+ yield pending.slice(0, idx + 1);
297
+ pending = pending.slice(idx + 1);
298
+ }
299
+ if (new TextEncoder().encode(pending).length > 4097)
300
+ pending = " ".repeat(4098);
301
+ }
302
+ if (pending)
303
+ yield pending;
304
+ }
305
+ childEnv() {
306
+ const source = this.options.env ?? process.env;
307
+ const out = {};
308
+ for (const key of CHILD_ENV_ALLOWLIST) {
309
+ const value = source[key];
310
+ if (value !== undefined)
311
+ out[key] = value;
312
+ }
313
+ out.KEI_AGENTWARE_SDK_LANG = RUNTIME_LINK_SDK_LANG;
314
+ out.KEI_AGENTWARE_SDK_VERSION = this.options.sdkVersion ?? SDK_VERSION;
315
+ out.KEI_RUNTIME_CONTROL_PLANE_URL = this.config.controlPlaneUrl;
316
+ out.KEI_HARNESS_KIND = this.config.harness.kind;
317
+ out.KEI_HARNESS_VERSION = this.config.harness.version;
318
+ out.KEI_DEPLOYMENT_ENV = this.config.harness.deploymentEnv;
319
+ return out;
320
+ }
321
+ async verifyBinary() {
322
+ const expected = this.config.binary.sha256;
323
+ if (!expected)
324
+ return;
325
+ const hash = createHash("sha256");
326
+ try {
327
+ for await (const chunk of createReadStream(this.config.binary.path))
328
+ hash.update(chunk);
329
+ }
330
+ catch {
331
+ throw new BinaryFailure();
332
+ }
333
+ if (hash.digest("hex") !== expected)
334
+ throw new BinaryFailure();
335
+ }
336
+ transition(state, reason) {
337
+ if (this.state === state && this.reason === reason)
338
+ return;
339
+ this.state = state;
340
+ this.reason = reason;
341
+ const name = {
342
+ starting: "runtime.link.started",
343
+ connected: "runtime.link.connected",
344
+ degraded: "runtime.link.degraded",
345
+ reconnecting: "runtime.link.reconnecting",
346
+ terminal: "runtime.link.terminal",
347
+ stopped: "runtime.link.stopped",
348
+ }[state];
349
+ if (!name)
350
+ return;
351
+ const event = {
352
+ name,
353
+ at: this.options.now?.() ?? new Date(),
354
+ state,
355
+ reason: reason ?? "",
356
+ runId: this.runId,
357
+ seq: Date.now(),
358
+ sdkInstanceId: this.sdkId,
359
+ harness: {
360
+ kind: this.config.harness.kind,
361
+ version: this.config.harness.version,
362
+ deploymentEnv: this.config.harness.deploymentEnv,
363
+ sdkLang: RUNTIME_LINK_SDK_LANG,
364
+ sdkVersion: this.options.sdkVersion ?? SDK_VERSION,
365
+ },
366
+ restarts: this.restarts,
367
+ consecutiveFails: this.consecutiveFails,
368
+ };
369
+ try {
370
+ const safe = linkEventToWire(event);
371
+ if (this.waiters.length)
372
+ this.waiters.shift()({ done: false, value: event });
373
+ else {
374
+ if (this.eventsQueue.length >= 64)
375
+ this.eventsQueue.shift();
376
+ this.eventsQueue.push(event);
377
+ }
378
+ if (this.options.audit)
379
+ void Promise.resolve(this.options.audit(safe)).catch(() => undefined);
380
+ }
381
+ catch {
382
+ /* audit/event serialization must fail closed without leaking arbitrary input */
383
+ }
384
+ }
385
+ async withTimeout(task) {
386
+ if (!task)
387
+ return;
388
+ let timer;
389
+ await Promise.race([
390
+ task,
391
+ new Promise((resolve) => {
392
+ timer = setTimeout(resolve, this.config.stopTimeoutMs);
393
+ }),
394
+ ]);
395
+ if (timer)
396
+ clearTimeout(timer);
397
+ }
398
+ }
399
+ class BinaryFailure extends Error {
400
+ }
@@ -9,7 +9,7 @@ export class MiddlewareImpl {
9
9
  execute(toolName, args, caller) {
10
10
  const decision = this.evaluator
11
11
  ? this.evaluator.evaluate(toolName, args, caller)
12
- : { action: Action.ALLOW, rule: "default", reason: "no policy configured", timestamp: new Date() };
12
+ : { action: Action.DENY, rule: "default", reason: "no policy configured; default deny", timestamp: new Date() };
13
13
  if (this.auditor) {
14
14
  this.auditor.record({
15
15
  session_id: caller.session_id || "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haikeilabs/agentware",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Agent middleware and tooling for LLM tool calling",
5
5
  "repository": {
6
6
  "type": "git",