@appliqation/agent-core 0.1.3 → 0.1.5

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,6 +1,19 @@
1
1
  export interface McpClientOptions {
2
2
  origin: string;
3
3
  apiKey: string;
4
+ /**
5
+ * Per-HTTP-call timeout in millis, via AbortSignal.timeout() — without
6
+ * this, a hung appq origin hangs the call (and the whole run) forever,
7
+ * since fetch has no default timeout of its own. Defaults to 30s.
8
+ */
9
+ timeoutMs?: number;
10
+ /**
11
+ * Retry attempts for a transient failure (network error, HTTP 429, or a
12
+ * 5xx) before giving up — not a JSON-RPC application-level error or any
13
+ * other non-retryable HTTP status, which retrying can't fix. Defaults to
14
+ * 2 (3 attempts total), with exponential backoff between attempts.
15
+ */
16
+ maxRetries?: number;
4
17
  }
5
18
  export interface McpTextContent {
6
19
  type: 'text';
@@ -1 +1 @@
1
- {"version":3,"file":"mcpClient.d.ts","sourceRoot":"","sources":["../../src/appq/mcpClient.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AASD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAClE;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,uFAAuF;IACvF,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3E;;;;;;OAMG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChF,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;IACzF;;;;;;;;;OASG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAkFjE"}
1
+ {"version":3,"file":"mcpClient.d.ts","sourceRoot":"","sources":["../../src/appq/mcpClient.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAClE;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,uFAAuF;IACvF,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3E;;;;;;OAMG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,mFAAmF;IACnF,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChF,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;IACzF;;;;;;;;;OASG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrE;AAcD,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAiHjE"}
@@ -2,11 +2,51 @@
2
2
  // a module-level singleton — each consuming agent has its own .env/config
3
3
  // shape, so origin/apiKey are supplied by the caller rather than read from a
4
4
  // shared global.
5
+ const DEFAULT_TIMEOUT_MS = 30_000;
6
+ const DEFAULT_MAX_RETRIES = 2;
7
+ const RETRY_BASE_DELAY_MS = 300;
8
+ function isRetryableStatus(status) {
9
+ return status === 429 || status >= 500;
10
+ }
11
+ function sleep(ms) {
12
+ return new Promise((resolve) => setTimeout(resolve, ms));
13
+ }
5
14
  export function createMcpClient(opts) {
6
15
  let requestId = 0;
16
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
17
+ const maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES;
18
+ // Every fetch in this client goes through here — a hung origin now times
19
+ // out instead of hanging the run forever, and a transient failure (network
20
+ // error, 429, 5xx) gets a few retries with backoff before giving up. The
21
+ // last attempt's response/error is what the caller sees either way — no
22
+ // silent retry-then-succeed masking, just fewer spurious failures from
23
+ // blips that would have succeeded a moment later.
24
+ async function fetchWithRetry(url, init) {
25
+ let lastError;
26
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
27
+ try {
28
+ const res = await fetch(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
29
+ if (isRetryableStatus(res.status) && attempt < maxRetries) {
30
+ lastError = new Error(`appq MCP HTTP ${res.status}`);
31
+ await sleep(RETRY_BASE_DELAY_MS * 2 ** attempt);
32
+ continue;
33
+ }
34
+ return res;
35
+ }
36
+ catch (err) {
37
+ lastError = err;
38
+ if (attempt < maxRetries) {
39
+ await sleep(RETRY_BASE_DELAY_MS * 2 ** attempt);
40
+ continue;
41
+ }
42
+ throw err;
43
+ }
44
+ }
45
+ throw lastError;
46
+ }
7
47
  async function rpc(method, params) {
8
48
  const id = ++requestId;
9
- const res = await fetch(`${opts.origin}/api/appq/mcp`, {
49
+ const res = await fetchWithRetry(`${opts.origin}/api/appq/mcp`, {
10
50
  method: 'POST',
11
51
  headers: {
12
52
  'Content-Type': 'application/json',
@@ -59,7 +99,7 @@ export function createMcpClient(opts) {
59
99
  return result.tools;
60
100
  },
61
101
  async uploadScreenshot(pngBuffer, label) {
62
- const res = await fetch(`${opts.origin}/api/appq/mcp/upload-screenshot`, {
102
+ const res = await fetchWithRetry(`${opts.origin}/api/appq/mcp/upload-screenshot`, {
63
103
  method: 'POST',
64
104
  headers: {
65
105
  'X-API-Key': opts.apiKey,
@@ -1 +1 @@
1
- {"version":3,"file":"mcpClient.js","sourceRoot":"","sources":["../../src/appq/mcpClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcpClient.js","sourceRoot":"","sources":["../../src/appq/mcpClient.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { type AuditRecord, type AuditSink, type AuditEnv, noopAuditSink, createJsonlAuditSink, createMongoAuditSink, resolveAuditSink, safeRecord, createUsageAccumulator, } from './sink.js';
1
+ export { type AuditRecord, type AuditSink, type AuditEnv, noopAuditSink, createJsonlAuditSink, createMongoAuditSink, resolveAuditSink, safeRecord, safeClose, createUsageAccumulator, } from './sink.js';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,sBAAsB,GACvB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,sBAAsB,GACvB,MAAM,WAAW,CAAC"}
@@ -1,2 +1,2 @@
1
- export { noopAuditSink, createJsonlAuditSink, createMongoAuditSink, resolveAuditSink, safeRecord, createUsageAccumulator, } from './sink.js';
1
+ export { noopAuditSink, createJsonlAuditSink, createMongoAuditSink, resolveAuditSink, safeRecord, safeClose, createUsageAccumulator, } from './sink.js';
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,sBAAsB,GACvB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,SAAS,EACT,sBAAsB,GACvB,MAAM,WAAW,CAAC"}
@@ -22,6 +22,17 @@ export interface AuditRecord {
22
22
  }
23
23
  export interface AuditSink {
24
24
  record(entry: AuditRecord): Promise<void>;
25
+ /**
26
+ * Releases whatever resource this sink holds open (a Mongo connection
27
+ * pool/topology monitor) — a no-op for sinks that hold nothing. Every CLI
28
+ * calls this once via safeClose() after its one record() call, since none
29
+ * of these CLIs call process.exit() (see cli/index.ts's top-level
30
+ * .catch()) — they set process.exitCode and let the event loop drain,
31
+ * which is correct, but means anything still holding the loop open (an
32
+ * unclosed Mongo client's background timers/sockets) hangs the process
33
+ * indefinitely instead of exiting.
34
+ */
35
+ close(): Promise<void>;
25
36
  }
26
37
  export declare const noopAuditSink: AuditSink;
27
38
  export declare function createJsonlAuditSink(opts: {
@@ -41,6 +52,12 @@ export declare function createMongoAuditSink(opts: {
41
52
  * already being non-fatal.
42
53
  */
43
54
  export declare function safeRecord(sink: AuditSink, entry: AuditRecord): Promise<void>;
55
+ /**
56
+ * Every CLI should call this once, after its one safeRecord() call — see
57
+ * AuditSink.close() above for why. Same non-fatal reasoning as safeRecord():
58
+ * a failure to close cleanly must never affect the real run's exit code.
59
+ */
60
+ export declare function safeClose(sink: AuditSink): Promise<void>;
44
61
  export interface AuditEnv {
45
62
  auditMongoUri?: string;
46
63
  auditMongoDb?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../src/audit/sink.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,eAAO,MAAM,aAAa,EAAE,SAI3B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAM1E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAqBzG;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnF;AAED,MAAM,WAAW,QAAQ;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,SAAS,CASzD;AAED,UAAU,UAAU;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,4GAA4G;AAC5G,wBAAgB,sBAAsB;eAOvB,UAAU,GAAG,IAAI;cAMlB,WAAW,CAAC,OAAO,CAAC;EAIjC"}
1
+ {"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../src/audit/sink.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,kGAAkG;IAClG,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C;;;;;;;;;OASG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,eAAO,MAAM,aAAa,EAAE,SAO3B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAS1E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAyBzG;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnF;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9D;AAED,MAAM,WAAW,QAAQ;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,SAAS,CASzD;AAED,UAAU,UAAU;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,4GAA4G;AAC5G,wBAAgB,sBAAsB;eAOvB,UAAU,GAAG,IAAI;cAMlB,WAAW,CAAC,OAAO,CAAC;EAIjC"}
@@ -11,23 +11,30 @@ export const noopAuditSink = {
11
11
  async record() {
12
12
  // Intentionally does nothing — the default when no sink is configured.
13
13
  },
14
+ async close() {
15
+ // Nothing was ever opened.
16
+ },
14
17
  };
15
18
  export function createJsonlAuditSink(opts) {
16
19
  return {
17
20
  async record(entry) {
18
21
  await appendFile(opts.filePath, JSON.stringify(entry) + '\n', 'utf8');
19
22
  },
23
+ async close() {
24
+ // appendFile holds no persistent handle open — nothing to release.
25
+ },
20
26
  };
21
27
  }
22
28
  export function createMongoAuditSink(opts) {
29
+ let client;
23
30
  let collectionPromise;
24
31
  function getCollection() {
25
32
  // Lazy-connect-once: the client is created and connected on the first
26
33
  // record() call, then reused — a CLI invocation that never calls
27
34
  // record() (e.g. audit unconfigured elsewhere in the same process)
28
- // never opens a connection at all.
35
+ // never opens a connection at all, and close() below has nothing to do.
29
36
  if (!collectionPromise) {
30
- const client = new MongoClient(opts.uri);
37
+ client = new MongoClient(opts.uri);
31
38
  collectionPromise = client.connect().then(() => client.db(opts.dbName).collection(opts.collection));
32
39
  }
33
40
  return collectionPromise;
@@ -37,6 +44,10 @@ export function createMongoAuditSink(opts) {
37
44
  const collection = await getCollection();
38
45
  await collection.insertOne(entry);
39
46
  },
47
+ async close() {
48
+ if (client)
49
+ await client.close();
50
+ },
40
51
  };
41
52
  }
42
53
  /**
@@ -55,6 +66,19 @@ export async function safeRecord(sink, entry) {
55
66
  console.error(`[audit] failed to record: ${err.message}`);
56
67
  }
57
68
  }
69
+ /**
70
+ * Every CLI should call this once, after its one safeRecord() call — see
71
+ * AuditSink.close() above for why. Same non-fatal reasoning as safeRecord():
72
+ * a failure to close cleanly must never affect the real run's exit code.
73
+ */
74
+ export async function safeClose(sink) {
75
+ try {
76
+ await sink.close();
77
+ }
78
+ catch (err) {
79
+ console.error(`[audit] failed to close cleanly: ${err.message}`);
80
+ }
81
+ }
58
82
  /**
59
83
  * Precedence mirrors resolveProvider()'s own shape: Mongo (if fully
60
84
  * configured) > JSONL > noop. Nothing writes anywhere unless explicitly
@@ -1 +1 @@
1
- {"version":3,"file":"sink.js","sourceRoot":"","sources":["../../src/audit/sink.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sink.js","sourceRoot":"","sources":["../../src/audit/sink.ts"],"names":[],"mappings":"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"}
@@ -3,15 +3,24 @@ export declare class BudgetTracker {
3
3
  private readonly budget;
4
4
  private calls;
5
5
  private pages;
6
+ private totalTokens;
6
7
  private readonly startedAt;
7
8
  constructor(budget: RunBudget);
8
9
  countCall(): void;
9
10
  countPage(): void;
11
+ /** Accumulates one turn's real token usage — every field counts toward maxTotalTokens, cache included. */
12
+ countUsage(usage?: {
13
+ inputTokens: number;
14
+ outputTokens: number;
15
+ cacheWriteTokens?: number;
16
+ cacheReadTokens?: number;
17
+ }): void;
10
18
  /** Returns a human-readable reason if a cap has been exceeded, else null. */
11
19
  exceeded(): string | null;
12
20
  state(): {
13
21
  calls: number;
14
22
  pages: number;
23
+ totalTokens: number;
15
24
  elapsedMillis: number;
16
25
  };
17
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/engine/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,qBAAa,aAAa;IAKZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAEX,MAAM,EAAE,SAAS;IAE9C,SAAS,IAAI,IAAI;IAIjB,SAAS,IAAI,IAAI;IAIjB,6EAA6E;IAC7E,QAAQ,IAAI,MAAM,GAAG,IAAI;IAUzB,KAAK;;;;;CAGN"}
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/engine/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,qBAAa,aAAa;IAMZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IALnC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAEX,MAAM,EAAE,SAAS;IAE9C,SAAS,IAAI,IAAI;IAIjB,SAAS,IAAI,IAAI;IAIjB,0GAA0G;IAC1G,UAAU,CAAC,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAK5H,6EAA6E;IAC7E,QAAQ,IAAI,MAAM,GAAG,IAAI;IAazB,KAAK;;;;;;CAGN"}
@@ -2,6 +2,7 @@ export class BudgetTracker {
2
2
  budget;
3
3
  calls = 0;
4
4
  pages = 0;
5
+ totalTokens = 0;
5
6
  startedAt = Date.now();
6
7
  constructor(budget) {
7
8
  this.budget = budget;
@@ -12,12 +13,21 @@ export class BudgetTracker {
12
13
  countPage() {
13
14
  this.pages += 1;
14
15
  }
16
+ /** Accumulates one turn's real token usage — every field counts toward maxTotalTokens, cache included. */
17
+ countUsage(usage) {
18
+ if (!usage)
19
+ return;
20
+ this.totalTokens += usage.inputTokens + usage.outputTokens + (usage.cacheWriteTokens ?? 0) + (usage.cacheReadTokens ?? 0);
21
+ }
15
22
  /** Returns a human-readable reason if a cap has been exceeded, else null. */
16
23
  exceeded() {
17
24
  if (this.calls >= this.budget.maxCalls)
18
25
  return `${this.calls} tool calls (cap ${this.budget.maxCalls})`;
19
26
  if (this.pages >= this.budget.maxPages)
20
27
  return `${this.pages} page navigations (cap ${this.budget.maxPages})`;
28
+ if (this.budget.maxTotalTokens && this.totalTokens >= this.budget.maxTotalTokens) {
29
+ return `${this.totalTokens} total tokens (cap ${this.budget.maxTotalTokens})`;
30
+ }
21
31
  const elapsed = Date.now() - this.startedAt;
22
32
  if (elapsed >= this.budget.maxMillis) {
23
33
  return `${Math.round(elapsed / 1000)}s elapsed (cap ${Math.round(this.budget.maxMillis / 1000)}s)`;
@@ -25,7 +35,7 @@ export class BudgetTracker {
25
35
  return null;
26
36
  }
27
37
  state() {
28
- return { calls: this.calls, pages: this.pages, elapsedMillis: Date.now() - this.startedAt };
38
+ return { calls: this.calls, pages: this.pages, totalTokens: this.totalTokens, elapsedMillis: Date.now() - this.startedAt };
29
39
  }
30
40
  }
31
41
  //# sourceMappingURL=budget.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/engine/budget.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAKK;IAJrB,KAAK,GAAG,CAAC,CAAC;IACV,KAAK,GAAG,CAAC,CAAC;IACD,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAExC,YAA6B,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAElD,SAAS;QACP,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,6EAA6E;IAC7E,QAAQ;QACN,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,oBAAoB,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC;QACxG,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,0BAA0B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC;QAC9G,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5C,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;QACrG,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAC9F,CAAC;CACF"}
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/engine/budget.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IAMK;IALrB,KAAK,GAAG,CAAC,CAAC;IACV,KAAK,GAAG,CAAC,CAAC;IACV,WAAW,GAAG,CAAC,CAAC;IACP,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAExC,YAA6B,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;IAAG,CAAC;IAElD,SAAS;QACP,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,SAAS;QACP,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,0GAA0G;IAC1G,UAAU,CAAC,KAA0G;QACnH,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC;IAC5H,CAAC;IAED,6EAA6E;IAC7E,QAAQ;QACN,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,oBAAoB,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC;QACxG,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,0BAA0B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC;QAC9G,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YACjF,OAAO,GAAG,IAAI,CAAC,WAAW,sBAAsB,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,CAAC;QAChF,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5C,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;QACrG,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAC7H,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGtG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/D,GAAG,OAAO,CAAC,UAAU,CAAC,CAwDtB"}
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGtG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/D,GAAG,OAAO,CAAC,UAAU,CAAC,CAkEtB"}
@@ -7,24 +7,34 @@ export async function runLoop(args) {
7
7
  const { adapter, system, tools, dispatch, budget, signal, onEvent } = args;
8
8
  const tracker = new BudgetTracker(budget);
9
9
  const messages = [{ role: 'user', content: args.seedMessage }];
10
- let budgetExceeded = false;
10
+ // A cap being "exceeded" used to just append a note asking the model to
11
+ // stop while still offering it the full tool list — a request, not an
12
+ // enforcement, so a model that ignored it (or a turn already in flight)
13
+ // could keep going past the cap. This is the same hard stop maxTurns
14
+ // already used below: withhold tools entirely and force one final,
15
+ // tools-free completion call — a cap the model is told about is not a cap
16
+ // that's actually enforced until nothing past it can execute.
17
+ const finalize = async (turns) => {
18
+ messages.push({ role: 'user', content: 'Produce your final report now, without calling any tool.' });
19
+ const final = await adapter.complete({ system, messages, tools: [], signal });
20
+ return { report: final.text, turns, budgetExceeded: true };
21
+ };
11
22
  for (let turn = 0; turn < budget.maxTurns; turn++) {
12
23
  if (signal?.aborted)
13
24
  throw new Error('Run aborted');
14
25
  const cap = tracker.exceeded();
15
26
  if (cap) {
16
- budgetExceeded = true;
17
- messages.push({
18
- role: 'user',
19
- content: `Budget note: ${cap}. Stop probing and produce your final report now. Do not call any tool in this turn.`,
20
- });
27
+ onEvent?.({ type: 'log', detail: `Budget cap reached: ${cap}. Requesting final report.` });
28
+ return finalize(turn + 1);
21
29
  }
22
30
  const response = await adapter.complete({ system, messages, tools, signal });
23
31
  onEvent?.({ type: 'assistant', detail: response.text });
24
- if (response.usage)
32
+ if (response.usage) {
25
33
  onEvent?.({ type: 'usage', detail: response.usage });
34
+ tracker.countUsage(response.usage);
35
+ }
26
36
  if (response.toolCalls.length === 0) {
27
- return { report: response.text, turns: turn + 1, budgetExceeded };
37
+ return { report: response.text, turns: turn + 1, budgetExceeded: false };
28
38
  }
29
39
  messages.push({ role: 'assistant', content: response.text, toolCalls: response.toolCalls });
30
40
  for (const call of response.toolCalls) {
@@ -53,8 +63,6 @@ export async function runLoop(args) {
53
63
  }
54
64
  }
55
65
  onEvent?.({ type: 'log', detail: 'Reached max turns; requesting final report.' });
56
- messages.push({ role: 'user', content: 'Produce your final report now, without calling any tool.' });
57
- const final = await adapter.complete({ system, messages, tools: [], signal });
58
- return { report: final.text, turns: budget.maxTurns, budgetExceeded: true };
66
+ return finalize(budget.maxTurns);
59
67
  }
60
68
  //# sourceMappingURL=loop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/engine/loop.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -60,6 +60,15 @@ export interface RunBudget {
60
60
  maxMillis: number;
61
61
  /** Hard backstop on model turns, independent of the other caps — see engine/loop.ts. */
62
62
  maxTurns: number;
63
+ /**
64
+ * Optional hard ceiling on total tokens (input + output + cache write/read,
65
+ * summed across every turn) for one runLoop() invocation. Optional so
66
+ * existing RunBudget literals (tests, older configs) don't need updating —
67
+ * unset means no token ceiling, matching this field's prior total absence.
68
+ * A consuming agent's own config should still set a real default; see
69
+ * config/env.ts in any consuming CLI for the established pattern.
70
+ */
71
+ maxTotalTokens?: number;
63
72
  }
64
73
  export type ToolDispatcher = (name: string, args: Record<string, unknown>) => Promise<ToolResult>;
65
74
  export interface WorkflowRunOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,kFAAkF;QAClF,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,yFAAyF;QACzF,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAKD,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAElG,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,kFAAkF;QAClF,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,yFAAyF;QACzF,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAKD,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAElG,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB"}
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@appliqation/agent-core",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Shared engine (think->act->observe loop, budget tracking, appq MCP client, gated tool dispatch, Playwright browser tools, evidence capture) for Appliqation's family of standalone agents.",
5
+ "license": "MIT",
6
+ "repository": { "type": "git", "url": "git+https://github.com/appliqation/agent-core.git" },
7
+ "homepage": "https://github.com/appliqation/agent-core#readme",
8
+ "bugs": { "url": "https://github.com/appliqation/agent-core/issues" },
5
9
  "type": "module",
6
10
  "main": "dist/index.js",
7
11
  "types": "dist/index.d.ts",
@@ -65,10 +69,13 @@
65
69
  },
66
70
  "devDependencies": {
67
71
  "@appliqation/automation-sdk": "^2.7.0",
72
+ "@eslint/js": "^9.39.5",
68
73
  "@types/node": "^22.13.10",
74
+ "eslint": "^9.39.5",
69
75
  "playwright": "^1.51.0",
70
76
  "tsx": "^4.19.3",
71
77
  "typescript": "^5.8.2",
78
+ "typescript-eslint": "^8.67.0",
72
79
  "vitest": "^3.2.7"
73
80
  }
74
81
  }