@sema-agent/server 1.191.0 → 1.193.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 (55) hide show
  1. package/dist/budget.d.ts.map +1 -1
  2. package/dist/budget.js.map +1 -1
  3. package/dist/capabilities/sandbox-file-send.d.ts +2 -0
  4. package/dist/capabilities/sandbox-file-send.d.ts.map +1 -1
  5. package/dist/capabilities/sandbox-file-send.js +45 -7
  6. package/dist/capabilities/sandbox-file-send.js.map +1 -1
  7. package/dist/capabilities/send-user-file-tool.d.ts.map +1 -1
  8. package/dist/capabilities/send-user-file-tool.js +2 -1
  9. package/dist/capabilities/send-user-file-tool.js.map +1 -1
  10. package/dist/config.d.ts +1 -0
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +1 -0
  13. package/dist/config.js.map +1 -1
  14. package/dist/env-facts.d.ts +5 -0
  15. package/dist/env-facts.d.ts.map +1 -1
  16. package/dist/env-facts.js +38 -1
  17. package/dist/env-facts.js.map +1 -1
  18. package/dist/http/server.d.ts +2 -1
  19. package/dist/http/server.d.ts.map +1 -1
  20. package/dist/http/server.js +24 -7
  21. package/dist/http/server.js.map +1 -1
  22. package/dist/main.js +36 -6
  23. package/dist/main.js.map +1 -1
  24. package/dist/orchestration/workflow-completion-inbox.d.ts.map +1 -1
  25. package/dist/orchestration/workflow-completion-inbox.js +1 -2
  26. package/dist/orchestration/workflow-completion-inbox.js.map +1 -1
  27. package/dist/plugins/s3-presign.d.ts +16 -0
  28. package/dist/plugins/s3-presign.d.ts.map +1 -1
  29. package/dist/plugins/s3-presign.js +35 -4
  30. package/dist/plugins/s3-presign.js.map +1 -1
  31. package/dist/plugins/send-file-ledger.d.ts.map +1 -1
  32. package/dist/plugins/send-file-ledger.js +12 -4
  33. package/dist/plugins/send-file-ledger.js.map +1 -1
  34. package/dist/plugins/send-user-file.d.ts.map +1 -1
  35. package/dist/plugins/send-user-file.js +82 -12
  36. package/dist/plugins/send-user-file.js.map +1 -1
  37. package/dist/runs.d.ts.map +1 -1
  38. package/dist/runs.js +5 -2
  39. package/dist/runs.js.map +1 -1
  40. package/dist/security.d.ts +2 -0
  41. package/dist/security.d.ts.map +1 -1
  42. package/dist/security.js +4 -2
  43. package/dist/security.js.map +1 -1
  44. package/dist/sighup-idle.d.ts +1 -0
  45. package/dist/sighup-idle.d.ts.map +1 -1
  46. package/dist/sighup-idle.js +7 -6
  47. package/dist/sighup-idle.js.map +1 -1
  48. package/dist/spec-fields.d.ts +1 -0
  49. package/dist/spec-fields.d.ts.map +1 -1
  50. package/dist/spec-fields.js +5 -0
  51. package/dist/spec-fields.js.map +1 -1
  52. package/dist/tool-approval.d.ts.map +1 -1
  53. package/dist/tool-approval.js +9 -2
  54. package/dist/tool-approval.js.map +1 -1
  55. package/package.json +3 -3
@@ -28,7 +28,7 @@ import { redactSecrets, redactDeep, redactedPreview } from "../trace/redact.js";
28
28
  import { usageSummary, usageSeries, usageBreakdown } from "../usage-analytics.js";
29
29
  import { IdempotencyCache } from "./idempotency.js";
30
30
  export const MAX_USER_SKILLS = 10;
31
- export const MAX_SKILL_CONTENT_CHARS = 32_768;
31
+ export const MAX_SKILL_CONTENT_CHARS = 20_000;
32
32
  export const MAX_SYSTEM_PROMPT_CHARS = 16_384;
33
33
  export const MAX_OUTPUT_SCHEMA_CHARS = 32_768;
34
34
  function runMeta(prepared, source) {
@@ -54,7 +54,7 @@ export function validateUserSkills(skills) {
54
54
  if (typeof s["description"] !== "string" || s["description"].length > 1024)
55
55
  return "skill.description must be a string of at most 1024 characters";
56
56
  if (typeof s["content"] !== "string" || s["content"].length === 0 || s["content"].length > MAX_SKILL_CONTENT_CHARS)
57
- return `skill.content must be a non-empty string of at most ${MAX_SKILL_CONTENT_CHARS} characters`;
57
+ return `skill.content must be a non-empty string of at most ${MAX_SKILL_CONTENT_CHARS} characters (the engine truncates skill bodies at ${MAX_SKILL_CONTENT_CHARS} chars — a longer body would be silently cut)`;
58
58
  }
59
59
  return null;
60
60
  }
