@skilder-ai/runtime 0.8.3 → 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 +180 -178
- package/dist/index.js.map +3 -3
- package/dist/script-sdk-bundle.cjs +3 -1
- package/package.json +2 -2
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;
|
|
@@ -143989,7 +143990,6 @@ var ACTIVATION_COOLDOWN_MS = 6e4;
|
|
|
143989
143990
|
var DEFAULT_IDLE_TIMEOUT_MS = 3e5;
|
|
143990
143991
|
var DEFAULT_SCRIPT_TIMEOUT_MS = 3e4;
|
|
143991
143992
|
var MAX_INTERACTIVE_SCRIPT_TIMEOUT_MS = 3e5;
|
|
143992
|
-
var SCRIPT_ROUTE_TIMEOUT_MS = MAX_INTERACTIVE_SCRIPT_TIMEOUT_MS + 1e4;
|
|
143993
143993
|
var MAX_SCRIPT_OUTPUT_SIZE = 10485760;
|
|
143994
143994
|
var MAX_CONCURRENT_SCRIPTS = 16;
|
|
143995
143995
|
var MAX_DELEGATE_DEPTH = 3;
|
|
@@ -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
|
|
144658
|
+
if (!catalog || catalog.hats.length === 0) {
|
|
144662
144659
|
return [
|
|
144663
144660
|
"# Welcome to Skilder",
|
|
144664
144661
|
"",
|
|
144665
|
-
"No
|
|
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.
|
|
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("
|
|
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
|
-
|
|
144682
|
-
|
|
144683
|
-
const
|
|
144684
|
-
|
|
144685
|
-
|
|
144686
|
-
|
|
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,
|
|
144713
|
+
function appendReferencedResources(lines, mentions, related, skillName) {
|
|
144789
144714
|
if (mentions.length === 0) return;
|
|
144790
|
-
lines.push(
|
|
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(
|
|
144727
|
+
lines.push(`**Consume:** \`learn --path "${resourcePath}"\``);
|
|
144795
144728
|
} else if (m2.class === "executable") {
|
|
144796
|
-
lines.push(
|
|
144729
|
+
lines.push(`**Consume:** \`execute_script --path "${resourcePath}"\``);
|
|
144797
144730
|
} else {
|
|
144798
|
-
lines.push(
|
|
144731
|
+
lines.push(`**Consume:** \`download_asset --path "${resourcePath}"\``);
|
|
144799
144732
|
}
|
|
144733
|
+
lines.push("");
|
|
144800
144734
|
}
|
|
144801
144735
|
}
|
|
144802
|
-
function formatSkillDetails(skill, ctx
|
|
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(
|
|
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(
|
|
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
|
|
144823
|
-
if (
|
|
144824
|
-
|
|
144825
|
-
lines.push(
|
|
144826
|
-
lines.push(
|
|
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
|
-
|
|
144830
|
-
|
|
144831
|
-
|
|
144832
|
-
|
|
144833
|
-
|
|
144834
|
-
|
|
144835
|
-
|
|
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.
|
|
144859
|
-
|
|
144860
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
145001
|
-
|
|
145002
|
-
|
|
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") }] },
|
|
@@ -145959,7 +145892,8 @@ The path must point to a downloadable (binary) resource in a skill's related ite
|
|
|
145959
145892
|
if (toolConfig.__routing.type === "static") {
|
|
145960
145893
|
this.logger.debug(`Handling static tool ${toolConfig.__routing.toolName} for user ${this.identity.id}`);
|
|
145961
145894
|
const { response, skillIds } = await this.handleStaticTool(toolConfig.__routing.toolName, args);
|
|
145962
|
-
|
|
145895
|
+
const isWrapperTool = toolConfig.__routing.toolName === "call_tool";
|
|
145896
|
+
if (toolConfig.__routing.workspaceId && !isWrapperTool) {
|
|
145963
145897
|
try {
|
|
145964
145898
|
const message = SkillCallToolRequest.create({
|
|
145965
145899
|
type: "static",
|
|
@@ -149851,12 +149785,29 @@ var ScriptExecutorService = class ScriptExecutorService2 {
|
|
|
149851
149785
|
NODE_PATH: (0, import_path2.join)(tempDir, "node_modules")
|
|
149852
149786
|
}
|
|
149853
149787
|
});
|
|
149788
|
+
const pendingIds = /* @__PURE__ */ new Set();
|
|
149854
149789
|
let currentTimeout = timeout2;
|
|
149855
149790
|
let lastExtendingMethod;
|
|
149791
|
+
const killForTimeout = (reason) => {
|
|
149792
|
+
const ids = Array.from(pendingIds);
|
|
149793
|
+
pendingIds.clear();
|
|
149794
|
+
for (const id of ids) {
|
|
149795
|
+
writeFromKill(id, -32001, reason);
|
|
149796
|
+
}
|
|
149797
|
+
try {
|
|
149798
|
+
child.stdin?.end();
|
|
149799
|
+
} catch (err) {
|
|
149800
|
+
this.logger.debug({ error: err }, "child.stdin.end() during killForTimeout failed");
|
|
149801
|
+
}
|
|
149802
|
+
setTimeout(() => {
|
|
149803
|
+
if (!childExited)
|
|
149804
|
+
child.kill("SIGKILL");
|
|
149805
|
+
}, 250);
|
|
149806
|
+
};
|
|
149856
149807
|
let timeoutId = setTimeout(() => {
|
|
149857
149808
|
killed = true;
|
|
149858
|
-
child.kill("SIGKILL");
|
|
149859
149809
|
this.logger.warn({ timeout: currentTimeout, method: lastExtendingMethod }, "Interactive script timed out");
|
|
149810
|
+
killForTimeout(`Script timeout: runtime killed the script after ${currentTimeout}ms${lastExtendingMethod ? ` (last extending method: ${lastExtendingMethod})` : ""}.`);
|
|
149860
149811
|
}, currentTimeout);
|
|
149861
149812
|
const resetTimeout = (extraMs, method) => {
|
|
149862
149813
|
clearTimeout(timeoutId);
|
|
@@ -149864,25 +149815,27 @@ var ScriptExecutorService = class ScriptExecutorService2 {
|
|
|
149864
149815
|
const remaining = Math.min(extraMs, MAX_INTERACTIVE_SCRIPT_TIMEOUT_MS - elapsed);
|
|
149865
149816
|
if (remaining <= 0) {
|
|
149866
149817
|
killed = true;
|
|
149867
|
-
child.kill("SIGKILL");
|
|
149868
149818
|
this.logger.warn({ method }, "Interactive script exceeded max total timeout");
|
|
149819
|
+
killForTimeout(`Script timeout: exceeded max total interactive timeout (${MAX_INTERACTIVE_SCRIPT_TIMEOUT_MS}ms)${method ? ` while waiting on ${method}` : ""}.`);
|
|
149869
149820
|
return;
|
|
149870
149821
|
}
|
|
149871
149822
|
lastExtendingMethod = method;
|
|
149872
149823
|
currentTimeout = remaining;
|
|
149873
149824
|
timeoutId = setTimeout(() => {
|
|
149874
149825
|
killed = true;
|
|
149875
|
-
child.kill("SIGKILL");
|
|
149876
149826
|
this.logger.warn({ timeout: currentTimeout, method: lastExtendingMethod }, "Interactive script timed out");
|
|
149827
|
+
killForTimeout(`Script timeout: runtime killed the script after ${currentTimeout}ms${lastExtendingMethod ? ` (last extending method: ${lastExtendingMethod})` : ""}.`);
|
|
149877
149828
|
}, currentTimeout);
|
|
149878
149829
|
};
|
|
149879
149830
|
const safeWrite = (data) => {
|
|
149880
149831
|
if (childExited || !child.stdin?.writable)
|
|
149881
|
-
return;
|
|
149832
|
+
return false;
|
|
149882
149833
|
try {
|
|
149883
149834
|
child.stdin.write(data);
|
|
149835
|
+
return true;
|
|
149884
149836
|
} catch (err) {
|
|
149885
149837
|
this.logger.debug({ error: err }, "Failed to write to child stdin (process may have exited)");
|
|
149838
|
+
return false;
|
|
149886
149839
|
}
|
|
149887
149840
|
};
|
|
149888
149841
|
const writeResponse = (id, result) => {
|
|
@@ -149891,6 +149844,12 @@ var ScriptExecutorService = class ScriptExecutorService2 {
|
|
|
149891
149844
|
const writeError = (id, code, message) => {
|
|
149892
149845
|
safeWrite(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id }) + "\n");
|
|
149893
149846
|
};
|
|
149847
|
+
const writeFromKill = (id, code, message) => {
|
|
149848
|
+
const ok = safeWrite(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id }) + "\n");
|
|
149849
|
+
if (!ok) {
|
|
149850
|
+
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");
|
|
149851
|
+
}
|
|
149852
|
+
};
|
|
149894
149853
|
const rl = (0, import_readline.createInterface)({ input: child.stdout, crlfDelay: Infinity });
|
|
149895
149854
|
rl.on("line", (line) => {
|
|
149896
149855
|
if (outputTruncated)
|
|
@@ -149918,6 +149877,7 @@ var ScriptExecutorService = class ScriptExecutorService2 {
|
|
|
149918
149877
|
return;
|
|
149919
149878
|
}
|
|
149920
149879
|
inflightCount++;
|
|
149880
|
+
pendingIds.add(msg.id);
|
|
149921
149881
|
(async () => {
|
|
149922
149882
|
try {
|
|
149923
149883
|
if (msg.method === "delegate") {
|
|
@@ -149926,11 +149886,16 @@ var ScriptExecutorService = class ScriptExecutorService2 {
|
|
|
149926
149886
|
resetTimeout(toolCallTimeout + timeout2, msg.method);
|
|
149927
149887
|
}
|
|
149928
149888
|
const result = await onRequest(msg.method, msg.params);
|
|
149929
|
-
|
|
149889
|
+
if (pendingIds.delete(msg.id)) {
|
|
149890
|
+
writeResponse(msg.id, result);
|
|
149891
|
+
}
|
|
149930
149892
|
} catch (err) {
|
|
149931
|
-
|
|
149932
|
-
|
|
149893
|
+
if (pendingIds.delete(msg.id)) {
|
|
149894
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
149895
|
+
writeError(msg.id, -32e3, message);
|
|
149896
|
+
}
|
|
149933
149897
|
} finally {
|
|
149898
|
+
pendingIds.delete(msg.id);
|
|
149934
149899
|
inflightCount--;
|
|
149935
149900
|
if (inflightCount === 0 && inflightDone)
|
|
149936
149901
|
inflightDone();
|
|
@@ -154159,7 +154124,7 @@ ${cleanError}` : cleanError;
|
|
|
154159
154124
|
throw new Error("Invalid delegate params: expected { context: string, model?: string, temperature?: number }");
|
|
154160
154125
|
}
|
|
154161
154126
|
const { context: context2, model, temperature } = params;
|
|
154162
|
-
return this.handleScriptDelegate(context2, model, temperature, workspaceId, userKey, delegateDepth);
|
|
154127
|
+
return this.handleScriptDelegate(context2, model, temperature, workspaceId, userId, userKey, runtimeId, delegateDepth);
|
|
154163
154128
|
}
|
|
154164
154129
|
case "scripts/execute": {
|
|
154165
154130
|
if (!params || typeof params !== "object" || typeof params.path !== "string") {
|
|
@@ -154249,7 +154214,7 @@ ${cleanError}` : cleanError;
|
|
|
154249
154214
|
* Handle a delegate request from a TypeScript script via JSON-RPC IPC.
|
|
154250
154215
|
* Spawns a sub-agent using DelegateService and returns the result as a CallToolResult.
|
|
154251
154216
|
*/
|
|
154252
|
-
async handleScriptDelegate(context2, model, temperature, workspaceId, userKey, delegateDepth) {
|
|
154217
|
+
async handleScriptDelegate(context2, model, temperature, workspaceId, userId, userKey, runtimeId, delegateDepth) {
|
|
154253
154218
|
if (!this.delegateService) {
|
|
154254
154219
|
this.logger.warn({ event: "delegate_service_unavailable" }, "Delegate requested but DelegateService not injected");
|
|
154255
154220
|
return {
|
|
@@ -154262,14 +154227,51 @@ ${cleanError}` : cleanError;
|
|
|
154262
154227
|
isError: true
|
|
154263
154228
|
};
|
|
154264
154229
|
}
|
|
154265
|
-
|
|
154266
|
-
|
|
154267
|
-
|
|
154268
|
-
|
|
154269
|
-
|
|
154270
|
-
|
|
154271
|
-
|
|
154230
|
+
const publishMonitoring = (response) => {
|
|
154231
|
+
try {
|
|
154232
|
+
const message = new SkillCallToolRequest({
|
|
154233
|
+
type: "static",
|
|
154234
|
+
toolName: "delegate",
|
|
154235
|
+
workspaceId,
|
|
154236
|
+
from: runtimeId ?? "script",
|
|
154237
|
+
userId,
|
|
154238
|
+
userKey,
|
|
154239
|
+
arguments: {
|
|
154240
|
+
context: context2,
|
|
154241
|
+
...model !== void 0 && { model },
|
|
154242
|
+
...temperature !== void 0 && { temperature }
|
|
154243
|
+
},
|
|
154244
|
+
response,
|
|
154245
|
+
delegateDepth
|
|
154246
|
+
});
|
|
154247
|
+
this.natsService.publish(message);
|
|
154248
|
+
} catch (error48) {
|
|
154249
|
+
this.logger.error({ err: error48, event: "script_delegate_publish_failed" }, "Failed to publish script delegate monitoring event");
|
|
154250
|
+
}
|
|
154251
|
+
};
|
|
154252
|
+
let result;
|
|
154253
|
+
try {
|
|
154254
|
+
result = await this.delegateService.execute({
|
|
154255
|
+
context: context2,
|
|
154256
|
+
model,
|
|
154257
|
+
temperature,
|
|
154258
|
+
workspaceId,
|
|
154259
|
+
userKey,
|
|
154260
|
+
delegateDepth: delegateDepth ?? 0
|
|
154261
|
+
});
|
|
154262
|
+
} catch (error48) {
|
|
154263
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
154264
|
+
publishMonitoring({
|
|
154265
|
+
content: [{ type: "text", text: `Error: Delegate failed unexpectedly: ${message}` }],
|
|
154266
|
+
isError: true
|
|
154267
|
+
});
|
|
154268
|
+
throw error48;
|
|
154269
|
+
}
|
|
154270
|
+
publishMonitoring({
|
|
154271
|
+
content: result.content,
|
|
154272
|
+
...result.isError && { isError: true }
|
|
154272
154273
|
});
|
|
154274
|
+
return result;
|
|
154273
154275
|
}
|
|
154274
154276
|
/**
|
|
154275
154277
|
* Route a tool call from a script to the appropriate MCP server via NATS.
|