@sema-agent/core 5.2.0 → 5.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/brain/anthropic.js +12 -2
  3. package/dist/brain/media-degrade.d.ts +14 -0
  4. package/dist/brain/media-degrade.js +30 -0
  5. package/dist/brain/openai.js +9 -11
  6. package/dist/brain/timeout.d.ts +14 -0
  7. package/dist/brain/timeout.js +114 -0
  8. package/dist/core/a2a-task-state.d.ts +15 -0
  9. package/dist/core/a2a-task-state.js +68 -0
  10. package/dist/core/a2a.d.ts +42 -0
  11. package/dist/core/a2a.js +651 -0
  12. package/dist/core/checkpoint-store.d.ts +6 -1
  13. package/dist/core/checkpoint-store.js +3 -1
  14. package/dist/core/exec-output-tail.d.ts +0 -1
  15. package/dist/core/exec-output-tail.js +0 -6
  16. package/dist/core/mcp.d.ts +11 -4
  17. package/dist/core/mcp.js +11 -31
  18. package/dist/core/protocol-naming.d.ts +7 -0
  19. package/dist/core/protocol-naming.js +32 -0
  20. package/dist/core/protocol-table.d.ts +3 -1
  21. package/dist/core/protocol-table.js +37 -32
  22. package/dist/core/runner/prepare-task.d.ts +9 -0
  23. package/dist/core/runner/prepare-task.js +52 -15
  24. package/dist/core/runner/runtask.js +34 -4
  25. package/dist/core/runner/tool-disclosure.d.ts +1 -1
  26. package/dist/core/runner/tool-disclosure.js +1 -1
  27. package/dist/core/runner/turn-attachments.d.ts +1 -2
  28. package/dist/core/runner/turn-attachments.js +1 -12
  29. package/dist/core/store-contracts/background-agent-store-contract.d.ts +5 -0
  30. package/dist/core/store-contracts/background-agent-store-contract.js +213 -0
  31. package/dist/core/task-registry-agent.d.ts +14 -1
  32. package/dist/core/task-registry-agent.js +2 -2
  33. package/dist/core/types.d.ts +18 -2
  34. package/dist/engine/execution-env/node-execution-env.d.ts +0 -1
  35. package/dist/engine/execution-env/node-execution-env.js +12 -30
  36. package/dist/index.d.ts +8 -3
  37. package/dist/index.js +6 -2
  38. package/dist/prompt-assembly/event-registry.js +1 -0
  39. package/dist/tools/fs/fs-read.js +5 -3
  40. package/dist/tools/fs/fs-shared.d.ts +1 -0
  41. package/dist/tools/fs/fs-shared.js +1 -0
  42. package/dist/tools/web.js +12 -4
  43. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -40,7 +40,8 @@ export { decideAutoPromote, deriveTripwire, FROZEN_DENYLIST_FLOOR, type AutoProm
40
40
  export { runCascade, type CascadeRung, type CascadeConfig, type CascadeAttempt, type CascadeRunResult, type GateVerdict, } from "./agents/cascade.js";
41
41
  export { pgQuery, mysqlQuery, sqliteQuery } from "./tools/sql-adapters.js";
42
42
  export { materializeMcpTools, MCP_PREFIX, type MaterializedMcp, type McpServerStatus, type McpRefreshResult } from "./core/mcp.js";
43
- export { PROTOCOL_TABLE, MCP_NAMESPACE, protocolOf, type ProtocolNamespace, type ProtocolId } from "./core/protocol-table.js";
43
+ export { materializeA2aTools, A2aRpcError, type MaterializedA2a, type A2aPeerStatus, type A2aRefreshResult, type A2aToolAxis } from "./core/a2a.js";
44
+ export { PROTOCOL_TABLE, MCP_NAMESPACE, A2A_NAMESPACE, protocolOf, type ProtocolNamespace, type ProtocolId } from "./core/protocol-table.js";
44
45
  export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, stripRev, type SessionPolicyStore, type SessionPermissionRules, type StoredSessionRules, type SessionRulesRecord, type PutRulesOptions, } from "./core/session-policy-store.js";
