@skilder-ai/runtime 0.8.2 → 0.8.4

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/index.js CHANGED
@@ -87668,6 +87668,7 @@ var DEFAULT_OPTIMIZATION_INSIGHTS_LOOKBACK_SECONDS = 30 * 24 * 60 * 60;
87668
87668
  // ../common/src/constants.node.ts
87669
87669
  var MCP_CALL_TOOL_TIMEOUT = parseInt(process.env.MCP_CALL_TOOL_TIMEOUT ?? "10000", 10);
87670
87670
  var DEFAULT_REQUEST_TIMEOUT = parseInt(process.env.DEFAULT_REQUEST_TIMEOUT ?? "10000", 10);
87671
+ var SCRIPT_ROUTE_TIMEOUT_MS = 31e4;
87671
87672
 
87672
87673
  // ../../node_modules/.pnpm/bcryptjs@3.0.3/node_modules/bcryptjs/index.js
87673
87674
  var nextTick = typeof setImmediate === "function" ? setImmediate : typeof scheduler === "object" && typeof scheduler.postTask === "function" ? scheduler.postTask.bind(scheduler) : setTimeout;
@@ -144488,7 +144489,7 @@ For other resources, use the \`learn\` tool instead.`
144488
144489
  delegateDepth
144489
144490
  });
