@sema-agent/core 5.55.0 → 5.56.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 (42) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/agents/send-message-tool.js +48 -2
  3. package/dist/agents/subagent.js +250 -89
  4. package/dist/core/auto-compaction.d.ts +17 -4
  5. package/dist/core/auto-compaction.js +3 -0
  6. package/dist/core/context-edit.d.ts +55 -6
  7. package/dist/core/context-edit.js +12 -1
  8. package/dist/core/hooks.d.ts +293 -11
  9. package/dist/core/hooks.js +158 -11
  10. package/dist/core/human-input-projection.d.ts +20 -2
  11. package/dist/core/human-input-projection.js +9 -0
  12. package/dist/core/permission-rules.d.ts +23 -15
  13. package/dist/core/permission-rules.js +40 -31
  14. package/dist/core/runner/prepare-task.d.ts +8 -0
  15. package/dist/core/runner/prepare-task.js +34 -23
  16. package/dist/core/runner/runtask.js +158 -21
  17. package/dist/core/runner/session-rule-policy.js +5 -5
  18. package/dist/core/session-reconcile.d.ts +32 -0
  19. package/dist/core/session-reconcile.js +15 -0
  20. package/dist/core/task-notification.d.ts +34 -7
  21. package/dist/core/task-notification.js +11 -1
  22. package/dist/core/task-registry-agent.d.ts +20 -3
  23. package/dist/core/task-registry-agent.js +31 -2
  24. package/dist/core/tool-policy.d.ts +14 -9
  25. package/dist/core/tool-policy.js +27 -22
  26. package/dist/core/types.d.ts +37 -11
  27. package/dist/core/untrusted-text.js +8 -0
  28. package/dist/engine/compaction/compaction.d.ts +77 -7
  29. package/dist/engine/compaction/compaction.js +98 -9
  30. package/dist/engine/compaction/utils.d.ts +4 -0
  31. package/dist/engine/compaction/utils.js +6 -0
  32. package/dist/engine/harness/agent-harness.d.ts +84 -0
  33. package/dist/engine/harness/agent-harness.js +88 -12
  34. package/dist/engine/harness/messages.d.ts +4 -2
  35. package/dist/engine/harness/messages.js +7 -2
  36. package/dist/engine/harness/types.d.ts +11 -5
  37. package/dist/engine/loop/types.d.ts +7 -0
  38. package/dist/engine/session/import-validate.js +10 -0
  39. package/dist/engine/session/session.js +2 -2
  40. package/dist/orchestration/run-spec.js +8 -1
  41. package/dist/prompts/default.d.ts +10 -4
  42. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { asAgentMessage, createCompactionSummaryMessage, createCustomMessage, } from "../harness/messages.js";
2
2
  import { SessionError, isValidModelChange, normalizeAnnouncedListing, normalizeCompactionStateCarrier, normalizeGitAnnouncement, normalizeReminderMark, normalizeWorkspaceState } from "../harness/types.js";
3
3
  import { normalizePromptEpoch } from "../../prompt-assembly/epoch.js";
4
- import { budgetInvokedSkillsRetention, readElidedMessages, readRetainedInvokedSkills, renderInvokedSkillsRetention, } from "../compaction/utils.js";
4
+ import { budgetInvokedSkillsRetention, readElidedMessages, readRetainedInvokedSkills, readUnsummarizedMessages, renderInvokedSkillsRetention, } from "../compaction/utils.js";
5
5
  const RETENTION_CLAMP_DEFAULT_CHARS_PER_TOKEN = 4;
6
6
  const RETENTION_CLAMP_WINDOW_FRACTION = 0.5;