45
46
  export { SAFETY_MERGE_CONFORMANCE_CORPUS, type SafetyMergeVector } from "./core/safety-merge-corpus.js";
46
47
  export { SAFETY_AXIS_VOCABULARY } from "./core/safety-axis-vocab.js";
@@ -163,8 +164,12 @@ export { sessionRepoContract } from "./core/store-contracts/session-repo-contrac
163
164
  export { toolResultStoreContract } from "./core/store-contracts/tool-result-store-contract.js";
164
165
  export { fileSnapshotStoreContract } from "./core/store-contracts/file-snapshot-store-contract.js";
165
166
  export { MAILBOX_CONTRACT_SCOPE, mailboxStoreContract, mailboxAckOwnershipContract, mailboxBundledOnlyContract, } from "./core/store-contracts/mailbox-store-contract.js";
166
- export { type BackgroundAgentStore, type BackgroundAgentRecord, type BackgroundAgentRowSummary, type BackgroundAgentUsage, canAccessAgentRecord, BackgroundAgentStoreError, InMemoryBackgroundAgentStore, reconcileParkedAgents, } from "./core/background-agent-store.js";
167
+ export { BACKGROUND_AGENT_CONTRACT_SCOPE, backgroundAgentStoreContract, backgroundAgentStoreScopesContract, } from "./core/store-contracts/background-agent-store-contract.js";
168
+ export { type BackgroundAgentStore, type BackgroundAgentRecord, type BackgroundAgentRowSummary, type BackgroundAgentUsage, canAccessAgentRecord, STALE_RUNNING_REAP_ATTRIBUTION, BackgroundAgentStoreError, InMemoryBackgroundAgentStore, reconcileParkedAgents, queryBackgroundAgents, type BackgroundAgentQuery, } from "./core/background-agent-store.js";
169
+ export { serveDurableAgentRowLane, buildAgentPollDetails, type AgentPollDetailsInput, } from "./core/task-registry-agent.js";
170
+ export type { UnifiedTaskResult } from "./core/task-registry-shared.js";
167
171
  export { FileBackgroundAgentStore, type FileBackgroundAgentStoreOptions } from "./stores/file/background-agent-store.js";
172
+ export { A2A_TASK_STATES, type A2ATaskState, type A2ATaskStateReversal, type A2ATaskStateReversalFaithful, type A2ATaskStateReversalLossy, toA2ATaskState, fromA2ATaskState, } from "./core/a2a-task-state.js";
168
173
  export { type WorkflowJournalStore, type WorkflowJournalEntry, InMemoryWorkflowJournalStore, callKeyOrdinal, JOURNAL_OVERSIZE_ERROR_CODE, } from "./core/workflow-journal-store.js";
169
174
  export { untrustedEgressForHuman, redactHostLeaks, redactSecrets, boundedRedactedSummary } from "./core/untrusted-egress.js";
170
175
  export type { RedactionFinding, RedactionReport, RedactionConfidence } from "./core/untrusted-egress.js";
@@ -193,7 +198,7 @@ export { retryBackoffMs, parseRetryAfter } from "./brain/retry.js";
193
198
  export { type BrainTimeoutConfig } from "./brain/timeout.js";
194
199
  export { createAssistantMessageEventStream } from "./internal/llm.js";
195
200
  export type { AssistantMessage, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, StopReason, StreamFn, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserMessage, } from "./internal/llm.js";
196
- export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, RuntimeCaps, BackgroundChildEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskResult, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ToolEffect, WorkflowGovernanceBaseline, } from "./core/types.js";
201
+ export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, RuntimeCaps, BackgroundChildEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskResult, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ToolEffect, WorkflowGovernanceBaseline, } from "./core/types.js";
197
202
  export { Type } from "typebox";
198
203
  export type { TSchema, Static } from "typebox";
199
204
  export { explainPromptAssembly, describeDefaultPack, type DefaultPackDescription, type ExplainInput } from "./prompt-assembly/explain.js";
package/dist/index.js CHANGED
@@ -37,7 +37,8 @@ export { decideAutoPromote, deriveTripwire, FROZEN_DENYLIST_FLOOR, } from "./cor
37
37
  export { runCascade, } from "./agents/cascade.js";
