@sema-agent/server 1.250.0 → 1.252.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/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/fleet/fleet-bus.d.ts.map +1 -1
- package/dist/fleet/fleet-bus.js +1 -1
- package/dist/fleet/fleet-bus.js.map +1 -1
- package/dist/fleet/subagent-tail-bus.d.ts +14 -0
- package/dist/fleet/subagent-tail-bus.d.ts.map +1 -0
- package/dist/fleet/subagent-tail-bus.js +95 -0
- package/dist/fleet/subagent-tail-bus.js.map +1 -0
- package/dist/http/server.d.ts.map +1 -1
- package/dist/http/server.js +95 -0
- package/dist/http/server.js.map +1 -1
- package/dist/main.js +20 -8
- package/dist/main.js.map +1 -1
- package/dist/plugins/background-agent-store-sql.d.ts.map +1 -1
- package/dist/plugins/background-agent-store-sql.js +4 -4
- package/dist/plugins/background-agent-store-sql.js.map +1 -1
- package/dist/plugins/roster-store-sql.d.ts +2 -0
- package/dist/plugins/roster-store-sql.d.ts.map +1 -1
- package/dist/plugins/roster-store-sql.js +8 -0
- package/dist/plugins/roster-store-sql.js.map +1 -1
- package/dist/runs.d.ts.map +1 -1
- package/dist/runs.js +12 -2
- package/dist/runs.js.map +1 -1
- package/package.json +2 -2
package/dist/http/server.js
CHANGED
|
@@ -21,6 +21,7 @@ import { looksLikeJwt } from "../auth-bridge.js";
|
|
|
21
21
|
import { redactSteerIn } from "../orchestration/workflow-agent-steer.js";
|
|
22
22
|
import { emitPendingWorkflowCompletions, taskNotificationInboxEntry, taskNotificationFoldKey, taskNotificationStreamKey, NotifiedKeys } from "../orchestration/workflow-completion-inbox.js";
|
|
23
23
|
import { fleetRunPublisher, fleetRunLabels } from "../fleet/fleet-bus.js";
|
|
24
|
+
import { defaultSubagentTailBus, projectTailFrame } from "../fleet/subagent-tail-bus.js";
|
|
24
25
|
import { RateLimiter } from "../observability/rate-limit.js";
|
|
25
26
|
import { withPrincipal } from "../observability/principal-context.js";
|
|
26
27
|
import { projectEvents, runSummary, mapTraceEvent, toolStartEventData, toolEndEventData, taskProgressEventData, taskNotificationEventData, compactedEventData, diagnosticsEventData, brainStatusEventData, appendModelUsageDelta, appendPromptManifest, attachModelUsage } from "../trace/project.js";
|
|
@@ -168,6 +169,7 @@ const WORKFLOW_AGENT_STEER_RE = /^\/v1\/workflows\/([^/]+)\/agents\/([^/]+)\/ste
|
|
|
168
169
|
const RUN_SUBAGENT_STEER_RE = /^\/v1\/runs\/([^/]+)\/subagents\/([^/]+)\/steer$/;
|
|
169
170
|
const RUN_SUBAGENT_RESUME_RE = /^\/v1\/runs\/([^/]+)\/subagents\/([^/]+)\/resume$/;
|
|
170
171
|
const RUN_SUBAGENT_OUTPUT_RE = /^\/v1\/runs\/([^/]+)\/subagents\/([^/]+)\/output$/;
|
|
172
|
+
const RUN_SUBAGENT_STREAM_RE = /^\/v1\/runs\/([^/]+)\/subagents\/([^/]+)\/stream$/;
|
|
171
173
|
const RUN_TASK_OUTPUT_RE = /^\/v1\/runs\/([^/]+)\/tasks\/([^/]+)\/output$/;
|
|
172
174
|
const RUN_TASK_STOP_RE = /^\/v1\/runs\/([^/]+)\/tasks\/([^/]+)\/stop$/;
|
|
173
175
|
const HAND_TOOL_NAMES = Object.keys(HAND_TOOL_EFFECTS);
|
|
@@ -677,6 +679,7 @@ export function createHttpServer(deps) {
|
|
|
677
679
|
appendSystemPrompt: true,
|
|
678
680
|
compactionModel: true,
|
|
679
681
|
subagentOutput: Boolean(deps.subagentTaskOutput) && Boolean(deps.runStore),
|
|
682
|
+
subagentStream: Boolean(deps.subagentTaskOutput) && Boolean(deps.runStore),
|
|
680
683
|
taskHandles: Boolean(deps.taskHandleOutput) && Boolean(deps.taskHandleStop) && Boolean(deps.runStore),
|
|
681
684
|
taskAgents: deps.config.requirePrincipal !== true,
|
|
682
685
|
retainBackgroundProcesses: deps.config.requirePrincipal !== true,
|
|
@@ -982,6 +985,14 @@ export function createHttpServer(deps) {
|
|
|
982
985
|
onForwardEvent: (e) => {
|
|
983
986
|
fleetPub?.onForwardEvent(e);
|
|
984
987
|
ledgerSink?.onForwardEvent(e);
|
|
988
|
+
{
|
|
989
|
+
const bg = e.bgAgentId;
|
|
990
|
+
if (bg !== undefined && defaultSubagentTailBus.hasSubscribers(bg)) {
|
|
991
|
+
const f = projectTailFrame(e);
|
|
992
|
+
if (f)
|
|
993
|
+
defaultSubagentTailBus.publish(bg, f);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
985
996
|
if (res.writableEnded)
|
|
986
997
|
return;
|
|
987
998
|
const t = e.type;
|
|
@@ -1008,6 +1019,9 @@ export function createHttpServer(deps) {
|
|
|
1008
1019
|
onTaskNotification: (n) => {
|
|
1009
1020
|
if (n.task_type === "workflow")
|
|
1010
1021
|
return;
|
|
1022
|
+
if (defaultSubagentTailBus.hasSubscribers(n.task_id)) {
|
|
1023
|
+
defaultSubagentTailBus.publish(n.task_id, { type: "task_settled", taskId: n.task_id, status: n.status, ...(n.summary ? { summary: redactSecrets(n.summary) } : {}) });
|
|
1024
|
+
}
|
|
1011
1025
|
const hadRow = fleetPub?.onChildTerminal(n.sessionId ?? n.task_id, n.status, n.task_id, n.toolUseId) ?? false;
|
|
1012
1026
|
const deliverable = syncLegLive && !res.writableEnded && !res.destroyed;
|
|
1013
1027
|
const parked = !deliverable && Boolean(deps.workflowCompletionInbox && prepared.spec.sessionId);
|
|
@@ -1975,6 +1989,76 @@ export function createHttpServer(deps) {
|
|
|
1975
1989
|
sendJson(res, 200, { taskId: runId, target, content: out.content, output: out.details });
|
|
1976
1990
|
return;
|
|
1977
1991
|
}
|
|
1992
|
+
const subStreamMatch = req.method === "GET" ? RUN_SUBAGENT_STREAM_RE.exec(url) : null;
|
|
1993
|
+
if (subStreamMatch) {
|
|
1994
|
+
if (!deps.runStore || !deps.subagentTaskOutput) {
|
|
1995
|
+
sendJson(res, 501, { error: "subagent streams require the run store" });
|
|
1996
|
+
return;
|
|
1997
|
+
}
|
|
1998
|
+
const principal = gatedPrincipal(req, deps.config);
|
|
1999
|
+
if (deps.config.requirePrincipal && principal === undefined) {
|
|
2000
|
+
sendJson(res, 401, { error: `missing principal header '${deps.config.principalHeader}'` });
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
2003
|
+
const runId = safeDecode(subStreamMatch[1]);
|
|
2004
|
+
const target = safeDecode(subStreamMatch[2]);
|
|
2005
|
+
if (runId === null || target === null) {
|
|
2006
|
+
sendJson(res, 400, { error: "malformed subagent path (invalid percent-encoding)" });
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
2009
|
+
const trusted = explicitOperatorOk(principal, deps.config.operatorPrincipals);
|
|
2010
|
+
const run = await deps.runStore.getRun(runId);
|
|
2011
|
+
if (!run || (!trusted && run.owner !== null && run.owner !== principal)) {
|
|
2012
|
+
sendJson(res, 404, { error: "run not found" });
|
|
2013
|
+
return;
|
|
2014
|
+
}
|
|
2015
|
+
const callerSession = new URL(req.url ?? "", "http://x").searchParams.get("session");
|
|
2016
|
+
if (!trusted && run.sessionId && callerSession !== run.sessionId) {
|
|
2017
|
+
sendJson(res, 404, { error: "run not found" });
|
|
2018
|
+
return;
|
|
2019
|
+
}
|
|
2020
|
+
const probe = await deps.subagentTaskOutput(target, { owner: runId, scope: run.owner ?? "default", ...(run.sessionId ? { sessionId: run.sessionId } : {}) });
|
|
2021
|
+
const probeDetails = probe.details;
|
|
2022
|
+
if (probeDetails?.error === "not_found" || probeDetails?.type !== "background_agent") {
|
|
2023
|
+
sendJson(res, 404, { error: `no background agent "${target}" under this run (unknown handle, not this run's child, or already reaped — bg children live in the replica-local registry for the parent's lifetime; wa… workflow-agent rows are read via the workflow journal, not this verb)` });
|
|
2024
|
+
return;
|
|
2025
|
+
}
|
|
2026
|
+
sseHeaders(res);
|
|
2027
|
+
res.write(`event: meta\ndata: ${JSON.stringify({ version: 1, runId, target, status: probeDetails.status ?? "running", live: "replica-local", replayFace: "GET /v1/runs/:id/subagents/:handle/output" })}\n\n`);
|
|
2028
|
+
if (probeDetails.status !== "running" && probeDetails.status !== "pending") {
|
|
2029
|
+
res.end();
|
|
2030
|
+
return;
|
|
2031
|
+
}
|
|
2032
|
+
const it = defaultSubagentTailBus.subscribe(target);
|
|
2033
|
+
let closed = false;
|
|
2034
|
+
const hb = setInterval(() => {
|
|
2035
|
+
if (!res.writableEnded)
|
|
2036
|
+
res.write(`event: heartbeat\ndata: {}\n\n`);
|
|
2037
|
+
}, 15_000);
|
|
2038
|
+
if (typeof hb.unref === "function")
|
|
2039
|
+
hb.unref();
|
|
2040
|
+
req.on("close", () => {
|
|
2041
|
+
closed = true;
|
|
2042
|
+
void it.return?.();
|
|
2043
|
+
});
|
|
2044
|
+
try {
|
|
2045
|
+
for (;;) {
|
|
2046
|
+
const n = await it.next();
|
|
2047
|
+
if (n.done || closed || res.writableEnded)
|
|
2048
|
+
break;
|
|
2049
|
+
res.write(`event: forward\ndata: ${JSON.stringify(n.value)}\n\n`);
|
|
2050
|
+
if (n.value.type === "task_settled")
|
|
2051
|
+
break;
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
finally {
|
|
2055
|
+
clearInterval(hb);
|
|
2056
|
+
void it.return?.();
|
|
2057
|
+
if (!res.writableEnded)
|
|
2058
|
+
res.end();
|
|
2059
|
+
}
|
|
2060
|
+
return;
|
|
2061
|
+
}
|
|
1978
2062
|
const taskVerbMatch = req.method === "GET" ? RUN_TASK_OUTPUT_RE.exec(url) : req.method === "POST" ? RUN_TASK_STOP_RE.exec(url) : null;
|
|
1979
2063
|
if (taskVerbMatch) {
|
|
1980
2064
|
const stopVerb = req.method === "POST";
|
|
@@ -4875,6 +4959,14 @@ export function createHttpServer(deps) {
|
|
|
4875
4959
|
const stream = await deps.runner.resumeStream(token, outcome, { ...taskConfig, signal: cancelCtrl.signal, preemptSignal: preemptCtrl.signal }, {
|
|
4876
4960
|
onForwardEvent: (e) => {
|
|
4877
4961
|
fleetPub?.onForwardEvent(e);
|
|
4962
|
+
{
|
|
4963
|
+
const bg = e.bgAgentId;
|
|
4964
|
+
if (bg !== undefined && defaultSubagentTailBus.hasSubscribers(bg)) {
|
|
4965
|
+
const f = projectTailFrame(e);
|
|
4966
|
+
if (f)
|
|
4967
|
+
defaultSubagentTailBus.publish(bg, f);
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4878
4970
|
if (!rs || !taskId)
|
|
4879
4971
|
return;
|
|
4880
4972
|
const t = e.type;
|
|
@@ -4891,6 +4983,9 @@ export function createHttpServer(deps) {
|
|
|
4891
4983
|
onTaskNotification: (n) => {
|
|
4892
4984
|
if (n.task_type === "workflow")
|
|
4893
4985
|
return;
|
|
4986
|
+
if (defaultSubagentTailBus.hasSubscribers(n.task_id)) {
|
|
4987
|
+
defaultSubagentTailBus.publish(n.task_id, { type: "task_settled", taskId: n.task_id, status: n.status, ...(n.summary ? { summary: redactSecrets(n.summary) } : {}) });
|
|
4988
|
+
}
|
|
4894
4989
|
const hadRow = fleetPub?.onChildTerminal(n.sessionId ?? n.task_id, n.status, n.task_id, n.toolUseId) ?? false;
|
|
4895
4990
|
const parked = !resumeLegLive && Boolean(deps.workflowCompletionInbox && sessionId);
|
|
4896
4991
|
deps.logger?.info?.("task_notification_observed", { route: "resume", taskId: n.task_id, taskType: n.task_type, status: n.status, hadFleetRow: hadRow, legLive: resumeLegLive, parkedDurable: parked });
|