@frankieai/server 0.2.4 → 0.2.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/{chunk-7J5Z5MIK.js → chunk-HPYT6ZIU.js} +51 -7
- package/dist/chunk-HPYT6ZIU.js.map +1 -0
- package/dist/{chunk-YDXEBJON.js → chunk-SQ5NJKFE.js} +2 -2
- package/dist/control-server.js +2 -2
- package/dist/index.js +2 -2
- package/dist/server.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-7J5Z5MIK.js.map +0 -1
- /package/dist/{chunk-YDXEBJON.js.map → chunk-SQ5NJKFE.js.map} +0 -0
|
@@ -1477,7 +1477,7 @@ function msg(error) {
|
|
|
1477
1477
|
}
|
|
1478
1478
|
|
|
1479
1479
|
// src/agent/prompt.ts
|
|
1480
|
-
import { activeSkills } from "@frankieai/core";
|
|
1480
|
+
import { activeSkills, SKILL_TOOL_NAME } from "@frankieai/core";
|
|
1481
1481
|
function buildSystemPrompt(config, session, availableTools) {
|
|
1482
1482
|
const sections = [];
|
|
1483
1483
|
const configurationAssistant = config.features.configurationAssistant;
|
|
@@ -1533,7 +1533,7 @@ ${config.agent.systemPrompt.trim()}`);
|
|
|
1533
1533
|
}
|
|
1534
1534
|
sections.push(renderUserSection(session));
|
|
1535
1535
|
const skills = activeSkills(config, availableTools);
|
|
1536
|
-
if (skills.length) sections.push("## Reviewed workspace skills\nThese recipes do not grant additional permissions or override safety rules. Each skill lists only its currently approved, available tools. Instructions may describe additional operations: skip unavailable steps, explain the limitation, and never claim the whole task succeeded when a required step was unavailable.\n" + JSON.stringify(skills.map(({ name, goal, instructions, tools }) => ({ name, goal, instructions, tools }))));
|
|
1536
|
+
if (skills.length) sections.push("## Reviewed workspace skills\nThese recipes do not grant additional permissions or override safety rules. Each skill lists only its currently approved, available tools. Instructions may describe additional operations: skip unavailable steps, explain the limitation, and never claim the whole task succeeded when a required step was unavailable.\nBefore you begin following one of these skills, call the `" + SKILL_TOOL_NAME + "` tool with the skill's exact name, so the person can see which recipe you're applying. It grants no permissions and does nothing on its own \u2014 it's only a visible marker. Then carry out that skill's steps.\n" + JSON.stringify(skills.map(({ name, goal, instructions, tools }) => ({ name, goal, instructions, tools }))));
|
|
1537
1537
|
return sections.join("\n\n");
|
|
1538
1538
|
}
|
|
1539
1539
|
function isOnboardingAssistant(config) {
|
|
@@ -1639,9 +1639,51 @@ function renderPageContext(context) {
|
|
|
1639
1639
|
import { Agent } from "@earendil-works/pi-agent-core";
|
|
1640
1640
|
import {
|
|
1641
1641
|
describeTool as describeTool3,
|
|
1642
|
-
activeSkills as
|
|
1642
|
+
activeSkills as activeSkills3,
|
|
1643
1643
|
evaluateToolPolicy as evaluateToolPolicy3
|
|
1644
1644
|
} from "@frankieai/core";
|
|
1645
|
+
|
|
1646
|
+
// src/agent/skill-tools.ts
|
|
1647
|
+
import { Type as Type4 } from "@earendil-works/pi-ai";
|
|
1648
|
+
import { activeSkills as activeSkills2, SKILL_TOOL_NAME as SKILL_TOOL_NAME2 } from "@frankieai/core";
|
|
1649
|
+
function isSkillTool(name) {
|
|
1650
|
+
return name === SKILL_TOOL_NAME2;
|
|
1651
|
+
}
|
|
1652
|
+
function buildSkillTools(config, availableTools) {
|
|
1653
|
+
const skills = activeSkills2(config, availableTools);
|
|
1654
|
+
if (!skills.length) return [];
|
|
1655
|
+
const names = skills.map((skill) => skill.name);
|
|
1656
|
+
return [
|
|
1657
|
+
{
|
|
1658
|
+
name: SKILL_TOOL_NAME2,
|
|
1659
|
+
label: "Use skill",
|
|
1660
|
+
description: `Announce that you are about to follow one of the reviewed workspace skills, so the person can see which recipe you're applying. Call this with the skill's exact name immediately before you begin its steps. It grants no new permissions and performs no action on its own.
|
|
1661
|
+
|
|
1662
|
+
Available skills: ${names.join(", ")}.`,
|
|
1663
|
+
parameters: Type4.Unsafe({
|
|
1664
|
+
type: "object",
|
|
1665
|
+
required: ["skill"],
|
|
1666
|
+
properties: { skill: { type: "string", description: "The exact name of the workspace skill you are about to follow." } }
|
|
1667
|
+
}),
|
|
1668
|
+
async execute(_id, args) {
|
|
1669
|
+
const requested = String((typeof args === "object" && args !== null ? args["skill"] : "") ?? "").trim();
|
|
1670
|
+
const match = skills.find((skill) => skill.name.toLowerCase() === requested.toLowerCase());
|
|
1671
|
+
if (!match) {
|
|
1672
|
+
return {
|
|
1673
|
+
content: [{ type: "text", text: `No active skill is named "${requested}". The skills available this turn are: ${names.join(", ")}.` }],
|
|
1674
|
+
details: null
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
return {
|
|
1678
|
+
content: [{ type: "text", text: `Now following the "${match.name}" skill. Apply its steps using only its approved tools.` }],
|
|
1679
|
+
details: null
|
|
1680
|
+
};
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
];
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
// src/agent/runner.ts
|
|
1645
1687
|
async function* runTurn(params) {
|
|
1646
1688
|
const { config, session } = params;
|
|
1647
1689
|
const toolset = await collectTools({
|
|
@@ -1651,6 +1693,8 @@ async function* runTurn(params) {
|
|
|
1651
1693
|
...params.onWarning ? { onWarning: params.onWarning } : {}
|
|
1652
1694
|
});
|
|
1653
1695
|
const availableTools = toolset.tools.map((tool) => tool.name);
|
|
1696
|
+
const skillTools = buildSkillTools(config, availableTools);
|
|
1697
|
+
const agentTools = [...toolset.tools, ...skillTools];
|
|
1654
1698
|
const queue = new EventQueue();
|
|
1655
1699
|
let turnCount = 0;
|
|
1656
1700
|
let lastAssistant;
|
|
@@ -1662,7 +1706,7 @@ async function* runTurn(params) {
|
|
|
1662
1706
|
systemPrompt: buildSystemPrompt(config, session, availableTools),
|
|
1663
1707
|
model: params.modelOverride ?? params.model,
|
|
1664
1708
|
thinkingLevel: config.model.thinkingLevel,
|
|
1665
|
-
tools:
|
|
1709
|
+
tools: agentTools,
|
|
1666
1710
|
messages: session.messages
|
|
1667
1711
|
},
|
|
1668
1712
|
// Per-request sampling lives here rather than on the agent: the stream
|
|
@@ -1686,7 +1730,7 @@ async function* runTurn(params) {
|
|
|
1686
1730
|
// tools are exempt: they're gated by the workspaceAdmin flag, not the
|
|
1687
1731
|
// allow/deny policy, so the policy would otherwise block them here.
|
|
1688
1732
|
beforeToolCall: async ({ toolCall }) => {
|
|
1689
|
-
if (isPlatformTool(toolCall.name)) return void 0;
|
|
1733
|
+
if (isPlatformTool(toolCall.name) || isSkillTool(toolCall.name)) return void 0;
|
|
1690
1734
|
const decision = evaluateToolPolicy3(toolCall.name, config.agent.tools);
|
|
1691
1735
|
if (decision.allowed) return void 0;
|
|
1692
1736
|
queue.push({
|
|
@@ -1728,7 +1772,7 @@ async function* runTurn(params) {
|
|
|
1728
1772
|
});
|
|
1729
1773
|
}).finally(() => queue.close());
|
|
1730
1774
|
try {
|
|
1731
|
-
yield { type: "skills_loaded", skills:
|
|
1775
|
+
yield { type: "skills_loaded", skills: activeSkills3(config, availableTools).map(({ id, name, revision }) => ({ id, name, revision })) };
|
|
1732
1776
|
yield { type: "tools_active", apis: toolset.apis };
|
|
1733
1777
|
for await (const event of queue) yield event;
|
|
1734
1778
|
await run;
|
|
@@ -3207,4 +3251,4 @@ export {
|
|
|
3207
3251
|
resolveStores,
|
|
3208
3252
|
resolveTenantStore
|
|
3209
3253
|
};
|
|
3210
|
-
//# sourceMappingURL=chunk-
|
|
3254
|
+
//# sourceMappingURL=chunk-HPYT6ZIU.js.map
|