@sema-agent/server 1.315.0 → 1.317.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.
Files changed (133) hide show
  1. package/README.md +9 -0
  2. package/README.zh-CN.md +7 -0
  3. package/dist/config-types.d.ts +1 -1
  4. package/dist/config.d.ts +14 -0
  5. package/dist/config.js +148 -45
  6. package/dist/elicitation.js +2 -2
  7. package/dist/http/idempotency.d.ts +1 -0
  8. package/dist/http/idempotency.js +3 -0
  9. package/dist/http/principal-gate.d.ts +12 -0
  10. package/dist/http/principal-gate.js +52 -0
  11. package/dist/http/route-ctx.d.ts +116 -0
  12. package/dist/http/route-ctx.js +2 -0
  13. package/dist/http/routes/approvals-assistant.d.ts +11 -0
  14. package/dist/http/routes/approvals-assistant.js +530 -0
  15. package/dist/http/routes/attachments.d.ts +4 -0
  16. package/dist/http/routes/attachments.js +106 -0
  17. package/dist/http/routes/capabilities.d.ts +4 -0
  18. package/dist/http/routes/capabilities.js +111 -0
  19. package/dist/http/routes/fleet.d.ts +4 -0
  20. package/dist/http/routes/fleet.js +147 -0
  21. package/dist/http/routes/images.d.ts +20 -0
  22. package/dist/http/routes/images.js +572 -0
  23. package/dist/http/routes/leader.d.ts +4 -0
  24. package/dist/http/routes/leader.js +48 -0
  25. package/dist/http/routes/memory-policy.d.ts +4 -0
  26. package/dist/http/routes/memory-policy.js +105 -0
  27. package/dist/http/routes/notify-wake.d.ts +4 -0
  28. package/dist/http/routes/notify-wake.js +133 -0
  29. package/dist/http/routes/observability.d.ts +4 -0
  30. package/dist/http/routes/observability.js +63 -0
  31. package/dist/http/routes/runs.d.ts +19 -0
  32. package/dist/http/routes/runs.js +967 -0
  33. package/dist/http/routes/session-sync.d.ts +36 -0
  34. package/dist/http/routes/session-sync.js +513 -0
  35. package/dist/http/routes/sessions-list.d.ts +4 -0
  36. package/dist/http/routes/sessions-list.js +117 -0
  37. package/dist/http/routes/sessions.d.ts +17 -0
  38. package/dist/http/routes/sessions.js +746 -0
  39. package/dist/http/routes/side-query.d.ts +4 -0
  40. package/dist/http/routes/side-query.js +88 -0
  41. package/dist/http/routes/tasks.d.ts +4 -0
  42. package/dist/http/routes/tasks.js +632 -0
  43. package/dist/http/routes/trace-usage.d.ts +4 -0
  44. package/dist/http/routes/trace-usage.js +239 -0
  45. package/dist/http/routes/workflows.d.ts +5 -0
  46. package/dist/http/routes/workflows.js +337 -0
  47. package/dist/http/run-meta.d.ts +11 -0
  48. package/dist/http/run-meta.js +16 -0
  49. package/dist/http/send.d.ts +7 -0
  50. package/dist/http/send.js +34 -0
  51. package/dist/http/server.d.ts +12 -12
  52. package/dist/http/server.js +289 -5502
  53. package/dist/http/sse-log.d.ts +25 -0
  54. package/dist/http/sse-log.js +59 -0
  55. package/dist/http/wire-types.d.ts +6 -0
  56. package/dist/http/workspace-content.d.ts +3 -0
  57. package/dist/http/workspace-content.js +20 -0
  58. package/dist/leader/endpoint.js +4 -4
  59. package/dist/main.js +5 -5
  60. package/dist/plugins/approval-store-sql.d.ts +52 -0
  61. package/dist/plugins/approval-store-sql.js +119 -0
  62. package/dist/plugins/breaker-state-sql.d.ts +29 -0
  63. package/dist/plugins/breaker-state-sql.js +104 -0
  64. package/dist/plugins/file-snapshot-store-sql.d.ts +38 -0
  65. package/dist/plugins/file-snapshot-store-sql.js +210 -0
  66. package/dist/plugins/image-index-sql.d.ts +33 -0
  67. package/dist/plugins/image-index-sql.js +328 -0
  68. package/dist/plugins/outcome-ledger-sql.d.ts +70 -0
  69. package/dist/plugins/outcome-ledger-sql.js +158 -0
  70. package/dist/plugins/pg-approval-store.d.ts +1 -27
  71. package/dist/plugins/pg-approval-store.js +1 -83
  72. package/dist/plugins/pg-breaker-state.d.ts +1 -19
  73. package/dist/plugins/pg-breaker-state.js +1 -88
  74. package/dist/plugins/pg-file-snapshot-store.d.ts +1 -27
  75. package/dist/plugins/pg-file-snapshot-store.js +1 -190
  76. package/dist/plugins/pg-image-index.d.ts +1 -21
  77. package/dist/plugins/pg-image-index.js +1 -217
  78. package/dist/plugins/pg-outcome-ledger.d.ts +2 -22
  79. package/dist/plugins/pg-outcome-ledger.js +1 -104
  80. package/dist/plugins/pg-resume-anchor-store.d.ts +1 -13
  81. package/dist/plugins/pg-resume-anchor-store.js +1 -22
  82. package/dist/plugins/pg-run-store.d.ts +1 -75
  83. package/dist/plugins/pg-run-store.js +1 -287
  84. package/dist/plugins/pg-session-policy-store.d.ts +1 -11
  85. package/dist/plugins/pg-session-policy-store.js +1 -90
  86. package/dist/plugins/pg-tool-result-store.d.ts +1 -15
  87. package/dist/plugins/pg-tool-result-store.js +1 -52
  88. package/dist/plugins/pg-workflow-journal-store.d.ts +1 -20
  89. package/dist/plugins/pg-workflow-journal-store.js +1 -34
  90. package/dist/plugins/pg-workflow-run-store.d.ts +1 -55
  91. package/dist/plugins/pg-workflow-run-store.js +1 -220
  92. package/dist/plugins/remote-env-host.js +4 -3
  93. package/dist/plugins/resume-anchor-store-sql.d.ts +23 -0
  94. package/dist/plugins/resume-anchor-store-sql.js +38 -0
  95. package/dist/plugins/run-store-sql.d.ts +89 -0
  96. package/dist/plugins/run-store-sql.js +397 -0
  97. package/dist/plugins/session-policy-store-sql.d.ts +22 -0
  98. package/dist/plugins/session-policy-store-sql.js +109 -0
  99. package/dist/plugins/tidb-approval-store.d.ts +1 -39
  100. package/dist/plugins/tidb-approval-store.js +1 -71
  101. package/dist/plugins/tidb-breaker-state.d.ts +1 -17
  102. package/dist/plugins/tidb-breaker-state.js +1 -74
  103. package/dist/plugins/tidb-file-snapshot-store.d.ts +1 -27
  104. package/dist/plugins/tidb-file-snapshot-store.js +1 -192
  105. package/dist/plugins/tidb-image-index.d.ts +1 -19
  106. package/dist/plugins/tidb-image-index.js +1 -149
  107. package/dist/plugins/tidb-outcome-ledger.d.ts +1 -57
  108. package/dist/plugins/tidb-outcome-ledger.js +1 -97
  109. package/dist/plugins/tidb-resume-anchor-store.d.ts +1 -13
  110. package/dist/plugins/tidb-resume-anchor-store.js +1 -22
  111. package/dist/plugins/tidb-run-store.d.ts +1 -75
  112. package/dist/plugins/tidb-run-store.js +1 -306
  113. package/dist/plugins/tidb-session-policy-store.d.ts +1 -11
  114. package/dist/plugins/tidb-session-policy-store.js +1 -86
  115. package/dist/plugins/tidb-tool-result-store.d.ts +1 -13
  116. package/dist/plugins/tidb-tool-result-store.js +1 -38
  117. package/dist/plugins/tidb-workflow-journal-store.d.ts +1 -20
  118. package/dist/plugins/tidb-workflow-journal-store.js +1 -34
  119. package/dist/plugins/tidb-workflow-run-store.d.ts +1 -61
  120. package/dist/plugins/tidb-workflow-run-store.js +1 -231
  121. package/dist/plugins/tool-result-store-sql.d.ts +25 -0
  122. package/dist/plugins/tool-result-store-sql.js +69 -0
  123. package/dist/plugins/workflow-journal-store-sql.d.ts +30 -0
  124. package/dist/plugins/workflow-journal-store-sql.js +53 -0
  125. package/dist/plugins/workflow-run-store-sql.d.ts +85 -0
  126. package/dist/plugins/workflow-run-store-sql.js +299 -0
  127. package/dist/question.js +2 -2
  128. package/dist/run-local.js +1 -1
  129. package/dist/tool-approval.js +2 -2
  130. package/dist/trace/ledger-sink.js +1 -1
  131. package/dist/trace/project.d.ts +1 -0
  132. package/dist/trace/project.js +3 -0
  133. package/package.json +1 -1