38
38
  export { pgQuery, mysqlQuery, sqliteQuery } from "./tools/sql-adapters.js";
39
39
  export { materializeMcpTools, MCP_PREFIX } from "./core/mcp.js";
40
- export { PROTOCOL_TABLE, MCP_NAMESPACE, protocolOf } from "./core/protocol-table.js";
40
+ export { materializeA2aTools, A2aRpcError } from "./core/a2a.js";
41
+ export { PROTOCOL_TABLE, MCP_NAMESPACE, A2A_NAMESPACE, protocolOf } from "./core/protocol-table.js";
41
42
  export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, stripRev, } from "./core/session-policy-store.js";
42
43
  export { SAFETY_MERGE_CONFORMANCE_CORPUS } from "./core/safety-merge-corpus.js";
43
44
  export { SAFETY_AXIS_VOCABULARY } from "./core/safety-axis-vocab.js";
@@ -149,8 +150,11 @@ export { sessionRepoContract } from "./core/store-contracts/session-repo-contrac
149
150
  export { toolResultStoreContract } from "./core/store-contracts/tool-result-store-contract.js";
150
151
  export { fileSnapshotStoreContract } from "./core/store-contracts/file-snapshot-store-contract.js";
151
152
  export { MAILBOX_CONTRACT_SCOPE, mailboxStoreContract, mailboxAckOwnershipContract, mailboxBundledOnlyContract, } from "./core/store-contracts/mailbox-store-contract.js";
152
- export { canAccessAgentRecord, BackgroundAgentStoreError, InMemoryBackgroundAgentStore, reconcileParkedAgents, } from "./core/background-agent-store.js";
153
+ export { BACKGROUND_AGENT_CONTRACT_SCOPE, backgroundAgentStoreContract, backgroundAgentStoreScopesContract, } from "./core/store-contracts/background-agent-store-contract.js";
154
+ export { canAccessAgentRecord, STALE_RUNNING_REAP_ATTRIBUTION, BackgroundAgentStoreError, InMemoryBackgroundAgentStore, reconcileParkedAgents, queryBackgroundAgents, } from "./core/background-agent-store.js";
155
+ export { serveDurableAgentRowLane, buildAgentPollDetails, } from "./core/task-registry-agent.js";
153
156
  export { FileBackgroundAgentStore } from "./stores/file/background-agent-store.js";
157
+ export { A2A_TASK_STATES, toA2ATaskState, fromA2ATaskState, } from "./core/a2a-task-state.js";
154
158
  export { InMemoryWorkflowJournalStore, callKeyOrdinal, JOURNAL_OVERSIZE_ERROR_CODE, } from "./core/workflow-journal-store.js";
155
159
  export { untrustedEgressForHuman, redactHostLeaks, redactSecrets, boundedRedactedSummary } from "./core/untrusted-egress.js";
156
160
  export { MemoryRosterStore, FileRosterStore } from "./agents/roster-store.js";
