@sema-agent/core 2.3.0 → 2.4.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/agents/send-message-tool.d.ts +4 -0
- package/dist/agents/send-message-tool.js +37 -24
- package/dist/agents/subagent.js +275 -127
- package/dist/brain/errors.d.ts +1 -0
- package/dist/brain/errors.js +14 -0
- package/dist/brain/stream-engine.js +3 -3
- package/dist/core/context-edit.js +2 -1
- package/dist/core/runner/prepare-task.js +20 -1
- package/dist/core/runner/tool-output-projection.js +2 -1
- package/dist/core/store-contracts/checkpoint-store-contract.d.ts +37 -0
- package/dist/core/store-contracts/checkpoint-store-contract.js +195 -0
- package/dist/core/store-contracts/contract-harness.d.ts +6 -0
- package/dist/core/store-contracts/contract-harness.js +16 -0
- package/dist/core/store-contracts/contract-kit-version.d.ts +1 -0
- package/dist/core/store-contracts/contract-kit-version.js +2 -0
- package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +3 -0
- package/dist/core/store-contracts/file-snapshot-store-contract.js +126 -0
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +6 -0
- package/dist/core/store-contracts/mailbox-store-contract.js +193 -0
- package/dist/core/store-contracts/session-repo-contract.d.ts +3 -0
- package/dist/core/store-contracts/session-repo-contract.js +36 -0
- package/dist/core/store-contracts/tool-result-store-contract.d.ts +3 -0
- package/dist/core/store-contracts/tool-result-store-contract.js +35 -0
- package/dist/core/task-notification.d.ts +2 -0
- package/dist/core/task-registry-agent.d.ts +4 -0
- package/dist/core/task-registry-agent.js +13 -0
- package/dist/core/task-registry-monitor.js +6 -6
- package/dist/core/task-registry-shared.d.ts +8 -2
- package/dist/core/task-registry-shared.js +1 -1
- package/dist/core/task-registry.d.ts +6 -0
- package/dist/core/task-registry.js +48 -4
- package/dist/core/tool-result-store.d.ts +3 -2
- package/dist/core/tool-result-store.js +12 -4
- package/dist/core/trace.d.ts +7 -0
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -0
- package/dist/engine/lsp/node-lsp-manager.js +16 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/orchestration/builtin-workflows.d.ts +1 -1
- package/dist/orchestration/builtin-workflows.js +11 -2
- package/dist/orchestration/workflow-governance.d.ts +6 -1
- package/dist/orchestration/workflow-governance.js +24 -4
- package/dist/orchestration/workflow-primitives.js +7 -1
- package/dist/orchestration/workflow.d.ts +1 -0
- package/dist/orchestration/workflow.js +31 -2
- package/dist/tools/fs/fs-bash.d.ts +7 -1
- package/dist/tools/fs/fs-bash.js +51 -20
- package/dist/tools/fs/fs-read.js +22 -11
- package/dist/tools/fs/fs-search-tools.js +3 -3
- package/dist/tools/fs/fs-shared.d.ts +20 -7
- package/dist/tools/fs/fs-shared.js +17 -3
- package/dist/tools/fs/fs-write.js +4 -4
- package/dist/tools/fs/index.d.ts +2 -0
- package/dist/tools/fs/index.js +7 -1
- package/dist/tools/fs/repo-map.js +2 -2
- package/dist/tools/fs/safety.d.ts +10 -0
- package/dist/tools/fs/safety.js +15 -1
- package/dist/tools/monitor.js +18 -4
- package/dist/tools/web.js +6 -2
- package/dist/tools/worktree.js +46 -25
- package/package.json +1 -1
|
@@ -21,6 +21,8 @@ export interface SendMessageToolOptions {
|
|
|
21
21
|
senderName?: string;
|
|
22
22
|
roster?: import("./roster-store.js").RosterStore;
|
|
23
23
|
siblingRetain?: SubagentRetainLedger;
|
|
24
|
+
parentTaskId?: string;
|
|
25
|
+
parentSessionId?: string;
|
|
24
26
|
onBackgroundChildEvent?: (event: import("../core/types.js").BackgroundChildEvent) => void;
|
|
25
27
|
agentStore?: import("../core/background-agent-store.js").BackgroundAgentStore;
|
|
26
28
|
mailbox?: import("../core/mailbox-store.js").MailboxStore;
|
|
@@ -34,6 +36,8 @@ export interface SendMessageToolOptions {
|
|
|
34
36
|
details?: unknown;
|
|
35
37
|
}>;
|
|
36
38
|
}
|
|
39
|
+
export declare const SEND_MESSAGE_SUMMARY_MAX = 200;
|
|
40
|
+
export declare function clipSendMessageSummary(raw: string): string;
|
|
37
41
|
export declare function createSendMessageTool(opts: SendMessageToolOptions): import("../core/types.js").AgentTool<Type.TObject<{
|
|
38
42
|
to: Type.TString;
|
|
39
43
|
message: Type.TString;
|
|
@@ -8,6 +8,12 @@ import { createSubagentResume } from "./subagent.js";
|
|
|
8
8
|
export const SEND_MESSAGE_TOOL_NAME = "SendMessage";
|
|
9
9
|
let uplinkSeqGlobal = Date.now();
|
|
10
10
|
const UPLINK_RESULT_MAX = 8000;
|
|
11
|
+
export const SEND_MESSAGE_SUMMARY_MAX = 200;
|
|
12
|
+
export function clipSendMessageSummary(raw) {
|
|
13
|
+
return raw.length > SEND_MESSAGE_SUMMARY_MAX
|
|
14
|
+
? `${raw.slice(0, SEND_MESSAGE_SUMMARY_MAX)} [summary truncated: ${raw.length} chars total]`
|
|
15
|
+
: raw;
|
|
16
|
+
}
|
|
11
17
|
const TEAMMATE_MESSAGE_TAG = "teammate-message";
|
|
12
18
|
function frameTeammateMessage(args) {
|
|
13
19
|
const summaryAttr = args.summary !== undefined ? ` summary="${escapeAttributeValue(args.summary)}"` : "";
|
|
@@ -84,6 +90,9 @@ export function createSendMessageTool(opts) {
|
|
|
84
90
|
};
|
|
85
91
|
}
|
|
86
92
|
const senderId = ctx.taskId ?? opts.owner;
|
|
93
|
+
const [parentTaskId, parentSessionId] = ctx.parentTaskId !== undefined ? [ctx.parentTaskId, ctx.parentSessionId] : [opts.parentTaskId, opts.parentSessionId];
|
|
94
|
+
const senderIsChild = parentTaskId !== undefined || opts.uplink !== undefined || opts.senderName !== undefined || opts.siblingRetain !== undefined;
|
|
95
|
+
const senderLabel = opts.senderName ?? (senderIsChild ? senderId ?? "main" : "main");
|
|
87
96
|
if (senderId !== undefined && isObserverTaskId(senderId)) {
|
|
88
97
|
return { content: OBSERVER_SENDMESSAGE_SENDER_REFUSAL, details: { error: "observer_sender" }, isError: true };
|
|
89
98
|
}
|
|
@@ -92,7 +101,7 @@ export function createSendMessageTool(opts) {
|
|
|
92
101
|
}
|
|
93
102
|
if (normalizeAgentName(to) === "main") {
|
|
94
103
|
if (opts.uplink && senderId !== undefined) {
|
|
95
|
-
const uplinkSummaryRaw = typeof a.summary === "string" && a.summary.trim() !== "" ? a.summary.trim()
|
|
104
|
+
const uplinkSummaryRaw = typeof a.summary === "string" && a.summary.trim() !== "" ? clipSendMessageSummary(a.summary.trim()) : message.slice(0, 80);
|
|
96
105
|
const fromLabel = opts.senderName !== undefined ? opts.senderName : senderId;
|
|
97
106
|
try {
|
|
98
107
|
opts.uplink({
|
|
@@ -112,11 +121,7 @@ export function createSendMessageTool(opts) {
|
|
|
112
121
|
details: { type: "send-message", status: "uplinked", to: "main", seq: uplinkSeqGlobal },
|
|
113
122
|
};
|
|
114
123
|
}
|
|
115
|
-
|
|
116
|
-
opts.uplink !== undefined ||
|
|
117
|
-
opts.senderName !== undefined ||
|
|
118
|
-
opts.siblingRetain !== undefined;
|
|
119
|
-
if (!hasParent) {
|
|
124
|
+
if (!senderIsChild) {
|
|
120
125
|
return {
|
|
121
126
|
content: `You are the main conversation — "main" addresses you. Send to a named agent instead.`,
|
|
122
127
|
details: { error: "main_is_self", to },
|
|
@@ -151,9 +156,9 @@ export function createSendMessageTool(opts) {
|
|
|
151
156
|
if (!row)
|
|
152
157
|
return undefined;
|
|
153
158
|
if (!canAccessAgentRecord(row, access)) {
|
|
154
|
-
if (
|
|
159
|
+
if (parentTaskId === undefined)
|
|
155
160
|
return undefined;
|
|
156
|
-
const parentView = { ...access, owner:
|
|
161
|
+
const parentView = { ...access, owner: parentTaskId, ...(parentSessionId !== undefined ? { sessionId: parentSessionId } : {}) };
|
|
157
162
|
if (!canAccessAgentRecord(row, parentView))
|
|
158
163
|
return undefined;
|
|
159
164
|
}
|
|
@@ -271,10 +276,10 @@ export function createSendMessageTool(opts) {
|
|
|
271
276
|
};
|
|
272
277
|
}
|
|
273
278
|
const clipped = message.length > UPLINK_RESULT_MAX ? `${message.slice(0, UPLINK_RESULT_MAX)}\n[message truncated: ${message.length} chars total]` : message;
|
|
274
|
-
const t3Summary = typeof a.summary === "string" && a.summary.trim() !== "" ? a.summary.trim()
|
|
275
|
-
const t3From =
|
|
279
|
+
const t3Summary = typeof a.summary === "string" && a.summary.trim() !== "" ? clipSendMessageSummary(a.summary.trim()) : undefined;
|
|
280
|
+
const t3From = senderLabel;
|
|
276
281
|
try {
|
|
277
|
-
await opts.mailbox.append(scope, handle, {
|
|
282
|
+
await opts.mailbox.append(scope, handle, { from: t3From, content: t3Summary !== undefined ? `[${t3Summary}] ${clipped}` : clipped, sentAt: now });
|
|
278
283
|
}
|
|
279
284
|
catch (e) {
|
|
280
285
|
await rollback();
|
|
@@ -340,8 +345,8 @@ export function createSendMessageTool(opts) {
|
|
|
340
345
|
};
|
|
341
346
|
let idRow = opts.registry.getAccessibleTask(to, access);
|
|
342
347
|
let resolvedAccess = access;
|
|
343
|
-
if (!idRow &&
|
|
344
|
-
const parentView = { ...access, owner:
|
|
348
|
+
if (!idRow && parentTaskId !== undefined) {
|
|
349
|
+
const parentView = { ...access, owner: parentTaskId, ...(parentSessionId !== undefined ? { sessionId: parentSessionId } : {}) };
|
|
345
350
|
const siblingById = opts.registry.getAccessibleTask(to, parentView);
|
|
346
351
|
if (siblingById) {
|
|
347
352
|
idRow = siblingById;
|
|
@@ -356,8 +361,8 @@ export function createSendMessageTool(opts) {
|
|
|
356
361
|
let target = idRow;
|
|
357
362
|
if (!target) {
|
|
358
363
|
let byName = opts.registry.resolveBackgroundAgentByName(to, access);
|
|
359
|
-
if (byName.status === "not_found" &&
|
|
360
|
-
const parentView = { ...access, owner:
|
|
364
|
+
if (byName.status === "not_found" && parentTaskId !== undefined) {
|
|
365
|
+
const parentView = { ...access, owner: parentTaskId, ...(parentSessionId !== undefined ? { sessionId: parentSessionId } : {}) };
|
|
361
366
|
const sibling = opts.registry.resolveBackgroundAgentByName(to, parentView);
|
|
362
367
|
if (sibling.status === "found" || sibling.status === "ambiguous") {
|
|
363
368
|
byName = sibling;
|
|
@@ -412,8 +417,8 @@ export function createSendMessageTool(opts) {
|
|
|
412
417
|
}
|
|
413
418
|
if (row.status === "running" || row.status === "pending") {
|
|
414
419
|
return await withTargetLane(targetLaneKey(access.scope, targetId), async () => {
|
|
415
|
-
const s2Summary = typeof a.summary === "string" && a.summary.trim() !== "" ? a.summary.trim()
|
|
416
|
-
const fromLabel =
|
|
420
|
+
const s2Summary = typeof a.summary === "string" && a.summary.trim() !== "" ? clipSendMessageSummary(a.summary.trim()) : undefined;
|
|
421
|
+
const fromLabel = senderLabel;
|
|
417
422
|
const s2Clipped = message.length > UPLINK_RESULT_MAX
|
|
418
423
|
? `${message.slice(0, UPLINK_RESULT_MAX)}\n[message truncated: ${message.length} chars total]`
|
|
419
424
|
: message;
|
|
@@ -444,11 +449,19 @@ export function createSendMessageTool(opts) {
|
|
|
444
449
|
isError: true,
|
|
445
450
|
};
|
|
446
451
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
+
const nowRow = opts.registry.getAccessibleTask(targetId, resolvedAccess);
|
|
453
|
+
const stillLive = nowRow !== undefined && (nowRow.status === "running" || nowRow.status === "pending");
|
|
454
|
+
return stillLive
|
|
455
|
+
? {
|
|
456
|
+
content: `Message not sent: ${who} is still starting up (it has not begun reading messages yet) — the message was not delivered. Send again shortly.`,
|
|
457
|
+
details: { error: "settle_race", to },
|
|
458
|
+
isError: true,
|
|
459
|
+
}
|
|
460
|
+
: {
|
|
461
|
+
content: `Message not sent: ${who} just finished (delivery raced its completion). Send again to continue it from its transcript.`,
|
|
462
|
+
details: { error: "settle_race", to },
|
|
463
|
+
isError: true,
|
|
464
|
+
};
|
|
452
465
|
});
|
|
453
466
|
}
|
|
454
467
|
if (row.status === "killed") {
|
|
@@ -510,8 +523,8 @@ export function createSendMessageTool(opts) {
|
|
|
510
523
|
...(row.rootSessionId !== undefined ? { rowRootSessionId: row.rootSessionId } : {}),
|
|
511
524
|
...(opts.notify ? { currentParentNotify: opts.notify } : {}),
|
|
512
525
|
});
|
|
513
|
-
const summary = typeof a.summary === "string" && a.summary.trim() !== "" ? a.summary.trim()
|
|
514
|
-
const fromPrefix =
|
|
526
|
+
const summary = typeof a.summary === "string" && a.summary.trim() !== "" ? clipSendMessageSummary(a.summary.trim()) : undefined;
|
|
527
|
+
const fromPrefix = parentTaskId !== undefined ? `(message from teammate "${opts.senderName ?? senderId ?? "unknown"}")\n` : "";
|
|
515
528
|
try {
|
|
516
529
|
const safeSummary = summary !== undefined ? escapeEnvelopeTag(TEAMMATE_MESSAGE_TAG, summary) : undefined;
|
|
517
530
|
const safeMessage = escapeEnvelopeTag(TEAMMATE_MESSAGE_TAG, message);
|