144490
144491
  try {
144491
- const response = await this.natsService.request(toolCallRequest, { timeout: MCP_CALL_TOOL_TIMEOUT });
144492
+ const response = await this.natsService.request(toolCallRequest, { timeout: SCRIPT_ROUTE_TIMEOUT_MS });
144492
144493
  if (response instanceof ErrorResponse) {
144493
144494
  return {
144494
144495
  content: [{ type: "text", text: `Error: ${response.data.error}` }],
@@ -145958,7 +145959,8 @@ The path must point to a downloadable (binary) resource in a skill's related ite
145958
145959
  if (toolConfig.__routing.type === "static") {
145959
145960
  this.logger.debug(`Handling static tool ${toolConfig.__routing.toolName} for user ${this.identity.id}`);
145960
145961
  const { response, skillIds } = await this.handleStaticTool(toolConfig.__routing.toolName, args);
145961
- if (toolConfig.__routing.workspaceId) {
145962
+ const isWrapperTool = toolConfig.__routing.toolName === "call_tool";
145963
+ if (toolConfig.__routing.workspaceId && !isWrapperTool) {
145962
145964
  try {
145963
145965
  const message = SkillCallToolRequest.create({
145964
145966
  type: "static",
@@ -149850,12 +149852,29 @@ var ScriptExecutorService = class ScriptExecutorService2 {
149850
149852
  NODE_PATH: (0, import_path2.join)(tempDir, "node_modules")
149851
149853
  }
149852
149854
  });
149855
+ const pendingIds = /* @__PURE__ */ new Set();
149853
149856
  let currentTimeout = timeout2;
149854
149857
  let lastExtendingMethod;
149858
+ const killForTimeout = (reason) => {
149859
+ const ids = Array.from(pendingIds);
149860
+ pendingIds.clear();
149861
+ for (const id of ids) {
149862
+ writeFromKill(id, -32001, reason);
149863
+ }
149864
+ try {
149865
+ child.stdin?.end();
149866
+ } catch (err) {
149867
+ this.logger.debug({ error: err }, "child.stdin.end() during killForTimeout failed");
149868
+ }
149869
+ setTimeout(() => {
149870
+ if (!childExited)
149871
+ child.kill("SIGKILL");
149872
+ }, 250);
149873
+ };
149855
149874
  let timeoutId = setTimeout(() => {
149856
149875
  killed = true;
149857
- child.kill("SIGKILL");
149858
149876
  this.logger.warn({ timeout: currentTimeout, method: lastExtendingMethod }, "Interactive script timed out");
149877
+ killForTimeout(`Script timeout: runtime killed the script after ${currentTimeout}ms${lastExtendingMethod ? ` (last extending method: ${lastExtendingMethod})` : ""}.`);
149859
149878
  }, currentTimeout);
149860
149879
  const resetTimeout = (extraMs, method) => {
149861
149880
  clearTimeout(timeoutId);
@@ -149863,25 +149882,27 @@ var ScriptExecutorService = class ScriptExecutorService2 {
149863
149882
  const remaining = Math.min(extraMs, MAX_INTERACTIVE_SCRIPT_TIMEOUT_MS - elapsed);
149864
149883
  if (remaining <= 0) {
149865
149884
  killed = true;
149866
- child.kill("SIGKILL");
149867
149885
  this.logger.warn({ method }, "Interactive script exceeded max total timeout");
149886
+ killForTimeout(`Script timeout: exceeded max total interactive timeout (${MAX_INTERACTIVE_SCRIPT_TIMEOUT_MS}ms)${method ? ` while waiting on ${method}` : ""}.`);
149868
149887
  return;
149869
149888
  }
149870
149889
  lastExtendingMethod = method;
149871
149890
  currentTimeout = remaining;
149872
149891
  timeoutId = setTimeout(() => {
149873
149892
  killed = true;
149874
- child.kill("SIGKILL");
149875
149893
  this.logger.warn({ timeout: currentTimeout, method: lastExtendingMethod }, "Interactive script timed out");
149894
+ killForTimeout(`Script timeout: runtime killed the script after ${currentTimeout}ms${lastExtendingMethod ? ` (last extending method: ${lastExtendingMethod})` : ""}.`);
149876
149895
  }, currentTimeout);
149877
149896
  };
149878
149897
  const safeWrite = (data) => {
149879
149898
  if (childExited || !child.stdin?.writable)
149880
- return;
149899
+ return false;
149881
149900
  try {
149882
149901
  child.stdin.write(data);
149902
+ return true;
149883
149903
  } catch (err) {
149884
149904
  this.logger.debug({ error: err }, "Failed to write to child stdin (process may have exited)");
149905
+ return false;
149885
149906
  }
149886
149907
  };
149887
149908
  const writeResponse = (id, result) => {
@@ -149890,6 +149911,12 @@ var ScriptExecutorService = class ScriptExecutorService2 {
149890
149911
  const writeError = (id, code, message) => {
149891
149912
  safeWrite(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id }) + "\n");
149892
149913
  };
149914
+ const writeFromKill = (id, code, message) => {
149915
+ const ok = safeWrite(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id }) + "\n");
149916
+ if (!ok) {
149917
+ this.logger.warn({ id, message, event: "script_timeout_error_frame_drop" }, "Failed to deliver timeout JSON-RPC error frame to script \u2014 SDK will fall back to generic IPC-closed message");
149918
+ }
149919
+ };
149893
149920
  const rl = (0, import_readline.createInterface)({ input: child.stdout, crlfDelay: Infinity });
149894
149921
  rl.on("line", (line) => {
149895
149922
  if (outputTruncated)
@@ -149917,6 +149944,7 @@ var ScriptExecutorService = class ScriptExecutorService2 {
149917
149944
  return;
149918
149945
  }
149919
149946
  inflightCount++;
149947
+ pendingIds.add(msg.id);
149920
149948
  (async () => {
149921
149949
  try {
149922
149950
  if (msg.method === "delegate") {
@@ -149925,11 +149953,16 @@ var ScriptExecutorService = class ScriptExecutorService2 {
149925
149953
  resetTimeout(toolCallTimeout + timeout2, msg.method);
149926
149954
  }
149927
149955
  const result = await onRequest(msg.method, msg.params);
149928
- writeResponse(msg.id, result);
149956
+ if (pendingIds.delete(msg.id)) {
149957
+ writeResponse(msg.id, result);
149958
+ }
149929
149959
  } catch (err) {
149930
- const message = err instanceof Error ? err.message : String(err);
149931
- writeError(msg.id, -32e3, message);
149960
+ if (pendingIds.delete(msg.id)) {
149961
+ const message = err instanceof Error ? err.message : String(err);
149962
+ writeError(msg.id, -32e3, message);
149963
+ }
149932
149964
  } finally {
149965
+ pendingIds.delete(msg.id);
149933
149966
  inflightCount--;
149934
149967
  if (inflightCount === 0 && inflightDone)
149935
149968
  inflightDone();
@@ -154158,7 +154191,7 @@ ${cleanError}` : cleanError;
154158
154191
  throw new Error("Invalid delegate params: expected { context: string, model?: string, temperature?: number }");
154159
154192
  }
154160
154193
  const { context: context2, model, temperature } = params;
154161
- return this.handleScriptDelegate(context2, model, temperature, workspaceId, userKey, delegateDepth);
154194
+ return this.handleScriptDelegate(context2, model, temperature, workspaceId, userId, userKey, runtimeId, delegateDepth);
154162
154195
  }
154163
154196
  case "scripts/execute": {
154164
154197
  if (!params || typeof params !== "object" || typeof params.path !== "string") {
@@ -154248,7 +154281,7 @@ ${cleanError}` : cleanError;
154248
154281
  * Handle a delegate request from a TypeScript script via JSON-RPC IPC.
154249
154282
  * Spawns a sub-agent using DelegateService and returns the result as a CallToolResult.
154250
154283
  */
154251
- async handleScriptDelegate(context2, model, temperature, workspaceId, userKey, delegateDepth) {
154284
+ async handleScriptDelegate(context2, model, temperature, workspaceId, userId, userKey, runtimeId, delegateDepth) {
154252
154285
  if (!this.delegateService) {
154253
154286
  this.logger.warn({ event: "delegate_service_unavailable" }, "Delegate requested but DelegateService not injected");
154254
154287
  return {
@@ -154261,14 +154294,51 @@ ${cleanError}` : cleanError;
154261
154294
  isError: true
154262
154295
  };
154263
154296
  }
154264
- return this.delegateService.execute({
154265
- context: context2,
154266
- model,
154267
- temperature,
154268
- workspaceId,
154269
- userKey,
154270
- delegateDepth: delegateDepth ?? 0
154297
+ const publishMonitoring = (response) => {
154298
+ try {
154299
+ const message = new SkillCallToolRequest({
154300
+ type: "static",
154301
+ toolName: "delegate",
154302
+ workspaceId,
154303
+ from: runtimeId ?? "script",
154304
+ userId,
154305
+ userKey,
154306
+ arguments: {
154307
+ context: context2,
154308
+ ...model !== void 0 && { model },
154309
+ ...temperature !== void 0 && { temperature }
154310
+ },
154311
+ response,
154312
+ delegateDepth
154313
+ });
154314
+ this.natsService.publish(message);
154315
+ } catch (error48) {
154316
+ this.logger.error({ err: error48, event: "script_delegate_publish_failed" }, "Failed to publish script delegate monitoring event");
154317
+ }
154318
+ };
154319
+ let result;
154320
+ try {
154321
+ result = await this.delegateService.execute({
154322
+ context: context2,
154323
+ model,
154324
+ temperature,
154325
+ workspaceId,
154326
+ userKey,
154327
+ delegateDepth: delegateDepth ?? 0
154328
+ });
154329
+ } catch (error48) {
154330
+ const message = error48 instanceof Error ? error48.message : String(error48);
154331
+ publishMonitoring({
154332
+ content: [{ type: "text", text: `Error: Delegate failed unexpectedly: ${message}` }],
154333
+ isError: true
154334
+ });
154335
+ throw error48;
154336
+ }
154337
+ publishMonitoring({
154338
+ content: result.content,
154339
+ ...result.isError && { isError: true }
154271
154340
  });
154341
+ return result;
154272
154342
  }
154273
154343
  /**
154274
154344
  * Route a tool call from a script to the appropriate MCP server via NATS.