@sema-agent/server 7.6.0 → 7.7.1

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/main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
- import { Runner, TtlSessionStore, uuidv7, defaultTaskRegistry, createAllowDenyPolicy, workflowsCapability, createWebFetchSummarizer, resolveTaskModel as coreResolveTaskModel, probeSearchBackend, describeStaticWiring } from "@sema-agent/core";
4
+ import { Runner, InMemoryToolResultStore, TtlSessionStore, uuidv7, defaultTaskRegistry, createAllowDenyPolicy, workflowsCapability, createWebFetchSummarizer, resolveTaskModel as coreResolveTaskModel, probeSearchBackend, describeStaticWiring } from "@sema-agent/core";
5
5
  import { createSessionTitler } from "./session-titler.js";
6
6
  import { posIntEnv } from "./session-watch.js";
7
7
  import { selectEnvironmentTool } from "./capabilities/select-environment-tool.js";
@@ -18,6 +18,7 @@ import { assertGateIntentServiceable, hasOperatorGateIntent } from "./approval.j
18
18
  import { loadSkills } from "./capabilities/skills.js";
19
19
  import { GiteaClient } from "./capabilities/repo-tools.js";
20
20
  import { buildScenarios, builtinScenarioDetails } from "./capabilities/scenarios.js";
21
+ import { createHandsLaneRegistry, pickHandsRunner, withoutExecutionEnv } from "./capabilities/hands-lane.js";
21
22
  import { createLogger } from "./observability/logger.js";
22
23
  import { createToolTracer, createPermissionDeniedMeter } from "./observability/tool-trace.js";
23
24
  import { createRegistryJwtVerifier } from "./auth-bridge.js";