@@ -180,13 +180,14 @@ export function createHttpServer(deps) {
180
180
  const steerableRuns = new Map();
181
181
  const wakeParkMints = new Map();
182
182
  let uncountedBillableInflight = 0;
183
+ let admittedInflight = 0;
183
184
  if (deps.drainState)
184
- deps.drainState.inflight = () => new Set([...inflightRuns.keys(), ...steerableRuns.keys()]).size + uncountedBillableInflight + (deps.leaderEndpoint?.inflight?.() ?? 0);
185
- let lastBillableActivityAt = Date.now();
185
+ deps.drainState.inflight = () => new Set([...inflightRuns.keys(), ...steerableRuns.keys()]).size + uncountedBillableInflight + admittedInflight + (deps.leaderEndpoint?.inflight?.() ?? 0);
186
+ let lastBillableActivityAt = performance.now();
186
187
  const noteActivity = (url) => {
187
188
  if (url === "/health" || url.startsWith("/metrics"))
188
189
  return;
189
- lastBillableActivityAt = Date.now();
190
+ lastBillableActivityAt = performance.now();
190
191
  };
191
192
  if (deps.drainState)
192
193
  deps.drainState.lastActivityAt = () => lastBillableActivityAt;
@@ -259,11 +260,16 @@ export function createHttpServer(deps) {
259
260
  const method = req.method ?? "GET";
260
261
  const url = (req.url ?? "/").split("?")[0];
261
262
  noteActivity(url);
263
+ const admitted = method !== "OPTIONS" && url !== "/health" && !url.startsWith("/metrics");
264
+ if (admitted)
265
+ admittedInflight++;
262
266
  let logged = false;
263
267
  const record = (viaClose) => {
264
268
  if (logged)
265
269
  return;
266
270
  logged = true;
271
+ if (admitted)
272
+ admittedInflight--;
267
273
  const route = routeLabel(method, url);
268
274
  const seconds = (Date.now() - startedAt) / 1000;
269
275
  const aborted = viaClose && !res.writableEnded;
@@ -3646,6 +3652,16 @@ export function createHttpServer(deps) {
3646
3652
  return null;
3647
3653
  }
3648
3654
  }
3655
+ if (body.resumeAtMode !== undefined) {
3656
+ if (body.resumeAtMode !== "at" && body.resumeAtMode !== "before") {
3657
+ sendJson(res, 400, { error: 'resumeAtMode must be "at" or "before"' });
3658
+ return null;
3659
+ }
3660
+ if (body.resumeAt === undefined) {
3661
+ sendJson(res, 400, { error: "resumeAtMode requires resumeAt (it qualifies the rewind target)" });
3662
+ return null;
3663
+ }
3664
+ }
3649
3665
  if (body.suggestNextPrompts !== undefined && typeof body.suggestNextPrompts !== "boolean") {
3650
3666
  const s = body.suggestNextPrompts;
3651
3667
  if (typeof s !== "object" || s === null || Array.isArray(s)) {
@@ -3898,9 +3914,10 @@ export function createHttpServer(deps) {
3898
3914
  await emitPendingWorkflowCompletions(deps.workflowCompletionInbox, sessionId, principal ?? null, (frame) => {
3899
3915
  const { type, ...rest } = frame;
3900
3916
  const f = frame;
3917
+ const write = rs0.appendEvent(taskId, drainSeq++, type, rest);
3901
3918
  if (f.type === "task_notification" && f.task_id)
3902
- resumeNotifiedKeys.set(taskNotificationStreamKey({ task_type: f.task_type, task_id: f.task_id, status: String(f.status), seq: f.seq }), Promise.resolve(true));
3903
- return rs0.appendEvent(taskId, drainSeq++, type, rest);
3919
+ resumeNotifiedKeys.set(taskNotificationStreamKey({ task_type: f.task_type, task_id: f.task_id, status: String(f.status), seq: f.seq }), write.then(() => true, () => false));
3920
+ return write;
3904
3921
  }, { route: "resume-open", connection: "durable-append", log: (m, x) => deps.logger?.info?.(m, x) });
3905
3922
  }
3906
3923
  if (verifyRounds !== undefined) {