@@ -0,0 +1,105 @@
1
+ import { formatUserScope } from "@sema-agent/core";
2
+ import { parseMemorySyncRequest } from "../../memory-sync.js";
3
+ import { sendJson, sendError } from "../send.js";
4
+ import { gatedPrincipal, explicitOperatorOk } from "../principal-gate.js";
5
+ export async function handleMemoryPolicy(req, res, url, ctx) {
6
+ const miss = { fell: false };
7
+ await handleMemoryPolicyBody(req, res, url, ctx, miss);
8
+ return !miss.fell;
9
+ }
10
+ async function handleMemoryPolicyBody(req, res, url, ctx, miss) {
11
+ const { deps } = ctx;
12
+ const { readJson } = ctx.helpers;
13
+ if (url === "/v1/memory/export" && req.method === "GET") {
14
+ const principal = gatedPrincipal(req, deps.config);
15
+ if (!principal) {
16
+ sendError(res, 401, "auth.unauthorized", "unauthorized");
17
+ return;
18
+ }
19
+ if (deps.config.memoryEngineBackend === "file" || !deps.memoryExport) {
20
+ sendError(res, 501, "capability.memory_store_required", "memory export requires a DB memory backend (MEMORY_ENGINE_BACKEND=pg|tidb)");
21
+ return;
22
+ }
23
+ const scope = new URL(req.url ?? "", "http://x").searchParams.get("scope");
24
+ if (!scope) {
25
+ sendError(res, 400, "request.query_invalid", "missing ?scope=<key>");
26
+ return;
27
+ }
28
+ if (scope !== formatUserScope(principal) && !explicitOperatorOk(principal, deps.config.operatorPrincipals)) {
29
+ sendError(res, 404, "not_found.memory_scope", "not found");
30
+ return;
31
+ }
32
+ try {
33
+ const entries = await deps.memoryExport(scope);
34
+ sendJson(res, 200, { scope, exportedAt: new Date().toISOString(), entries });
35
+ }
36
+ catch (err) {
37
+ deps.logger?.warn?.("memory_export_failed", { scope, err: String(err) });
38
+ sendError(res, 500, "internal.error", "memory export failed");
39
+ }
40
+ return;
41
+ }
42
+ if (req.method === "POST" && url.startsWith("/v1/memory/sync/")) {
43
+ const principal = gatedPrincipal(req, deps.config);
44
+ if (!principal) {
45
+ sendError(res, 401, "auth.unauthorized", "unauthorized");
46
+ return;
47
+ }
48
+ if (deps.config.memoryEngineBackend === "file" || !deps.memorySync) {
49
+ sendError(res, 501, "capability.memory_store_required", "memory sync requires a DB memory backend (MEMORY_ENGINE_BACKEND=pg|tidb)");
50
+ return;
51
+ }
52
+ let scope;
53
+ try {
54
+ scope = decodeURIComponent(url.slice("/v1/memory/sync/".length));
55
+ }
56
+ catch {
57
+ sendError(res, 400, "memory_sync_invalid_scope", "malformed percent-encoding in :scope", { code: "memory_sync_invalid_scope" });
58
+ return;
59
+ }
60
+ if (scope.length === 0) {
61
+ sendError(res, 400, "memory_sync_invalid_scope", "missing :scope", { code: "memory_sync_invalid_scope" });
62
+ return;
63
+ }
64
+ if (scope !== formatUserScope(principal) && !explicitOperatorOk(principal, deps.config.operatorPrincipals)) {
65
+ sendError(res, 404, "not_found.memory_scope", "not found");
66
+ return;
67
+ }
68
+ const body = await readJson(req);
69
+ const parsed = parseMemorySyncRequest(body, scope);
70
+ if (!parsed.ok) {
71
+ sendError(res, 422, "memory_sync_invalid_body", parsed.error, { code: "memory_sync_invalid_body" });
72
+ return;
73
+ }
74
+ try {
75
+ const out = await deps.memorySync(scope, parsed.value);
76
+ sendJson(res, 200, out);
77
+ }
78
+ catch (err) {
79
+ deps.logger?.warn?.("memory_sync_failed", { scope, peer: parsed.value.peer, err: String(err) });
80
+ sendError(res, 500, "internal.error", "memory sync failed");
81
+ }
82
+ return;
83
+ }
84
+ if (url === "/v1/policy" && req.method === "GET") {
85
+ const principal = gatedPrincipal(req, deps.config);
86
+ if (deps.config.requirePrincipal && !principal) {
87
+ sendError(res, 401, "auth.principal_required", `missing principal header '${deps.config.principalHeader}'`);
88
+ return;
89
+ }
90
+ sendJson(res, 200, {
91
+ autonomy: deps.config.autonomy ?? null,
92
+ commandPolicy: deps.config.commandPolicy ?? [],
93
+ approvalRequire: deps.config.approvalRequire,
94
+ limits: {
95
+ maxTaskCostUsd: deps.config.maxTaskCostUsd,
96
+ maxTaskTokens: deps.config.maxTaskTokens,
97
+ maxPrincipalCostUsd: deps.config.maxPrincipalCostUsd,
98
+ costQuotaWindowSec: deps.config.costQuotaWindowSec,
99
+ },
100
+ });
101
+ return;
102
+ }
103
+ miss.fell = true;
104
+ }
105
+ //# sourceMappingURL=memory-policy.js.map
@@ -0,0 +1,4 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { RouteCtx } from "../route-ctx.js";
3
+ export declare function handleNotifyWake(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
4
+ //# sourceMappingURL=notify-wake.d.ts.map
@@ -0,0 +1,133 @@
1
+ import { taskNotificationInboxEntry } from "../../orchestration/workflow-completion-inbox.js";
2
+ import { sendJson, sendError } from "../send.js";
3
+ import { gatedPrincipal, explicitOperatorOk } from "../principal-gate.js";
4
+ export async function handleNotifyWake(req, res, url, ctx) {
5
+ const miss = { fell: false };
6
+ await handleNotifyWakeBody(req, res, url, ctx, miss);
7
+ return !miss.fell;
8
+ }
9
+ async function handleNotifyWakeBody(req, res, url, ctx, miss) {
10
+ const { deps } = ctx;
11
+ const { steerableRuns } = ctx.registry;
12
+ const { readJson, rateLimited, quotaExceeded, leaseDenied } = ctx.helpers;
13
+ const { resumeWake } = ctx.legs;
14
+ if (req.method === "POST" && /^\/v1\/sessions\/[^/]+\/notify$/.test(url)) {
15
+ if (rateLimited(req, res) || quotaExceeded(req, res))
16
+ return;
17
+ const principal = gatedPrincipal(req, deps.config);
18
+ if (deps.config.requirePrincipal && principal === undefined) {
19
+ sendError(res, 401, "auth.principal_required", `missing principal header '${deps.config.principalHeader}'`);
20
+ return;
21
+ }
22
+ const notifySession = decodeURIComponent(url.split("/")[3]);
23
+ let nb;
24
+ try {
25
+ nb = (await readJson(req));
26
+ }
27
+ catch {
28
+ sendError(res, 400, "request.body_shape", "body must be JSON: { task_id, status, summary, result?, seq?, source? }");
29
+ return;
30
+ }
31
+ if (typeof nb.task_id !== "string" || nb.task_id.trim().length === 0 || nb.task_id.length > 190) {
32
+ sendError(res, 400, "request.field_invalid", "task_id must be a non-empty string of at most 190 characters");
33
+ return;
34
+ }
35
+ const NOTIFY_STATUSES = ["completed", "failed", "killed", "cancelled", "event"];
36
+ if (typeof nb.status !== "string" || !NOTIFY_STATUSES.includes(nb.status)) {
37
+ sendError(res, 400, "request.field_invalid", `status must be one of ${NOTIFY_STATUSES.join("/")}`);
38
+ return;
39
+ }
40
+ if (typeof nb.summary !== "string" || nb.summary.trim().length === 0) {
41
+ sendError(res, 400, "request.field_invalid", "summary must be a non-empty string");
42
+ return;
43
+ }
44
+ if (nb.result !== undefined && typeof nb.result !== "string") {
45
+ sendError(res, 400, "request.field_invalid", "result must be a string when present");
46
+ return;
47
+ }
48
+ if (nb.seq !== undefined && (typeof nb.seq !== "number" || !Number.isInteger(nb.seq) || nb.seq < 1)) {
49
+ sendError(res, 400, "request.field_invalid", "seq must be a positive integer when present");
50
+ return;
51
+ }
52
+ if (nb.source !== undefined && (typeof nb.source !== "string" || nb.source.length > 190)) {
53
+ sendError(res, 400, "request.field_invalid", "source must be a string of at most 190 characters when present");
54
+ return;
55
+ }
56
+ if (!deps.sessionStorage?.ownerOf) {
57
+ sendError(res, 501, "capability.session_ownership_required", "external notify requires the session-ownership face (sessionStorage.ownerOf)");
58
+ return;
59
+ }
60
+ const notifyOwner = await deps.sessionStorage.ownerOf(notifySession);
61
+ if (notifyOwner === undefined) {
62
+ sendError(res, 404, "not_found.session", "session not found");
63
+ return;
64
+ }
65
+ const notifyOperator = explicitOperatorOk(principal, deps.config.operatorPrincipals);
66
+ if (!notifyOperator && notifyOwner !== null && notifyOwner !== principal) {
67
+ sendError(res, 404, "not_found.session", "session not found");
68
+ return;
69
+ }
70
+ const payload = {
71
+ task_id: nb.task_id,
72
+ status: nb.status,
73
+ summary: nb.summary,
74
+ ...(nb.result !== undefined ? { result: nb.result } : {}),
75
+ ...(nb.seq !== undefined ? { seq: nb.seq } : {}),
76
+ ...(nb.source !== undefined ? { source: nb.source } : {}),
77
+ };
78
+ const liveTaskId = await deps.runStore?.getActiveTaskId?.(notifySession).catch(() => undefined);
79
+ const liveStream = liveTaskId !== undefined && liveTaskId !== null ? steerableRuns.get(liveTaskId) : undefined;
80
+ if (liveStream) {
81
+ try {
82
+ await liveStream.notify(payload);
83
+ sendJson(res, 200, { sessionId: notifySession, delivery: "live" });
84
+ return;
85
+ }
86
+ catch (e) {
87
+ const code = e.code;
88
+ if (typeof code === "string" && code.startsWith("notify.")) {
89
+ sendError(res, 400, code, e instanceof Error ? e.message : "invalid notification");
90
+ return;
91
+ }
92
+ }
93
+ }
94
+ if (!deps.workflowCompletionInbox) {
95
+ sendError(res, 501, "capability.workflow_store_required", "external notify park requires the workflow completion inbox (WORKFLOW_RUN_STORE)");
96
+ return;
97
+ }
98
+ await deps.workflowCompletionInbox.enqueue(taskNotificationInboxEntry(notifySession, notifyOwner ?? principal ?? null, { task_id: payload.task_id, task_type: "external", status: payload.status, summary: payload.summary, ...(payload.result !== undefined ? { result: payload.result } : {}), ...(payload.seq !== undefined ? { seq: payload.seq } : {}), ...(payload.source !== undefined ? { source: payload.source } : {}) }, Date.now()));
99
+ sendJson(res, 202, { sessionId: notifySession, delivery: "parked", note: "no live stream — parked in the session inbox; drained as a task_notification on the next stream open" });
100
+ return;
101
+ }
102
+ if (req.method === "POST" && /^\/v1\/sessions\/[^/]+\/wake$/.test(url)) {
103
+ if (!deps.checkpointStore) {
104
+ sendError(res, 501, "capability.checkpoint_store_required", "wake requires the checkpoint store");
105
+ return;
106
+ }
107
+ if (rateLimited(req, res) || quotaExceeded(req, res) || (await leaseDenied(req, res)))
108
+ return;
109
+ const principal = gatedPrincipal(req, deps.config);
110
+ if (deps.config.requirePrincipal && principal === undefined) {
111
+ sendError(res, 401, "auth.principal_required", `missing principal header '${deps.config.principalHeader}'`);
112
+ return;
113
+ }
114
+ const wakeSession = decodeURIComponent(url.split("/")[3]);
115
+ let wakeBody;
116
+ try {
117
+ wakeBody = (await readJson(req));
118
+ }
119
+ catch {
120
+ sendError(res, 400, "request.body_shape", "body must be JSON: { message?: string }");
121
+ return;
122
+ }
123
+ if (wakeBody.message !== undefined && (typeof wakeBody.message !== "string" || wakeBody.message.length === 0)) {
124
+ sendError(res, 400, "request.field_invalid", "message must be a non-empty string when present");
125
+ return;
126
+ }
127
+ const out = await resumeWake(wakeSession, wakeBody.message, principal, req);
128
+ sendJson(res, out.status, out.body);
129
+ return;
130
+ }
131
+ miss.fell = true;
132
+ }
133
+ //# sourceMappingURL=notify-wake.js.map
@@ -0,0 +1,4 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { RouteCtx } from "../route-ctx.js";
3
+ export declare function handleObservability(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
4
+ //# sourceMappingURL=observability.d.ts.map
@@ -0,0 +1,63 @@
1
+ import { sendJson, sendError } from "../send.js";
2
+ import { gatedPrincipal, isOperator, explicitOperatorOk } from "../principal-gate.js";
3
+ export async function handleObservability(req, res, url, ctx) {
4
+ const miss = { fell: false };
5
+ await handleObservabilityBody(req, res, url, ctx, miss);
6
+ return !miss.fell;
7
+ }
8
+ async function handleObservabilityBody(req, res, url, ctx, miss) {
9
+ const { deps } = ctx;
10
+ if (url === "/v1/outcomes" && req.method === "GET") {
11
+ if (deps.config.requirePrincipal) {
12
+ const principal = gatedPrincipal(req, deps.config);
13
+ if (!explicitOperatorOk(principal, deps.config.operatorPrincipals)) {
14
+ sendError(res, 403, "auth.operator_only", "outcomes view is operator-only on a multi-tenant worker");
15
+ return;
16
+ }
17
+ }
18
+ if (!deps.outcomeSink?.summary) {
19
+ sendError(res, 501, "capability.outcome_ledger_required", "no queryable outcome ledger on this worker (File sink — read the JSONL dataset directly)");
20
+ return;
21
+ }
22
+ const q = new URL(req.url ?? "/", "http://localhost").searchParams;
23
+ const sig = q.get("signature") ?? undefined;
24
+ try {
25
+ const rows = await deps.outcomeSink.summary({ ...(sig ? { taskSignature: sig } : {}), includeAborted: q.get("includeAborted") === "true" });
26
+ sendJson(res, 200, { outcomes: rows });
27
+ }
28
+ catch (err) {
29
+ deps.logger?.warn?.("outcomes_summary_failed", { err: String(err) });
30
+ sendError(res, 500, "internal.error", "outcome summary failed");
31
+ }
32
+ return;
33
+ }
34
+ if (url === "/v1/usage" && req.method === "GET") {
35
+ const principal = gatedPrincipal(req, deps.config);
36
+ if (!principal) {
37
+ sendError(res, 401, "auth.principal_required", `missing principal header '${deps.config.principalHeader}'`);
38
+ return;
39
+ }
40
+ const windowSec = deps.config.costQuotaWindowSec;
41
+ if (!deps.costQuota) {
42
+ sendJson(res, 200, { enabled: false, windowSec, maxTaskCostUsd: deps.config.maxTaskCostUsd, maxTaskTokens: deps.config.maxTaskTokens });
43
+ return;
44
+ }
45
+ const d = deps.costQuota.check(principal);
46
+ sendJson(res, 200, {
47
+ enabled: true,
48
+ windowSec,
49
+ usedMicroUsd: d.usedMicroUsd,
50
+ usedUsd: d.usedMicroUsd / 1_000_000,
51
+ limitMicroUsd: d.limitMicroUsd,
52
+ limitUsd: d.limitMicroUsd / 1_000_000,
53
+ remainingMicroUsd: Math.max(0, d.limitMicroUsd - d.usedMicroUsd),
54
+ overLimit: !d.allowed,
55
+ retryAfterSec: d.retryAfterSec,
56
+ maxTaskCostUsd: deps.config.maxTaskCostUsd,
57
+ maxTaskTokens: deps.config.maxTaskTokens,
58
+ });
59
+ return;
60
+ }
61
+ miss.fell = true;
62
+ }
63
+ //# sourceMappingURL=observability.js.map
@@ -0,0 +1,19 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { RouteCtx } from "../route-ctx.js";
3
+ export declare const RUN_ID_RE: RegExp;
4
+ export declare const RUN_CANCEL_RE: RegExp;
5
+ export declare const RUN_STEER_RE: RegExp;
6
+ export declare const RUN_DETACH_RE: RegExp;
7
+ export declare const RUN_COMPACT_RE: RegExp;
8
+ export declare const ELICIT_RESPOND_RE: RegExp;
9
+ export declare const QUESTION_RESPOND_RE: RegExp;
10
+ export declare const TOOL_APPROVAL_RESPOND_RE: RegExp;
11
+ export declare const RUN_SUBAGENT_STEER_RE: RegExp;
12
+ export declare const RUN_SUBAGENT_RESUME_RE: RegExp;
13
+ export declare const RUN_SUBAGENT_OUTPUT_RE: RegExp;
14
+ export declare const RUN_SUBAGENT_STREAM_RE: RegExp;
15
+ export declare const RUN_TASK_OUTPUT_RE: RegExp;
16
+ export declare const RUN_TASK_STOP_RE: RegExp;
17
+ export declare function handleRuns(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
18
+ export declare function handleRunVerbs(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
19
+ //# sourceMappingURL=runs.d.ts.map