@skilder-ai/runtime 0.7.3 → 0.7.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
@@ -138461,6 +138461,34 @@ var WorkspaceRole = /* @__PURE__ */ ((WorkspaceRole2) => {
138461
138461
  return WorkspaceRole2;
138462
138462
  })(WorkspaceRole || {});
138463
138463
 
138464
+ // ../common/src/utils/parse-script-args.ts
138465
+ function parseScriptArgs(argsString) {
138466
+ const args = [];
138467
+ let current = "";
138468
+ let inQuotes = false;
138469
+ let quoteChar = "";
138470
+ for (const char of argsString) {
138471
+ if ((char === '"' || char === "'") && !inQuotes) {
138472
+ inQuotes = true;
138473
+ quoteChar = char;
138474
+ } else if (char === quoteChar && inQuotes) {
138475
+ inQuotes = false;
138476
+ quoteChar = "";
138477
+ } else if (char === " " && !inQuotes) {
138478
+ if (current) {
138479
+ args.push(current);
138480
+ current = "";
138481
+ }
138482
+ } else {
138483
+ current += char;
138484
+ }
138485
+ }
138486
+ if (current) {
138487
+ args.push(current);
138488
+ }
138489
+ return args;
138490
+ }
138491
+
138464
138492
  // ../common/src/related-content-detector.ts
138465
138493
  function escapeRegex2(str) {
138466
138494
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -144820,39 +144848,9 @@ For other resources, use the \`learn\` tool instead.`
144820
144848
  };
144821
144849
  }
144822
144850
  const script = scriptEntry;
144823
- const args = lookupArgs ? this.parseScriptArgs(lookupArgs) : [];
144851
+ const args = lookupArgs ? parseScriptArgs(lookupArgs) : [];
144824
144852
  return await this.routeScriptToRuntime(script, skill, args);
144825
144853
  }