7
7
  export function buildSessionContext(pathEntries, opts) {
@@ -67,7 +67,7 @@ export function buildSessionContext(pathEntries, opts) {
67
67
  retainedSkills = budgetInvokedSkillsRetention(retainedSkills, budgetChars);
68
68
  }
69
69
  const retainedSkillsBlock = renderInvokedSkillsRetention(retainedSkills);
70
- messages.push(asAgentMessage(createCompactionSummaryMessage(compaction.summary + retainedSkillsBlock, compaction.tokensBefore, compaction.timestamp, readElidedMessages(compaction.details))));
70
+ messages.push(asAgentMessage(createCompactionSummaryMessage(compaction.summary + retainedSkillsBlock, compaction.tokensBefore, compaction.timestamp, readElidedMessages(compaction.details), readUnsummarizedMessages(compaction.details))));
71
71
  const compactionIdx = pathEntries.findIndex((e) => e.type === "compaction" && e.id === compaction.id);
72
72
  let foundFirstKept = false;
73
73
  for (let i = 0; i < compactionIdx; i++) {
@@ -114,6 +114,9 @@ export async function runSpec(runner, contract, opts) {
114
114
  postCompact: (opts.taskSpec.hooks.postCompact ?? deployBaseline.hooks.postCompact)?.bind(opts.taskSpec.hooks.postCompact ? opts.taskSpec.hooks : deployBaseline.hooks),
115
115
  stopFailure: (opts.taskSpec.hooks.stopFailure ?? deployBaseline.hooks.stopFailure)?.bind(opts.taskSpec.hooks.stopFailure ? opts.taskSpec.hooks : deployBaseline.hooks),
116
116
  permissionDenied: (opts.taskSpec.hooks.permissionDenied ?? deployBaseline.hooks.permissionDenied)?.bind(opts.taskSpec.hooks.permissionDenied ? opts.taskSpec.hooks : deployBaseline.hooks),
117
+ ...((opts.taskSpec.hooks.timeoutMs ?? deployBaseline.hooks.timeoutMs) !== undefined
118
+ ? { timeoutMs: opts.taskSpec.hooks.timeoutMs ?? deployBaseline.hooks.timeoutMs }
119
+ : {}),
117
120
  }
118
121
  : (opts.taskSpec.hooks ?? deployBaseline?.hooks);
119
122
  let guardRestores = 0;
@@ -130,10 +133,14 @@ export async function runSpec(runner, contract, opts) {
130
133
  ...(userHooks?.postCompact && { postCompact: userHooks.postCompact.bind(userHooks) }),
131
134
  ...(userHooks?.stopFailure && { stopFailure: userHooks.stopFailure.bind(userHooks) }),
132
135
  ...(userHooks?.permissionDenied && { permissionDenied: userHooks.permissionDenied.bind(userHooks) }),
136
+ ...(userHooks?.timeoutMs !== undefined ? { timeoutMs: userHooks.timeoutMs } : {}),
133
137
  async stop(ctx) {
134
138
  guardRestores += restoreFrozenPaths(snapshot, rootDir);
135
139
  if (!gateAbandoned) {
136
- const report = await runOracle(contract.oracle, rootDir, { baseline, signal: opts.taskSpec.signal });
140
+ const gateSignal = ctx.signal !== undefined && opts.taskSpec.signal !== undefined ? AbortSignal.any([ctx.signal, opts.taskSpec.signal]) : (ctx.signal ?? opts.taskSpec.signal);
141
+ const report = await runOracle(contract.oracle, rootDir, { baseline, ...(gateSignal !== undefined ? { signal: gateSignal } : {}) });
142
+ if (ctx.signal?.aborted === true)
143
+ return undefined;
137
144
  oracleRuns++;
138
145
  if (report.verdict === "red") {
139
146
  oracleHadRedRun = true;
@@ -142,8 +142,8 @@ export declare const CYBER_RISK = "IMPORTANT: Assist with authorized security te
142
142
  export declare const URL_SAFETY = "IMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident that the URLs are for helping the user with programming. You may use URLs provided by the user in their messages or local files.";
143
143
  /**
144
144
  * Tool-result retention reminder (design/64 §6.2 C). Always injected: core's in-task context management
145
- * (`clearStaleToolResults`) unconditionally clears old tool-result content before each request, so the
146
- * model must persist anything load-bearing into its own response.
145
+ * (`clearStaleToolResults`) can clear old tool-result content out of a request, and compaction can
146
+ * replace it with prose, so the model must persist anything load-bearing into its own response.
147
147
  *
148
148
  * RB-328 — CITATION CORRECTED. Source = the CC **88 readable tree**
149
149
  * (`collection-claude-code-source-code/original-source-code/src/constants/prompts.ts:841`,
@@ -157,8 +157,14 @@ export declare const URL_SAFETY = "IMPORTANT: You must NEVER generate or guess U
157
157
  * context-management claim (`_My` @596605-596612, the "The system will automatically compress prior
158
158
  * messages … your conversation with the user is not limited by the context window" line — an
159
159
  * overclaim {@link harnessHeadLines} explicitly refuses to copy). So 220 clears results without ever
160
- * telling the model to save what mattered. sema keeps the instruction: its clear is unconditional and
161
- * runs before EVERY request, which is a stronger reason to warn than CC's.
160
+ * telling the model to save what mattered. sema keeps the instruction and the REASON is now stated
161
+ * as measured rather than as remembered (anchoring re-check 2026-08-23): the earlier wording here
162
+ * ("its clear is unconditional and runs before EVERY request") is false about our own engine.
163
+ * `clearStaleToolResults` returns the original array untouched while the estimate is within
164
+ * `editBudget` (= `contextEditFrontier`, e.g. 167000 on a 200k window) — probed: under budget, same
165
+ * reference, zero clears. What is true, and is warning enough, is that a long session meets THREE
166
+ * removers: this pass once the frontier is crossed, the compaction boundary's summary, and the
167
+ * per-message aggregate tool-result budget, which sheds the largest results at any size.
162
168
  */
163
169
  export declare const SUMMARIZE_TOOL_RESULTS = "When working with tool results, write down any important information you might need later in your own response, as the original tool result may be cleared or summarized from the context later.";
164
170
  export declare const EXECUTION_ENVIRONMENT: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "5.55.0",
3
+ "version": "5.56.0",
4
4
  "description": "Stateless, task-oriented AI agent core",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",