From 53a3b7d687e87903c0205ef431dd529781a1fd26 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Mon, 13 Jul 2026 08:44:11 +0800 Subject: [PATCH] feat(common): surface skill file path in useSkill tool result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows the agent to resolve sibling resource files relative to the skill directory. 🤖 Generated with [Pochi](https://getpochi.com) | [Task](https://app.getpochi.com/share/p-a54b33c248d440c6bb95d72fc689a7ac) Co-Authored-By: Pochi --- .../src/base/prompts/__tests__/skill.test.ts | 38 +++++++++++++++++++ packages/common/src/base/prompts/skill.ts | 9 +++++ 2 files changed, 47 insertions(+) create mode 100644 packages/common/src/base/prompts/__tests__/skill.test.ts diff --git a/packages/common/src/base/prompts/__tests__/skill.test.ts b/packages/common/src/base/prompts/__tests__/skill.test.ts new file mode 100644 index 0000000000..4098db6488 --- /dev/null +++ b/packages/common/src/base/prompts/__tests__/skill.test.ts @@ -0,0 +1,38 @@ +import type { Skill } from "@getpochi/tools"; +import { describe, expect, it } from "vitest"; +import { createUseSkillResult } from "../skill"; + +const baseSkill: Skill = { + name: "demo-skill", + description: "A demo skill", + filePath: ".pochi/skills/demo-skill/SKILL.md", + instructions: "Do the thing.", +}; + +describe("createUseSkillResult", () => { + it("prepends the skill file path to the result", () => { + const result = createUseSkillResult(baseSkill); + expect(result).toContain( + "Skill location: .pochi/skills/demo-skill/SKILL.md", + ); + expect(result).toContain("Do the thing."); + }); + + it("keeps tool restriction instructions alongside the path", () => { + const result = createUseSkillResult({ + ...baseSkill, + allowedTools: "readFile writeToFile", + }); + expect(result).toContain("Skill location:"); + expect(result).toContain( + "This skill is restricted to use only the following tools: readFile writeToFile", + ); + expect(result).toContain("Do the thing."); + }); + + it("omits the location line when no file path is available", () => { + const result = createUseSkillResult({ ...baseSkill, filePath: "" }); + expect(result).not.toContain("Skill location:"); + expect(result).toBe("Do the thing."); + }); +}); diff --git a/packages/common/src/base/prompts/skill.ts b/packages/common/src/base/prompts/skill.ts index d3e5b6f8f8..a496df2d01 100644 --- a/packages/common/src/base/prompts/skill.ts +++ b/packages/common/src/base/prompts/skill.ts @@ -23,6 +23,15 @@ export function createUseSkillResult(skill: Skill): string { You must ONLY use these approved tools when executing this skill. Do not use any other tools that are not explicitly listed above. +${prompt}`; + } + + // Surface the skill's file path so the model can resolve sibling resources + // (scripts/, references/, assets/) relative to the skill's directory. + if (skill.filePath?.trim()) { + prompt = `Skill location: ${skill.filePath.trim()} +Use the directory containing this file as the base directory for resolving any relative resource paths referenced in the instructions below. + ${prompt}`; }