144826
- /**
144827
- * Parse script arguments from the path string.
144828
- * Arguments can be space-separated, with quoted strings supported.
144829
- */
144830
- parseScriptArgs(argsString) {
144831
- const args = [];
144832
- let current = "";
144833
- let inQuotes = false;
144834
- let quoteChar = "";
144835
- for (const char of argsString) {
144836
- if ((char === '"' || char === "'") && !inQuotes) {
144837
- inQuotes = true;
144838
- quoteChar = char;
144839
- } else if (char === quoteChar && inQuotes) {
144840
- inQuotes = false;
144841
- quoteChar = "";
144842
- } else if (char === " " && !inQuotes) {
144843
- if (current) {
144844
- args.push(current);
144845
- current = "";
144846
- }
144847
- } else {
144848
- current += char;
144849
- }
144850
- }
144851
- if (current) {
144852
- args.push(current);
144853
- }
144854
- return args;
144855
- }
144856
144854
  /**
144857
144855
  * Route script execution to a runtime via NATS.
144858
144856
  * Scripts always execute on the runtime linked to the script.
@@ -145178,34 +145176,68 @@ This file can be used with other file I/O tools that accept \`@skilder-file:/\`
145178
145176
  const lines = [];
145179
145177
  lines.push(`# Skill: ${skill.name}`);
145180
145178
  lines.push("");
145179
+ lines.push(...this.formatSkillDetails(skill));
145180
+ return {
145181
+ response: { content: [{ type: "text", text: lines.join("\n") }] },
145182
+ skillIds: [skill.id]
145183
+ };
145184
+ }
145185
+ /**
145186
+ * Format full details for a single skill including description, instructions, tool schemas,
145187
+ * and referenced resources. Used by both handleLearnSkill and handleGetHat to ensure DRY
145188
+ * consistency when rendering skill content.
145189
+ *
145190
+ * @param skill - The skill catalog entry to format
145191
+ * @param options.headingLevel - Heading level for tools section (2 for standalone, 4 for within-hat)
145192
+ * @param options.renderedToolNames - Set of tool names already rendered (for deduplication across skills in a hat)
145193
+ */
145194
+ formatSkillDetails(skill, options) {
145195
+ const headingLevel = options?.headingLevel ?? 2;
145196
+ const heading = "#".repeat(headingLevel);
145197
+ const renderedToolNames = options?.renderedToolNames;
145198
+ const firstSkillForTool = options?.firstSkillForTool;
145199
+ const lines = [];
145181
145200
  if (skill.description) {
145182
145201
  lines.push(skill.description);
145183
145202
  lines.push("");
145184
145203
  }
145185
145204
  if (skill.instructions) {
145186
- lines.push("## Instructions");
145205
+ lines.push(`${heading} Instructions`);
145187
145206
  lines.push(skill.instructions);
145188
145207
  lines.push("");
145189
145208
  }
145190
145209
  if (skill.toolNames.length > 0) {
145191
- lines.push("## Available Tools");
145210
+ lines.push(`${heading} Available Tools`);
145192
145211
  lines.push("Use `call_tool` with the tool name and input to execute these tools:");
145193
145212
  lines.push("");
145194
145213
  for (const toolName of skill.toolNames) {
145195
- const tool2 = this.tools.getValue()?.find((t4) => t4.name === toolName);
145196
- if (tool2) {
145197
- lines.push(`### ${tool2.name}`);
145198
- lines.push(tool2.description || "No description");
145199
- lines.push("");
145200
- lines.push("**Input Schema:**");
145201
- lines.push("```json");
145202
- lines.push(JSON.stringify(tool2.inputSchema, null, 2));
145203
- lines.push("```");
145214
+ const subHeading = "#".repeat(headingLevel + 1);
145215
+ if (renderedToolNames?.has(toolName)) {
145216
+ const firstSkill = firstSkillForTool?.get(toolName);
145217
+ lines.push(`${subHeading} ${toolName}`);
145218
+ lines.push(firstSkill ? `(schema shown above under ${firstSkill})` : "(schema shown above)");
145204
145219
  lines.push("");
145205
145220
  } else {
145206
- lines.push(`### ${toolName}`);
145207
- lines.push("Tool definition not available");
145208
- lines.push("");
145221
+ if (renderedToolNames) {
145222
+ renderedToolNames.add(toolName);
145223
+ firstSkillForTool?.set(toolName, skill.name);
145224
+ }
145225
+ const tool2 = this.tools.getValue()?.find((t4) => t4.name === toolName);
145226
+ if (tool2) {
145227
+ lines.push(`${subHeading} ${tool2.name}`);
145228
+ lines.push(tool2.description || "No description");
145229
+ lines.push("");
145230
+ lines.push("**Input Schema:**");
145231
+ lines.push("```json");
145232
+ lines.push(JSON.stringify(tool2.inputSchema, null, 2));
145233
+ lines.push("```");
145234
+ lines.push("");
145235
+ } else {
145236
+ this.logger.warn({ toolName, skillId: skill.id, toolsInitialized: this.tools.getValue() != null }, `Tool "${toolName}" referenced by skill "${skill.name}" not found in tools list`);
145237
+ lines.push(`${subHeading} ${toolName}`);
145238
+ lines.push("Tool definition not available");
145239
+ lines.push("");
145240
+ }
145209
145241
  }
145210
145242
  }
145211
145243
  lines.push('Call these tools using: `call_tool(tool_name="<name>", tool_input={...})`');
@@ -145221,10 +145253,7 @@ This file can be used with other file I/O tools that accept \`@skilder-file:/\`
145221
145253
  } catch (error48) {
145222
145254
  this.logger.warn({ error: error48, skillId: skill.id }, "Failed to detect related mentions in skill instructions");
145223
145255
  }
145224
- return {
145225
- response: { content: [{ type: "text", text: lines.join("\n") }] },
145226
- skillIds: [skill.id]
145227
- };
145256
+ return lines;
145228
145257
  }
145229
145258
  /**
145230
145259
  * Handle feedback_skill tool call.
@@ -145496,27 +145525,19 @@ ${JSON.stringify(toolConfig.inputSchema, null, 2)}`
145496
145525
  }
145497
145526
  this.session.learnedHatIds.add(hat.id);
145498
145527
  const skills = [];
145499
- const allToolNames = /* @__PURE__ */ new Set();
145500
145528
  const missingSkillIds = [];
145501
145529
  for (const skillId of hat.skillIds) {
145502
145530
  const skill = this.catalog.skills.find((s) => s.id === skillId);
145503
145531
  if (skill) {
145504
145532
  this.session.learnedSkillIds.add(skill.id);
145505
- skills.push({
145506
- name: skill.name,
145507
- description: skill.description,
145508
- instructions: skill.instructions,
145509
- toolNames: skill.toolNames
145510
- });
145511
- for (const toolName of skill.toolNames) {
145512
- allToolNames.add(toolName);
145513
- }
145533
+ skills.push(skill);
145514
145534
  } else {
145515
- this.logger.warn(`Skill ID "${skillId}" referenced in hat "${hat.name}" not found in catalog`);
145535
+ this.logger.warn({ skillId, hatId: hat.id, hatName: hat.name }, "Skill referenced in hat not found in catalog");
145516
145536
  missingSkillIds.push(skillId);
145517
145537
  }
145518
145538
  }
145519
- this.logger.info(`User ${this.identity.id} retrieved hat "${hat.name}" with ${skills.length} skills and ${allToolNames.size} tools`);
145539
+ const totalToolCount = new Set(skills.flatMap((s) => s.toolNames)).size;
145540
+ this.logger.info(`User ${this.identity.id} retrieved hat "${hat.name}" with ${skills.length} skills and ${totalToolCount} tools`);
145520
145541
  const lines = [];
145521
145542
  lines.push(`# Hat: ${hat.name}`);
145522
145543
  lines.push("");
@@ -145532,43 +145553,18 @@ ${JSON.stringify(toolConfig.inputSchema, null, 2)}`
145532
145553
  if (skills.length > 0) {
145533
145554
  lines.push("## Skills Learned");
145534
145555
  lines.push("");
145556
+ const renderedToolNames = /* @__PURE__ */ new Set();
145557
+ const firstSkillForTool = /* @__PURE__ */ new Map();
145535
145558
  for (const skill of skills) {
145536
145559
  lines.push(`### ${skill.name}`);
145537
- if (skill.description) {
145538
- lines.push(skill.description);
145539
- }
145540
- if (skill.instructions) {
145541
- lines.push("");
145542
- lines.push("**Instructions:**");
145543
- lines.push(skill.instructions);
145544
- }
145545
- if (skill.toolNames.length > 0) {
145546
- lines.push("");
145547
- lines.push(`**Tools:** ${skill.toolNames.join(", ")}`);
145548
- }
145560
+ lines.push(...this.formatSkillDetails(skill, { headingLevel: 4, renderedToolNames, firstSkillForTool }));
145549
145561
  lines.push("");
145550
145562
  }
145551
145563
  } else {
145552
145564
  lines.push("This hat contains no skills.");
145553
145565
  lines.push("");
145554
145566
  }