@@ -193,16 +194,54 @@ async function main() {
193
194
  const { principalCaps, centerRuntimeCapsResolver, runtimeCapsResolver } = createRuntimeCaps({ config, logger });
194
195
  // design/170 件A(#148 件3③):org 记忆准入装配(目录源三态选择+C12 能力探测,坏配置在此拒启动)。
195
196
  const orgMemoryAdmission = createOrgMemoryAdmissionWiring({ config, logger, metrics });
197
+ // 🔴 codex 复审(#196 finding-2b):`toolResultStore` 在**无 backend** 形下是 undefined,而 core 的
198
+ // Runner 构造函数会在缺席时**每只各自私建**一份 `RunnerSharedToolResultStore`(runtask.js
199
+ // `if (!this.deps.toolResultStore)`)。本部署有多只 Runner(主 / subRunner / hookAgent / #196 的两只无手
200
+ // 孪生),私建 ⇒ 每只一个独立店 ⇒ A 车道 offload 出去的 `ReadToolResult` 引用在 B 车道解引用不到
201
+ // (fork 子任务跨 runner 读父的 offload 是既有可达形,#196 的车道分家又多了一条)。这里显式铸**一份**
202
+ // 共享兜底(参数与 core 私建那只逐字相同:`RunnerSharedToolResultStore` 是 `InMemoryToolResultStore`
203
+ // 的空子类,cap 64M chars),只喂 Runner 侧。
204
+ // ⚠️ 刻意**不动** `toolResultStore` 本身:那个键的「present ⇔ durable 后端在场」语义还管着 E21 purge、
205
+ // reaper 清扫、leader 装配与 /health 的接线自述(改它会让无 backend 的部署自述成 "shared(sql)" = 谎)。
206
+ const runnerOffloadStore = toolResultStore ?? new InMemoryToolResultStore({ maxTotalChars: 64_000_000 });
196
207
  // design/158 A10:RunnerDeps 装配段搬到 src/boot/runner-deps.ts(逐字;runStore 晚绑改取值,见该文件头注)。
197
208
  const runnerDeps = createRunnerDeps({
198
209
  config, logger, metrics, localRoot, promptSource: configCenter.promptSource, rosterStore, backgroundAgentStore, mailboxStore, usageWindowStore, brain,
199
210
  pricing, tracer, outcomeSink, elicitation, question, toolApproval, sessionStore, memoryEngine,
200
- memorySyncRunner, toolResultStore, sessionPolicyStore, runtimeCapsResolver, fileSnapshotStore,
211
+ memorySyncRunner, toolResultStore: runnerOffloadStore, sessionPolicyStore, runtimeCapsResolver, fileSnapshotStore,
201
212
  executionEnvFactory, lspManager, fleetBus, deploymentHooks, workflowRunStore, workflowJournalStore,
202
213
  workflowAgentRegistry, workflowNotifyGate, workflowCompletionInbox, deliverWorkflowCompletion, orgMemoryAdmission,
203
214
  getRunStore: () => runStore,
204
215
  });
205
216
  const runner = new Runner(runnerDeps);
217
+ // #196:`runner` 的无手孪生 —— 同 deps 同实例(sessionStore/toolResultStore/checkpointStore… 全共享,
218
+ // `Runner.sessions` 就是传进去的那只 store,两只 Runner 不会各持一份会话缓存),唯独不挂
219
+ // `executionEnvFactory`。core 的 `handsEnabled = ownedEnv || deps.executionEnv` 是 **per-Runner** 合同,
220
+ // 单 runner 服务全场景时结构上无法逐场景兑现 —— 这只孪生就是兑现它的那一半(设计小票 §2a)。
221
+ // 声明 hands:"none" 的场景(scan / code-review 两腿 / team / center overlay)在 HTTP 执行点被路由到这里。
222
+ //
223
+ // 🔴 两条**已知边界**(codex 复审 2026-08-09 两轮提出,逐条亲验 core dist 后如实记账;两条的部署条件
224
+ // 互不相同 —— 不要把它们并成一句)。
225
+ //
226
+ // ① 会话锁是 **per-Runner** 的(core runtask.js 的 `sessionLocks` Map,每只 Runner 一份)。
227
+ // **条件:无 store backend 的部署形**。有 runStore 时同会话并发提交被服务端的 run 认领挡成 409
228
+ // (routes/tasks.ts:317 / routes/runs.ts:335 的 `createRun` 认领),两车道并发结构上不可达;无
229
+ // backend 的部署没有那道认领,同一 sessionId 上「一条 full + 一条 none」并发就失去了修前由单
230
+ // Runner 提供的串行化。同类缺口本就存在(subRunner 经 ForkRoutingSessionStore 也会碰宿主会话),
231
+ // 本件让它多一条可达路径。补偿:配任一 backend(含 `DB_BACKEND=local`)即恢复认领。
232
+ //
233
+ // ② 升级窗的旧 checkpoint。**条件恰恰相反:必须有 checkpointStore**(= 有 backend + DURABLE_APPROVAL),
234
+ // 且部署在 REMOTE_EXEC 车道上 —— 修前建立的 hands=none 场景 durable checkpoint 会带 workspaceHandle
235
+ // (可挂起 env 的快照形,以及**非**可挂起远端 env 的 `restoreMode:"park_only"` 形,两者都算;审批 park
236
+ // 与 resource suspend 都会写),续跑时被路由到这只无手 Runner,core 在 **CAS 之前**抛
237
+ // `CheckpointError("checkpoint.unsupported_version", "checkpoint has a remote workspaceHandle but no
238
+ // RunnerDeps.executionEnvFactory is wired to rebuild the env")`(runtask.js:3704)。
239
+ // 本仓的分类表把该码归 **TERMINAL**(http/server.ts 的 CheckpointError 分支):run 行被 `setTerminal`
240
+ // 成 failed 并**释放** task_active,响应 409 携带该 errorCode —— 会话**不会**被占住到 TTL,运维重提该
241
+ // 任务即可。故这是**响亮的、有界的**升级窗代价,不是静默损坏;但它是行为面的升级注记,发车说明必须写。
242
+ // ⚠️ 未覆盖登记:本形需要「真 durable 店 + 带 workspaceHandle 的旧 checkpoint」才能驱动,本批未建格
243
+ // (属真双库/迁移测试面)—— 移交主会话裁定是否要做 checkpoint 感知的续跑选路或启动期预检。
244
+ const handslessRunner = new Runner(withoutExecutionEnv(runnerDeps));
206
245
  // codex R10: TRUE ⇒ the Runner just froze a PRIVATE tier-expanded catalog copy (core runtask.js constructor,
207
246
  // dist-read) — in-place model-plane mutation no longer reaches it, so refresh-time plane changes must be
208
247
  // DEFERRED to restart (see appliedPlaneEff / applyEffective deferModelPlane). Captured HERE, at the same
@@ -321,7 +360,7 @@ async function main() {
321
360
  // (子会话住私有 TTL 店,park 前整树拷进 host durable 店——只查不迁的 1.263 形在拆店生产形下恒
322
361
  // 否决 park,cli 真机 14ms~2s expired 即此)。
323
362
  const subRunnerSessions = new ForkRoutingSessionStore(sessionStore, new TtlSessionStore({ defaultTtlDays: 1 / 24 }));
324
- const subRunner = new Runner({
363
+ const subRunnerDeps = {
325
364
  // [1543]§三族A 结构性根治(design/158 冲刺尾件):与主 runnerDeps 重复的 ~15 键统一走
326
365
  // createSharedRunnerDeps 展开——「双点挂载」从人工纪律变结构性保证(新共享键漏配其一=不可能,
327
366
  // 基座只有一份)。差异键在展开后显式列出,每个都有为何不同的理由(见 boot/runner-deps.ts 头注)。
@@ -337,7 +376,7 @@ async function main() {
337
376
  mailboxStore,
338
377
  rosterStore,
339
378
  deploymentHooks,
340
- toolResultStore,
379
+ toolResultStore: runnerOffloadStore,
341
380
  sessionPolicyStore,
342
381
  usageWindowStore,
343
382
  orgMemoryAdmission,
@@ -359,7 +398,13 @@ async function main() {
359
398
  // TaskStop on parked 走 expire CAS 仲裁(1.389 F-1);/decide 可赎回。行为钉 =
360
399
  // test/subagent-park-wiring.test.ts(SOURCE PIN + park 全链 + 旧形反向控制)。
361
400
  checkpointStore: checkpointStore ? checkpointStore : undefined,
362
- });
401
+ };
402
+ const subRunner = new Runner(subRunnerDeps);
403
+ // #196:`subRunner` 的无手孪生(同一份 deps 字面量摘掉 executionEnvFactory —— 差异面只有这一处,
404
+ // 结构上不可能漂移)。council 的 lens/arbiter、team 的成员/synthesizer 走它:那些子任务的人格声明
405
+ // 里一件工具都没有,却在修前照拿全量可写手(设计小票 §1 里最意外的一支)。
406
+ // ⚠️ 与主 subRunner 共享 `subRunnerSessions` 与 `checkpointStore` 同实例 —— park/fork 的行是同一批。
407
+ const handslessSubRunner = new Runner(withoutExecutionEnv(subRunnerDeps));
363
408
  // S6: resolve identity + owned session from the authenticated channel (never the body).
364
409
  const authorize = createAuthorizer(config, sessionStore);
365
410
  // S1/S2: durable async run registry + replayable event log (TiDB-backed).
@@ -598,7 +643,7 @@ async function main() {
598
643
  // design/158 S4:标注 `: ScenarioDeps` —— 无标注的字面量连自己的键名都不校验(打错/多写一个键
599
644
  // 只是多一个没人读的属性,编译期无声),这是 1.304 落错家那一族的另一半土壤。
600
645
  const scenarioDeps = {
601
- runner, subRunner, model: "default", skills, repoClient, requirePrincipal: config.requirePrincipal,
646
+ runner, subRunner, handslessSubRunner, model: "default", skills, repoClient, requirePrincipal: config.requirePrincipal,
602
647
  webSearch: webSearch ? webSearch : undefined, metrics, logger, webFetchSummarize,
603
648
  // core 1.364 写半场:与 RunnerDeps.backgroundAgentStore 同实例(组装区注释;半接=静默死特性)。
604
649
  backgroundAgentStore: backgroundAgentStore ? backgroundAgentStore : undefined,
@@ -898,8 +943,12 @@ async function main() {
898
943
  // 帽只在 watch 面在场时才有意义(缺席时路由 501,读不到它)——保持与原条件段同门,不单独接线。
899
944
  sessionEventsMaxConnections: sessionWatchRegistry ? posIntEnv(process.env.SESSION_EVENTS_MAX_CONNS, 256, 100_000) : undefined,
900
945
  };
946
+ // #196:hands lane 登记簿 —— resolveSpec 登记本请求场景的表态,HTTP 执行点凭 spec 取回选 Runner。
947
+ // 两处**同一实例**(交给 createResolveSpec 与 runnerFor 闭包),配对由这一行结构性保证。
948
+ const handsLanes = createHandsLaneRegistry();
901
949
  // design/158 A10:resolveSpec 段搬到 src/boot/resolve-spec.ts(逐字;两处活引用改取值,见该文件头注)。
902
950
  const resolveSpec = createResolveSpec({
951
+ handsLanes,
903
952
  config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver,
904
953
  getCenterPrompts: () => configCenter.getCenterPrompts(),
905
954
  getKeyResolver: () => configCenter.getKeyResolver(),
@@ -910,7 +959,9 @@ async function main() {
910
959
  sessionEnvSelection,
911
960
  liveQuestionFace: question, // #152:活体问答面在场 ⇒ durable question 门按活流分腿(见 ResolveSpecCtx 注)
912
961
  });
913
- const server = createHttpServer({ runner, config, resolveSpec, stores, coordinators, seams, observability, governance, deployment, knobs });
962
+ // #196:执行点选路。resolveSpec 已按场景判别位登记 lane;`full` 恒回主 runner(修前行为逐字不变)
963
+ const runnerFor = (spec) => pickHandsRunner(handsLanes.laneOf(spec), { full: runner, handsless: handslessRunner });
964
+ const server = createHttpServer({ runner, runnerFor, config, resolveSpec, stores, coordinators, seams, observability, governance, deployment, knobs });
914
965
  // D-D SLA-timer: wire the server's deny-sweep into the reaper holder declared above (the reaper is defined
915
966
  // before the server, so it calls through this late-bound reference).
916
967
  runDenySweep = server.denyExpiredApprovals;
@@ -25,6 +25,19 @@ export declare function createPermissionDeniedMeter(metrics: Pick<Metrics, "inc"
25
25
  *
26
26
  * Pure observation: every hook returns `undefined`, so it never rewrites args, never gates, never alters
27
27
  * the result (and per core's hooks invariant a hook's `allow` can't bypass the policy gate anyway).
28
+ *
29
+ * 🔴 core 5.20.0 起这条「纯观察」性质必须**声明**出来(`preToolUseObservational`),不能只写在注释里:
30
+ * core 5.19.0 的委派折叠按「PreToolUse 席位在不在」把父的 screening 面折进子代的祖先约束链——它分不出
31
+ * 诊断 tracer 与真裁决者。后果是**这个默认关的诊断旋钮**一开,该部署所有 hook-wired 父的 parked 子代
32
+ * checkpoint 就记 `parentConstraintCount=2`,而跨副本赎回腿(`boot/parked-revive-gate.ts`)恒供 1 ⇒
33
+ * core pre-CAS 响亮拒、行永久 pending(层数 park 时写死,事后关旋钮/重批/回滚都不改)。
34
+ * 声明之后该面不铸链条目,count 回到 1,病路消灭。
35
+ * ⛔ 打这个标的前提是**真的一条裁决都不出**:core 对声明了却返回判词的面是「拒绝采纳 + onError 告警」
36
+ * (classification `observational-hook-verdict-ignored`),即判词被静默丢弃——把标打到会裁决的面上比原
37
+ * 缺陷更坏。本文件三个 pre/post 回调恒返 `undefined`,`permissionDenied` 本就是 void 观察槽。
38
+ * 📎 连带的**可观测**变化(不是回归):core 的「可写工具面无 effect-aware 门」启动告警此前把本 tracer
39
+ * 算作一道门而被抑制;声明之后它不再算,于是「没配任何 policy 层 + 开着 TOOL_TRACE」的部署升级后会
40
+ * 多出那行告警。方向正确——tracer 从来没有门住任何东西,原先的抑制本身就是一次静默 fail-open。
28
41
  */
29
42
  export declare function createToolTracer(logger: Logger): Hooks;
30
43
  //# sourceMappingURL=tool-trace.d.ts.map
@@ -33,9 +33,23 @@ export function createPermissionDeniedMeter(metrics) {
33
33
  *
34
34
  * Pure observation: every hook returns `undefined`, so it never rewrites args, never gates, never alters
35
35
  * the result (and per core's hooks invariant a hook's `allow` can't bypass the policy gate anyway).
36
+ *
37
+ * 🔴 core 5.20.0 起这条「纯观察」性质必须**声明**出来(`preToolUseObservational`),不能只写在注释里:
38
+ * core 5.19.0 的委派折叠按「PreToolUse 席位在不在」把父的 screening 面折进子代的祖先约束链——它分不出
39
+ * 诊断 tracer 与真裁决者。后果是**这个默认关的诊断旋钮**一开,该部署所有 hook-wired 父的 parked 子代
40
+ * checkpoint 就记 `parentConstraintCount=2`,而跨副本赎回腿(`boot/parked-revive-gate.ts`)恒供 1 ⇒
41
+ * core pre-CAS 响亮拒、行永久 pending(层数 park 时写死,事后关旋钮/重批/回滚都不改)。
42
+ * 声明之后该面不铸链条目,count 回到 1,病路消灭。
43
+ * ⛔ 打这个标的前提是**真的一条裁决都不出**:core 对声明了却返回判词的面是「拒绝采纳 + onError 告警」
44
+ * (classification `observational-hook-verdict-ignored`),即判词被静默丢弃——把标打到会裁决的面上比原
45
+ * 缺陷更坏。本文件三个 pre/post 回调恒返 `undefined`,`permissionDenied` 本就是 void 观察槽。
46
+ * 📎 连带的**可观测**变化(不是回归):core 的「可写工具面无 effect-aware 门」启动告警此前把本 tracer
47
+ * 算作一道门而被抑制;声明之后它不再算,于是「没配任何 policy 层 + 开着 TOOL_TRACE」的部署升级后会
48
+ * 多出那行告警。方向正确——tracer 从来没有门住任何东西,原先的抑制本身就是一次静默 fail-open。
36
49
  */
37
50
  export function createToolTracer(logger) {
38
51
  return {
52
+ preToolUseObservational: true,
39
53
  preToolUse(toolName, input, ctx) {
40
54
  logger.info("tool_trace", { phase: "pre", id: ctx.toolCallId, tool: toolName, arg: summarize(input) });
41
55
  return undefined;
package/dist/run-local.js CHANGED
@@ -56,6 +56,7 @@ import { loadSkills } from "./capabilities/skills.js";
56
56
  import { GiteaClient } from "./capabilities/repo-tools.js";
57
57
  import { webSearchConfigFromEnv, createWebSearchBackend } from "./plugins/web-search.js";
58
58
  import { buildScenarios, selectScenario, centerScenarios } from "./capabilities/scenarios.js";
59
+ import { pickHandsRunner, withoutExecutionEnv } from "./capabilities/hands-lane.js";
59
60
  import { HttpError } from "./security.js";
60
61
  import { memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
61
62
  import { createMemorySyncRunner, createMemorySyncTransport } from "./memory-sync-client.js";
@@ -495,7 +496,7 @@ export async function runLocal(argv, deps = {}) {
495
496
  ...(ctx.classification !== undefined ? { classification: ctx.classification } : {}),
496
497
  err: String(err),
497
498
  });
498
- const runner = new Runner({
499
+ const runnerDeps = {
499
500
  brain,
500
501
  models: config.models,
501
502
  roles: config.roles,
@@ -521,14 +522,21 @@ export async function runLocal(argv, deps = {}) {
521
522
  ...(config.projectMemoryEnabled
522
523
  ? { loadProjectMemory: makeLoadProjectMemory({ logger }), probeInstructionSources: makeProbeInstructionSources() }
523
524
  : {}),
524
- });
525
+ };
526
+ const runner = new Runner(runnerDeps);
525
527
  // Sub-task runner (council lenses/team) — mirrors main.ts's subRunner, INCLUDING executionEnvFactory so a delegated
526
528
  // child gets hands (Bash/Read/Edit) on the host lane. Without it the child's handsEnabled is false — the exact
527
529
  // "subagent couldn't run pwd" defect fixed at main.ts:799; this is its run-local twin, caught by the systematic audit.
528
530
  // [1367]① fork server half(main.ts subRunner 同款):ForkRoutingSessionStore——fork/resume 形
529
531
  // (requireExisting)→ host 文件店优先(core 1.350 hostSessionFork 在宿主店 fork,拆店=响亮
530
532
  // resume.session_not_found),普通子任务 → 私有 TTL 店(throwaway 姿势保留)。
531
- const subRunner = new Runner({ brain, models: config.models, roles: config.roles, pricing, promptSource, sessionStore: new ForkRoutingSessionStore(sessionStore, new TtlSessionStore({ defaultTtlDays: 1 / 24 })), onError: engineOnError, onAsk, ...(executionEnvFactory ? { executionEnvFactory } : {}), ...(lspManager ? { lspManager } : {}) });
533
+ const subRunnerDeps = { brain, models: config.models, roles: config.roles, pricing, promptSource, sessionStore: new ForkRoutingSessionStore(sessionStore, new TtlSessionStore({ defaultTtlDays: 1 / 24 })), onError: engineOnError, onAsk, ...(executionEnvFactory ? { executionEnvFactory } : {}), ...(lspManager ? { lspManager } : {}) };
534
+ const subRunner = new Runner(subRunnerDeps);
535
+ // #196:无手孪生一对 —— **mirrors main.ts**(那边是 `handslessRunner` / `handslessSubRunner` 两只,同 deps
536
+ // 摘掉 executionEnvFactory)。run-local 是同形装配点,漏这一对 = 本地 lane 上 scan/council/team 的最终
537
+ // roster 仍被并集进全量可写手(server 修了、CLI 静默留病 —— 这条腿的 subRunner 当年就是这么漏配的)。
538
+ const handslessRunner = new Runner(withoutExecutionEnv(runnerDeps));
539
+ const handslessSubRunner = new Runner(withoutExecutionEnv(subRunnerDeps));
532
540
  // Capability layer (loadSkills + buildScenarios + selectScenario) — assembled exactly like main.ts.
533
541
  const skills = loadSkills(config.skillsDir);
534
542
  const repoClient = config.gitApiBaseUrl ? new GiteaClient(config.gitApiBaseUrl, config.gitApiToken) : undefined;
@@ -537,7 +545,7 @@ export async function runLocal(argv, deps = {}) {
537
545
  const webSearchCfg = webSearchConfigFromEnv();
538
546
  const webSearch = webSearchCfg ? createWebSearchBackend(webSearchCfg) : undefined;
539
547
  const scenarioDeps = {
540
- runner, subRunner, model: "default", skills, repoClient, metrics, logger,
548
+ runner, subRunner, handslessSubRunner, model: "default", skills, repoClient, metrics, logger,
541
549
  ...(webSearch ? { webSearch } : {}),
542
550
  brandIdentity: true, // run-local is always a local/TOC deployment → brand the default scenario as Sema.
543
551
  };
@@ -617,8 +625,10 @@ export async function runLocal(argv, deps = {}) {
617
625
  // ── Run ONE task to completion (the sync /v1/tasks path: plain runTask, no verify/cascade). ──
618
626
  let result;
619
627
  let exitCode = 0;
628
+ // #196:与 HTTP 腿同一条选路 —— 场景声明 hands:"none" 时任务跑无手 Runner(band 不 mount)。
629
+ const taskRunner = pickHandsRunner(cap.hands, { full: runner, handsless: handslessRunner });
620
630
  try {
621
- result = await runner.runTask(spec);
631
+ result = await taskRunner.runTask(spec);
622
632
  }
623
633
  catch (err) {
624
634
  printErr(`task crashed: ${err instanceof Error ? err.message : String(err)}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "7.6.0",
3
+ "version": "7.7.1",
4
4
  "description": "Sema Server — the server/API implementation layer for Sema, wiring core, registry, model providers, and cloud agent execution. Built on @sema-agent/core.",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",
@@ -54,7 +54,7 @@
54
54
  "build:binary:run-local:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 src/run-local.ts --outfile dist/run-local-darwin-arm64"
55
55
  },
56
56
  "dependencies": {
57
- "@sema-agent/core": "^5.19.0",
57
+ "@sema-agent/core": "^5.21.0",
58
58
  "@sema-agent/registry-core": "^0.16.0",
59
59
  "e2b": "^2.28.0",
60
60
  "libsodium-wrappers": "^0.8.4",
@@ -69,7 +69,7 @@
69
69
  "sharp": "^0.35.3"
70
70
  },
71
71
  "devDependencies": {
72
- "@sema-agent/sdk": "^6.9.0",
72
+ "@sema-agent/sdk": "^6.10.0",
73
73
  "@types/libsodium-wrappers": "^0.7.14",
74
74
  "@types/node": "22.10.2",
75
75
  "@types/pg": "^8.20.0",