@skilder-ai/runtime 0.8.4 → 0.8.5

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
@@ -144653,16 +144653,13 @@ SkillContentService = __decorate12([
144653
144653
  ], SkillContentService);
144654
144654
 
144655
144655
  // src/services/static-tools/init-skilder.handler.ts
144656
- function isHatPreloaded(hatId, ctx) {
144657
- return ctx.identity.preloadedHatIds?.includes(hatId) ?? false;
144658
- }
144659
144656
  function buildInitSkilderResponse(ctx) {
144660
144657
  const catalog = ctx.catalog;
144661
- if (!catalog || catalog.hats.length === 0 && catalog.skills.length === 0) {
144658
+ if (!catalog || catalog.hats.length === 0) {
144662
144659
  return [
144663
144660
  "# Welcome to Skilder",
144664
144661
  "",
144665
- "No skills or hats are configured for this session.",
144662
+ "No hats are configured for this session.",
144666
144663
  "",
144667
144664
  "Skilder provides specialized skills and tools to help you accomplish tasks."
144668
144665
  ].join("\n");
@@ -144670,107 +144667,35 @@ function buildInitSkilderResponse(ctx) {
144670
144667
  const lines = [];
144671
144668
  lines.push("# Welcome to Skilder");
144672
144669
  lines.push("");
144673
- lines.push("Skilder provides specialized skills and resources. Use `learn` to access resources by path.");
144670
+ lines.push("Skilder provides specialized skills and resources. Hats are the entry point \u2014 learn a hat first, then learn individual skills to unlock their tools.");
144674
144671
  lines.push("");
144675
- lines.push("**Path Examples:**");
144676
- lines.push('- `learn --path "/Skill Name"` - Learn a skill and unlock its tools');
144677
- lines.push('- `learn --path "/Skill Name/doc.md"` - Get a resource');
144678
- lines.push('- `learn --path "/hats/Hat Name"` - Learn all skills in a hat');
144679
- lines.push('- `execute_script --path "/Skill Name/script.py --args"` - Run a script');
144672
+ lines.push("## Available Hats");
144680
144673
  lines.push("");
144681
- const preloadedHats = catalog.hats.filter((h2) => isHatPreloaded(h2.id, ctx));
144682
- const discoverableHats = catalog.hats.filter((h2) => !isHatPreloaded(h2.id, ctx));
144683
- const preloadedSkillIds = new Set(ctx.identity.preloadedSkillIds ?? []);
144684
- if (discoverableHats.length > 0) {
144685
- lines.push("## Available Hats");
144686
- lines.push("");
144687
- lines.push('Use `learn --path "/hats/Hat Name"` to unlock all skills in a hat.');
144688
- lines.push("");
144689
- for (const hat of discoverableHats) {
144690
- const skillCount = hat.skillIds.length;
144691
- lines.push(
144692
- `- **${hat.name}**${hat.description ? `: ${hat.description}` : ""} (${skillCount} skill${skillCount !== 1 ? "s" : ""})`
144693
- );
144694
- }
144695
- lines.push("");
144696
- }
144697
- const discoverableSkills = catalog.skills.filter((s) => !preloadedSkillIds.has(s.id));
144698
- if (discoverableSkills.length > 0) {
144699
- lines.push("## Available Skills");
144700
- lines.push("");
144701
- lines.push('Use `learn --path "/Skill Name"` to unlock tools and view instructions.');
144702
- lines.push("");
144703
- for (const skill of discoverableSkills) {
144704
- const extras = [];
144705
- const learnableCount = skill.related.filter((r2) => r2.class === "learnable").length;
144706
- const executableCount = skill.related.filter((r2) => r2.class === "executable").length;
144707
- if (learnableCount > 0) {
144708
- extras.push(`${learnableCount} ref${learnableCount !== 1 ? "s" : ""}`);
144709
- }
144710
- if (executableCount > 0) {
144711
- extras.push(`${executableCount} script${executableCount !== 1 ? "s" : ""}`);
144712
- }
144713
- const extrasStr = extras.length > 0 ? ` [${extras.join(", ")}]` : "";
144714
- lines.push(`- **${skill.name}**${skill.description ? `: ${skill.description}` : ""}${extrasStr}`);
144674
+ lines.push("You MUST learn a hat before doing anything else. Hats are the only entry point.");
144675
+ lines.push("");
144676
+ for (const hat of catalog.hats) {
144677
+ lines.push(`### ${hat.name}`);
144678
+ if (hat.description) {
144679
+ lines.push(hat.description);
144715
144680
  }
144716
144681
  lines.push("");
144717
- }
144718
- if (preloadedHats.length > 0) {
144719
- lines.push("## Pre-loaded Hats (Ready to Use)");
144720
- lines.push("");
144721
- for (const hat of preloadedHats) {
144722
- lines.push(`### ${hat.name}`);
144723
- if (hat.description) {
144724
- lines.push(hat.description);
144725
- }
144726
- if (hat.instructions) {
144727
- lines.push("");
144728
- lines.push("**Instructions:**");
144729
- lines.push(hat.instructions);
144730
- }
144731
- lines.push("");
144732
- lines.push("**Skills in this hat:**");
144733
- for (const skillId of hat.skillIds) {
144734
- const skill = catalog.skills.find((s) => s.id === skillId);
144735
- if (skill) {
144736
- lines.push(`- **${skill.name}**${skill.description ? `: ${skill.description}` : ""}`);
144737
- if (skill.instructions) {
144738
- lines.push(` - Instructions: ${skill.instructions}`);
144739
- }
144740
- if (skill.toolNames.length > 0) {
144741
- lines.push(` - Tools: ${skill.toolNames.join(", ")}`);
144742
- }
144743
- }
144744
- }
144745
- lines.push("");
144746
- }
144747
- }
144748
- const preloadedSkills = catalog.skills.filter((s) => preloadedSkillIds.has(s.id));
144749
- const preloadedHatSkillIds = new Set(preloadedHats.flatMap((h2) => h2.skillIds));
144750
- const orphanPreloadedSkills = preloadedSkills.filter((s) => !preloadedHatSkillIds.has(s.id));
144751
- if (orphanPreloadedSkills.length > 0) {
144752
- lines.push("## Pre-loaded Skills (Ready to Use)");
144682
+ lines.push(`**Learn this hat:** \`learn --path "/hats/${hat.name}"\``);
144753
144683
  lines.push("");
144754
- for (const skill of orphanPreloadedSkills) {
144755
- lines.push(`### ${skill.name}`);
144756
- if (skill.description) {
144757
- lines.push(skill.description);
144758
- }
144759
- if (skill.instructions) {
144760
- lines.push("");
144761
- lines.push("**Instructions:**");
144762
- lines.push(skill.instructions);
144763
- }
144764
- if (skill.toolNames.length > 0) {
144765
- lines.push("");
144766
- lines.push(`**Tools:** ${skill.toolNames.join(", ")}`);
144767
- }
144768
- lines.push("");
144769
- }
144770
144684
  }
144771
144685
  return lines.join("\n");
144772
144686
  }
144773
144687
  async function handleInitSkilder(_args, ctx) {
144688
+ if (!ctx.catalog) {
144689
+ ctx.logger.warn(
144690
+ { userId: ctx.identity.id },
144691
+ "init_skilder called with null catalog \u2014 catalog may not have loaded yet"
144692
+ );
144693
+ } else if (ctx.catalog.hats.length === 0) {
144694
+ ctx.logger.warn(
144695
+ { userId: ctx.identity.id, skillCount: ctx.catalog.skills.length },
144696
+ "init_skilder called with no hats in catalog"
144697
+ );
144698
+ }
144774
144699
  return {
144775
144700
  response: { content: [{ type: "text", text: buildInitSkilderResponse(ctx) }] }
144776
144701
  };
@@ -144785,86 +144710,75 @@ function errorResult(text2, skillIds) {
144785
144710
  }
144786
144711
 
144787
144712
  // src/services/static-tools/learn.handler.ts
144788
- function appendReferencedResources(lines, mentions, skillName, heading) {
144713
+ function appendReferencedResources(lines, mentions, related, skillName) {
144789
144714
  if (mentions.length === 0) return;
144790
- lines.push(`## ${heading}`);
144715
+ lines.push("## Resources");
144716
+ lines.push("Only resources referenced in the skill description or instructions are shown.");
144717
+ lines.push("");
144791
144718
  for (const m2 of mentions) {
144792
144719
  const resourcePath = `/${skillName}/${m2.qualifiedName}`;
144720
+ const entry = related.find((r2) => (r2.path ? `${r2.path}/${r2.name}` : r2.name) === m2.qualifiedName);
144721
+ lines.push(`### ${m2.name}`);
144722
+ if (entry?.description) {
144723
+ lines.push(entry.description);
144724
+ }
144725
+ lines.push("");
144793
144726
  if (m2.class === "learnable") {
144794
- lines.push(`- To learn more about \`${m2.qualifiedName}\`: \`learn --path "${resourcePath}"\``);
144727
+ lines.push(`**Consume:** \`learn --path "${resourcePath}"\``);
144795
144728
  } else if (m2.class === "executable") {
144796
- lines.push(`- To execute \`${m2.qualifiedName}\`: \`execute_script --path "${resourcePath}"\``);
144729
+ lines.push(`**Consume:** \`execute_script --path "${resourcePath}"\``);
144797
144730
  } else {
144798
- lines.push(`- To download \`${m2.qualifiedName}\`: \`download_asset --path "${resourcePath}"\``);
144731
+ lines.push(`**Consume:** \`download_asset --path "${resourcePath}"\``);
144799
144732
  }
144733
+ lines.push("");
144800
144734
  }
144801
144735
  }
144802
- function formatSkillDetails(skill, ctx, options) {
144803
- const headingLevel = options?.headingLevel ?? 2;
144804
- const heading = "#".repeat(headingLevel);
144805
- const renderedToolNames = options?.renderedToolNames;
144806
- const firstSkillForTool = options?.firstSkillForTool;
144736
+ function formatSkillDetails(skill, ctx) {
144807
144737
  const lines = [];
144808
144738
  if (skill.description) {
144809
144739
  lines.push(skill.description);
144810
144740
  lines.push("");
144811
144741
  }
144812
144742
  if (skill.instructions) {
144813
- lines.push(`${heading} Instructions`);
144743
+ lines.push("## Instructions");
144814
144744
  lines.push(skill.instructions);
144815
144745
  lines.push("");
144816
144746
  }
144817
144747
  if (skill.toolNames.length > 0) {
144818
- lines.push(`${heading} Available Tools`);
144748
+ lines.push("## Available Tools");
144819
144749
  lines.push("Use `call_tool` with the tool name and input to execute these tools:");
144820
144750
  lines.push("");
144821
144751
  for (const toolName of skill.toolNames) {
144822
- const subHeading = "#".repeat(headingLevel + 1);
144823
- if (renderedToolNames?.has(toolName)) {
144824
- const firstSkill = firstSkillForTool?.get(toolName);
144825
- lines.push(`${subHeading} ${toolName}`);
144826
- lines.push(firstSkill ? `(schema shown above under ${firstSkill})` : "(schema shown above)");
144752
+ const tool2 = ctx.getTools()?.find((t4) => t4.name === toolName);
144753
+ if (tool2) {
144754
+ lines.push(`### ${tool2.name}`);
144755
+ lines.push(tool2.description || "No description");
144756
+ lines.push("");
144757
+ lines.push("**Input Schema:**");
144758
+ lines.push("```json");
144759
+ lines.push(JSON.stringify(tool2.inputSchema, null, 2));
144760
+ lines.push("```");
144827
144761
  lines.push("");
144828
144762
  } else {
144829
- if (renderedToolNames) {
144830
- renderedToolNames.add(toolName);
144831
- firstSkillForTool?.set(toolName, skill.name);
144832
- }
144833
- const tool2 = ctx.getTools()?.find((t4) => t4.name === toolName);
144834
- if (tool2) {
144835
- lines.push(`${subHeading} ${tool2.name}`);
144836
- lines.push(tool2.description || "No description");
144837
- lines.push("");
144838
- lines.push("**Input Schema:**");
144839
- lines.push("```json");
144840
- lines.push(JSON.stringify(tool2.inputSchema, null, 2));
144841
- lines.push("```");
144842
- lines.push("");
144843
- } else {
144844
- ctx.logger.warn(
144845
- { toolName, skillId: skill.id, toolsInitialized: ctx.getTools() != null },
144846
- `Tool "${toolName}" referenced by skill "${skill.name}" not found in tools list`
144847
- );
144848
- lines.push(`${subHeading} ${toolName}`);
144849
- lines.push("Tool definition not available");
144850
- lines.push("");
144851
- }
144763
+ ctx.logger.warn(
144764
+ { toolName, skillId: skill.id, toolsInitialized: ctx.getTools() != null },
144765
+ `Tool "${toolName}" referenced by skill "${skill.name}" not found in tools list`
144766
+ );
144767
+ lines.push(`### ${toolName}`);
144768
+ lines.push("Tool definition not available");
144769
+ lines.push("");
144852
144770
  }
144853
144771
  }
144854
144772
  lines.push('Call these tools using: `call_tool(tool_name="<name>", tool_input={...})`');
144855
144773
  } else {
144856
144774
  lines.push("This skill provides instructions only and has no associated tools.");
144857
144775
  }
144858
- if (skill.instructions && skill.related.length > 0) {
144859
- try {
144860
- const mentions = detectRelatedMentions(skill.instructions, skill.related);
144776
+ if (skill.related.length > 0) {
144777
+ const sourceText = [skill.description, skill.instructions].filter(Boolean).join("\n\n");
144778
+ const mentions = detectRelatedMentions(sourceText, skill.related);
144779
+ if (mentions.length > 0) {
144861
144780
  lines.push("");
144862
- appendReferencedResources(lines, mentions, skill.name, "Resources Referenced in Instructions");
144863
- } catch (error48) {
144864
- ctx.logger.error(
144865
- { err: error48, skillId: skill.id, skillName: skill.name },
144866
- "Failed to detect related mentions in skill instructions \u2014 skipping resource list"
144867
- );
144781
+ appendReferencedResources(lines, mentions, skill.related, skill.name);
144868
144782
  }
144869
144783
  }
144870
144784
  return lines;
@@ -144912,9 +144826,9 @@ function handleGetHat(hatName, ctx) {
144912
144826
  missingSkillIds.push(skillId);
144913
144827
  }
144914
144828
  }
144915
- const totalToolCount = new Set(skills.flatMap((s) => s.toolNames)).size;
144916
144829
  ctx.logger.info(
144917
- `User ${ctx.identity.id} retrieved hat "${hat.name}" with ${skills.length} skills and ${totalToolCount} tools`
144830
+ { userId: ctx.identity.id, hatId: hat.id, hatName: hat.name, skillCount: skills.length },
144831
+ "User retrieved hat"
144918
144832
  );
144919
144833
  const lines = [];
144920
144834
  lines.push(`# Hat: ${hat.name}`);
@@ -144929,13 +144843,16 @@ function handleGetHat(hatName, ctx) {
144929
144843
  lines.push("");
144930
144844
  }
144931
144845
  if (skills.length > 0) {
144932
- lines.push("## Skills Learned");
144846
+ lines.push("## Available Skills");
144847
+ lines.push('Use `learn --path "/Skill Name"` to learn a skill and unlock its tools and resources.');
144933
144848
  lines.push("");
144934
- const renderedToolNames = /* @__PURE__ */ new Set();
144935
- const firstSkillForTool = /* @__PURE__ */ new Map();
144936
144849
  for (const skill of skills) {
144937
144850
  lines.push(`### ${skill.name}`);
144938
- lines.push(...formatSkillDetails(skill, ctx, { headingLevel: 4, renderedToolNames, firstSkillForTool }));
144851
+ if (skill.description) {
144852
+ lines.push(skill.description);
144853
+ }
144854
+ lines.push("");
144855
+ lines.push(`**Learn this skill:** \`learn --path "/${skill.name}"\``);
144939
144856
  lines.push("");
144940
144857
  }
144941
144858
  } else {
@@ -144950,7 +144867,7 @@ function handleGetHat(hatName, ctx) {
144950
144867
  }
144951
144868
  return {
144952
144869
  response: { content: [{ type: "text", text: lines.join("\n") }] },
144953
- skillIds: hat.skillIds
144870
+ skillIds: []
144954
144871
  };
144955
144872
  }
144956
144873
  async function handleGetRelated(skillName, resourceName, ctx) {
@@ -144993,14 +144910,32 @@ To execute this script, use:
144993
144910
  lines.push(`**Description:** ${item.description}`);
144994
144911
  }
144995
144912
  lines.push("");
144996
- if (ctx.skillContentService && ctx.identity.userKey) {
144913
+ if (!ctx.skillContentService) {
144914
+ ctx.logger.error(
144915
+ { resourceId: item.id, skillId: skill.id },
144916
+ "skillContentService not injected \u2014 cannot fetch resource content"
144917
+ );
144918
+ lines.push("*Content unavailable: this runtime is not configured to fetch resource content.*");
144919
+ } else if (!ctx.identity.userKey) {
144920
+ ctx.logger.error(
144921
+ { resourceId: item.id, skillId: skill.id, userId: ctx.identity.id },
144922
+ "userKey missing \u2014 cannot authenticate resource content fetch"
144923
+ );
144924
+ lines.push("*Content unavailable: authentication context is missing. Please reconnect.*");
144925
+ } else {
144997
144926
  try {
144998
144927
  const content = await ctx.skillContentService.getContent(item.id, ctx.identity.userKey);
144999
- if (content) {
145000
- lines.push(content);
145001
- } else {
145002
- lines.push("*No content available for this resource.*");
144928
+ if (content == null) {
144929
+ ctx.logger.error(
144930
+ { resourceId: item.id, resourceName: item.name, skillId: skill.id },
144931
+ "skillContentService.getContent returned null \u2014 no content for resource"
144932
+ );
144933
+ return errorResult(
144934
+ `Error: No content found for resource "${item.name}". The resource may be empty or unavailable.`,
144935
+ [skill.id]
144936
+ );
145003
144937
  }
144938
+ lines.push(content);
145004
144939
  } catch (err) {
145005
144940
  ctx.logger.error({ err, resourceId: item.id }, "Failed to fetch resource content");
145006
144941
  return errorResult(
@@ -145008,8 +144943,6 @@ To execute this script, use:
145008
144943
  [skill.id]
145009
144944
  );
145010
144945
  }
145011
- } else {
145012
- lines.push("*Content unavailable: this runtime is not configured to fetch resource content.*");
145013
144946
  }
145014
144947
  return {
145015
144948
  response: { content: [{ type: "text", text: lines.join("\n") }] },