145555
- if (allToolNames.size > 0) {
145556
- lines.push("## All Available Tools");
145557
- lines.push("");
145558
- lines.push("The following tools are now available:");
145559
- for (const toolName of allToolNames) {
145560
- const tool2 = this.tools.getValue()?.find((t4) => t4.name === toolName);
145561
- if (tool2) {
145562
- lines.push(`- **${tool2.name}**: ${tool2.description || "No description"}`);
145563
- } else {
145564
- lines.push(`- **${toolName}**`);
145565
- }
145566
- }
145567
- lines.push("");
145568
- lines.push("You can now use these tools to help the user.");
145569
- }
145570
145567
  if (missingSkillIds.length > 0) {
145571
- lines.push("");
145572
145568
  lines.push("## Warning");
145573
145569
  lines.push("");
145574
145570
  lines.push(`Some skills referenced by this hat could not be loaded: ${missingSkillIds.join(", ")}`);
@@ -153049,7 +153045,8 @@ var ToolService = class ToolService2 extends Service {
153049
153045
  */
153050
153046
  async handleScriptExecution(msg, executedBy) {
153051
153047
  const { scriptId, scriptName, workspaceId, arguments: toolArgs } = msg.data;
153052
- const args = toolArgs?.args || [];
153048
+ const rawArgs = toolArgs?.args;
153049
+ const args = Array.isArray(rawArgs) ? rawArgs : typeof rawArgs === "string" && rawArgs.trim() ? parseScriptArgs(rawArgs) : [];
153053
153050
  this.logger.info({ scriptId, scriptName, argsCount: args.length }, "Handling script execution request");
153054
153051
  const fetchRequest = SkillFetchScriptRequest.create({
153055
153052
  scriptId,