@@ -5,6 +5,7 @@ export const EVENT_PROMPT_REGISTRY = new Map([
5
5
  { kind: "plan_mode", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#PLAN_MODE_FULL_BODY" },
6
6
  { kind: "date_change", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "always", rendererRef: "turn-attachments.ts#renderDateChange" },
7
7
  { kind: "instructions_change", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", maxBytes: 512, defaultPolicy: "always", rendererRef: "turn-attachments.ts#collectInstructionsChange" },
8
+ { kind: "workflow_size_guideline_change", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "always", rendererRef: "runtask.ts#workflowSizeGuidelineChangeNotice" },
8
9
  { kind: "budget_usd", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#renderBudgetUsd" },
9
10
  { kind: "background_tasks", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#renderBackgroundTasks" },
10
11
  { kind: "tools_delta", carrier: "message.user-prefix", trust: "external", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#renderToolsDelta" },
@@ -5,7 +5,7 @@ import { decodeTextBytes } from "./encoding.js";
5
5
  import { isNotebookPath, parseNotebookCells, renderNotebookCells, stripNotebookImageData, NOTEBOOK_IMAGE_BASE64_BUDGET } from "./notebook.js";
6
6
  import { MCP_IMAGE_MAX_BASE64, IMAGE_TARGET_RAW_SIZE } from "../../core/mcp.js";
7
7
  import { PDF_MAX_PAGES_PER_READ, pdfMagicMatches } from "./pdf.js";
8
- import { MAX_READ_BYTES, SLICED_READ_MAX_BYTES, MAX_IMAGE_READ_BYTES, MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES, resolveAutoDownsampler, MAX_READ_OUTPUT_CHARS, READ_CYBER_REMINDER, FILE_PATH_PARAMS, countLines, seededFileUnchangedReminder, enoentMessage, } from "./fs-shared.js";
8
+ import { MAX_READ_BYTES, SLICED_READ_MAX_BYTES, MAX_IMAGE_READ_BYTES, MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES, NO_DOWNSAMPLER_IMAGE_CAP_HINT, resolveAutoDownsampler, MAX_READ_OUTPUT_CHARS, READ_CYBER_REMINDER, FILE_PATH_PARAMS, countLines, seededFileUnchangedReminder, enoentMessage, } from "./fs-shared.js";
9
9
  import { readPdfFile, pdfResultToToolReturn } from "./fs-pdf.js";
10
10
  export function createReadFileTool(env, state, rootCanonical, cwdRef, additionalRoots, imageDownsampler, pdfCapabilities, bgOutputReadExemption) {
11
11
  return defineTool({
@@ -70,14 +70,16 @@ export function createReadFileTool(env, state, rootCanonical, cwdRef, additional
70
70
  }
71
71
  const downsampler = imageDownsampler === false ? undefined : (imageDownsampler ?? (await resolveAutoDownsampler()));
72
72
  const readCap = downsampler ? MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES : MAX_IMAGE_READ_BYTES;
73
+ const tooLargeToRead = (bytes) => `Error (Read): image "${path}" is too large to read (${bytes} bytes > ${readCap}-byte cap).` +
74
+ (downsampler ? "" : ` ${NO_DOWNSAMPLER_IMAGE_CAP_HINT}`);
73
75
  if (meta.value.size > readCap) {
74
- return errorResult(`Error (Read): image "${path}" is too large to read (${meta.value.size} bytes > ${readCap}-byte cap).`);
76
+ return errorResult(tooLargeToRead(meta.value.size));
75
77
  }
76
78
  const bin = await env.readBinaryFile(r.key, ctx.signal);
77
79
  if (!bin.ok)
78
80
  return errorResult(`Error (Read): cannot read image "${path}": ${bin.error.message}`);
79
81
  if (bin.value.byteLength > readCap) {
80
- return errorResult(`Error (Read): image "${path}" is too large to read (${bin.value.byteLength} bytes > ${readCap}-byte cap).`);
82
+ return errorResult(tooLargeToRead(bin.value.byteLength));
81
83
  }
82
84
  if (!imageMagicMatches(bin.value, imageMime)) {
83
85
  return errorResult(`Error (Read): "${path}" has an image extension but its content is not a valid ${imageMime} (empty, truncated, or mis-named).`);
@@ -18,6 +18,7 @@ export declare function persistedTextOf(encoded: string | Uint8Array): string;
18
18
  export declare function notReadRefusalText(env: ExecutionEnv, toolName: string, key: string, v: Pick<FsViolation, "code" | "message" | "partialView">, signal?: AbortSignal, fallbackHint?: string): Promise<string>;
19
19
  export declare const MAX_IMAGE_READ_BYTES: number;
20
20
  export declare const MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES: number;
21
+ export declare const NO_DOWNSAMPLER_IMAGE_CAP_HINT = "Install the optional \"sharp\" dependency (declared in this package's optionalDependencies) to read images up to 67108864 bytes \u2014 it downsamples them to fit the API image limit.";
21
22
  export type ReadImageDownsamplerOption = ImageDownsampler | false | undefined;
22
23
  export declare function resolveAutoDownsampler(): Promise<ImageDownsampler | undefined>;
23
24
  export declare const MAX_READ_OUTPUT_CHARS = 100000;
@@ -41,6 +41,7 @@ export async function notReadRefusalText(env, toolName, key, v, signal, fallback
41
41
  }
42
42
  export const MAX_IMAGE_READ_BYTES = 5 * 1024 * 1024;
43
43
  export const MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES = 64 * 1024 * 1024;
44
+ export const NO_DOWNSAMPLER_IMAGE_CAP_HINT = `Install the optional "sharp" dependency (declared in this package's optionalDependencies) to read images up to ${MAX_IMAGE_DOWNSAMPLE_INPUT_BYTES} bytes — it downsamples them to fit the API image limit.`;
44
45
  let autoDownsampler;
45
46
  export function resolveAutoDownsampler() {
46
47
  return (autoDownsampler ??= sharpImageDownsampler());
package/dist/tools/web.js CHANGED
@@ -211,11 +211,14 @@ async function fetchAllowlisted(doFetch, start, allowHosts, userAgent, signal, o
211
211
  export function webFetchToolSpec(config = {}) {
212
212
  const maxBytes = config.maxBytes ?? DEFAULT_MAX_BYTES;
213
213
  const doFetch = config.fetchImpl ?? globalThis.fetch;
214
+ const canSummarize = config.summarize !== undefined;
214
215
  return {
215
216
  name: "WebFetch",
216
217
  contract: { contractId: "core.web_fetch@1", implementationRevision: "1" },
217
- description: "Fetches a URL, converts the page to markdown, and answers `prompt` against it when a sub-model is " +
218
- "configured (otherwise returns the markdown).\n" +
218
+ description: (canSummarize
219
+ ? "Fetches a URL, converts the page to markdown, and answers `prompt` against it with a sub-model.\n"
220
+ : "Fetches a URL, converts the page to markdown, and returns the markdown. This deployment has no " +
221
+ "extraction sub-model wired, so pages come back in full for you to read.\n") +
219
222
  "\n" +
220
223
  "- Fails on authenticated/private URLs — use an authenticated MCP tool or `gh` for those instead.\n" +
221
224
  "- Cross-host redirects are returned to you rather than followed; call again with the redirect URL.\n" +
@@ -223,7 +226,9 @@ export function webFetchToolSpec(config = {}) {
223
226
  "hosts are always refused; if an allowlist is configured, only those hosts are reachable.",
224
227
  parameters: Type.Object({
225
228
  url: Type.String({ description: "The URL to fetch content from" }),
226
- prompt: Type.Optional(Type.String({ description: "The prompt to run on the fetched content (uses a sub-model if configured)." })),
229
+ ...(canSummarize
230
+ ? { prompt: Type.Optional(Type.String({ description: "The prompt to run on the fetched content (answered by the configured sub-model)." })) }
231
+ : {}),
227
232
  }),
228
233
  effect: "read",
229
234
  execute: async (args, ctx) => {
@@ -434,9 +439,12 @@ export function webFetchToolSpec(config = {}) {
434
439
  : bodyCut
435
440
  ? `\n\n[WebFetch: ${cutPhrase} — the error body itself was cut off mid-transfer: ${bodyBytes?.length ?? 0} bytes were received before the cutoff and the tail is missing]`
436
441
  : "";
442
+ const promptNote = prompt
443
+ ? `\n\n[note: the requested analysis ("${inlineUntrusted(prompt, 120)}") was NOT applied — the fetch failed with HTTP ${res.status}, so there is no page content to run it against; anything below is the server's error response, not an answer]`
444
+ : "";
437
445
  const content = (excerpt
438
446
  ? `${headline}\nThe error response body${trimmed.length > excerpt.length ? ` (first ${ERROR_BODY_EXCERPT_CHARS} chars)` : ""} follows:\n\n${delimitUntrusted(`WebFetch ${parsed.hostname}`, excerpt)}`
439
- : headline) + bodyStateNote;
447
+ : headline) + bodyStateNote + promptNote;
440
448
  return {
441
449
  content,
442
450
  details: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "5.2.0",
3
+ "version": "5.4.0",
4
4
  "description": "Stateless, task-oriented AI agent core",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",