@cognipeer/agent-sdk 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.cjs +88 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -13
- package/dist/index.d.ts +67 -13
- package/dist/index.mjs +87 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6922,6 +6922,42 @@ async function resolveAvailableSkills(skills, opts = {}) {
|
|
|
6922
6922
|
}
|
|
6923
6923
|
return out;
|
|
6924
6924
|
}
|
|
6925
|
+
var WORD_SPLIT = /[^\p{L}\p{N}]+/u;
|
|
6926
|
+
var MIN_TERM_LENGTH = 3;
|
|
6927
|
+
var FIELD_WEIGHTS = { key: 4, title: 3, header: 2 };
|
|
6928
|
+
var wordsOf = (text) => text.toLowerCase().split(WORD_SPLIT).filter((word) => word.length >= 2);
|
|
6929
|
+
var termHitsWord = (term, word) => word === term || word.startsWith(term) || word.length >= 3 && term.startsWith(word) || term.length >= 5 && word.length >= 5 && word.slice(0, 4) === term.slice(0, 4);
|
|
6930
|
+
function searchSkills(skills, query, limit = 10) {
|
|
6931
|
+
const cap = Math.max(1, limit);
|
|
6932
|
+
const normalized = (query || "").trim().toLowerCase();
|
|
6933
|
+
const terms = [
|
|
6934
|
+
...new Set(normalized.split(WORD_SPLIT).filter((term) => term.length >= MIN_TERM_LENGTH))
|
|
6935
|
+
];
|
|
6936
|
+
if (terms.length === 0) return skills.slice(0, cap);
|
|
6937
|
+
const scored = skills.map((skill, index) => {
|
|
6938
|
+
const fields = {
|
|
6939
|
+
key: wordsOf(skill.key),
|
|
6940
|
+
title: wordsOf(skill.title || ""),
|
|
6941
|
+
header: wordsOf(skill.header || "")
|
|
6942
|
+
};
|
|
6943
|
+
const exact = skill.key.toLowerCase() === normalized || (skill.title || "").toLowerCase() === normalized;
|
|
6944
|
+
let score = exact ? 100 : 0;
|
|
6945
|
+
let coverage = 0;
|
|
6946
|
+
for (const term of terms) {
|
|
6947
|
+
let hit = false;
|
|
6948
|
+
for (const [field, weight] of Object.entries(FIELD_WEIGHTS)) {
|
|
6949
|
+
if (fields[field].some((word) => termHitsWord(term, word))) {
|
|
6950
|
+
score += weight;
|
|
6951
|
+
hit = true;
|
|
6952
|
+
}
|
|
6953
|
+
}
|
|
6954
|
+
if (hit) coverage += 1;
|
|
6955
|
+
}
|
|
6956
|
+
return { skill, score, coverage, index };
|
|
6957
|
+
}).filter((entry) => entry.score > 0);
|
|
6958
|
+
scored.sort((a, b) => b.coverage - a.coverage || b.score - a.score || a.index - b.index);
|
|
6959
|
+
return scored.slice(0, cap).map((entry) => entry.skill);
|
|
6960
|
+
}
|
|
6925
6961
|
function buildSkillHeaderBlock(skills) {
|
|
6926
6962
|
if (skills.length === 0) return "";
|
|
6927
6963
|
const lines = skills.map((skill) => `- ${skill.key}: ${skill.header}`);
|
|
@@ -6945,24 +6981,65 @@ function dedupeToolsByName(tools) {
|
|
|
6945
6981
|
|
|
6946
6982
|
// src/smart/skills/skillTools.ts
|
|
6947
6983
|
var MAX_RETURNED_INDEX = 40;
|
|
6948
|
-
var
|
|
6984
|
+
var DEFAULT_SEARCH_LIMIT = 10;
|
|
6985
|
+
var MAX_SEARCH_LIMIT = 25;
|
|
6986
|
+
var isSearchDisclosure = (policy) => policy.disclosure === "search";
|
|
6987
|
+
var keySource = (policy) => isSearchDisclosure(policy) ? "search_skills" : "<available_skills>";
|
|
6988
|
+
var openSkillDescription = (policy) => `Load a capability on demand. Pass a skillKey from ${keySource(policy)}. A small skill binds all its tools immediately; a large one returns a tool index \u2014 then call bind_skill_tools with only the tools you need. Open only what the task needs.`;
|
|
6949
6989
|
var BIND_SKILL_TOOLS_DESCRIPTION = "After open_skill on a large skill, bind a chosen subset of its tools by name. Pick the few tools the task actually needs.";
|
|
6990
|
+
var SEARCH_SKILLS_DESCRIPTION = 'Find a reusable playbook (a "skill") for the task at hand. Skills are proven, pre-written procedures for specific kinds of work \u2014 each with its own tools, which are NOT in your tool list until you open the skill. Call this early whenever a request looks like an established procedure, or when you seem to be missing a capability you would expect to have: describe the task in `query`. Returns matching skill keys; pass one to open_skill to load its instructions and tools. An empty query lists what exists.';
|
|
6950
6991
|
function findSkill(deps, key) {
|
|
6951
6992
|
return deps.skills.find((skill) => skill.key === key);
|
|
6952
6993
|
}
|
|
6994
|
+
function createSearchSkillsTool(deps) {
|
|
6995
|
+
const tool = createTool({
|
|
6996
|
+
name: "search_skills",
|
|
6997
|
+
description: SEARCH_SKILLS_DESCRIPTION,
|
|
6998
|
+
schema: zod.z.object({
|
|
6999
|
+
query: zod.z.string().optional().describe("What you are trying to do, in a few words. Omit to list available skills."),
|
|
7000
|
+
limit: zod.z.number().int().positive().optional().describe(`Max results to return (default ${DEFAULT_SEARCH_LIMIT}).`)
|
|
7001
|
+
}).strict(),
|
|
7002
|
+
func: async ({ query, limit }) => {
|
|
7003
|
+
const { skills, policy, registryRef: ref } = tool._deps;
|
|
7004
|
+
const available = await resolveAvailableSkills(skills, { modelTier: policy.modelTier });
|
|
7005
|
+
if (available.length === 0) {
|
|
7006
|
+
return { skills: [], total: 0, hint: "No skills are available in this workspace." };
|
|
7007
|
+
}
|
|
7008
|
+
const capped = Math.min(limit || DEFAULT_SEARCH_LIMIT, MAX_SEARCH_LIMIT);
|
|
7009
|
+
const matches = searchSkills(available, query, capped);
|
|
7010
|
+
const missed = matches.length === 0;
|
|
7011
|
+
const shown = missed ? available.slice(0, capped) : matches;
|
|
7012
|
+
return {
|
|
7013
|
+
skills: shown.map((skill) => ({
|
|
7014
|
+
skillKey: skill.key,
|
|
7015
|
+
title: skill.title,
|
|
7016
|
+
header: skill.header,
|
|
7017
|
+
...ref.openedSkillKeys.includes(skill.key) ? { alreadyOpen: true } : {}
|
|
7018
|
+
})),
|
|
7019
|
+
total: available.length,
|
|
7020
|
+
hint: missed ? `Nothing matched "${query}" literally \u2014 listing ${shown.length} of ${available.length} instead. Judge them by their headers; call open_skill(skillKey) if one fits, otherwise carry on without a skill.` : "Call open_skill(skillKey) to load the one that fits."
|
|
7021
|
+
};
|
|
7022
|
+
}
|
|
7023
|
+
});
|
|
7024
|
+
tool._deps = deps;
|
|
7025
|
+
tool.__source = "smart-skills";
|
|
7026
|
+
return tool;
|
|
7027
|
+
}
|
|
6953
7028
|
function createOpenSkillTool(deps) {
|
|
6954
7029
|
const tool = createTool({
|
|
6955
7030
|
name: "open_skill",
|
|
6956
|
-
description:
|
|
7031
|
+
description: openSkillDescription(deps.policy),
|
|
6957
7032
|
schema: zod.z.object({
|
|
6958
|
-
skillKey: zod.z.string().min(1).describe(
|
|
7033
|
+
skillKey: zod.z.string().min(1).describe(`A key from ${keySource(deps.policy)}.`),
|
|
6959
7034
|
query: zod.z.string().optional().describe("What you need from the skill \u2014 used to rank a large skill's tools.")
|
|
6960
7035
|
}).strict(),
|
|
6961
7036
|
func: async ({ skillKey, query }) => {
|
|
6962
7037
|
const { registryRef: ref, policy } = tool._deps;
|
|
6963
7038
|
const skill = findSkill(tool._deps, skillKey);
|
|
6964
7039
|
if (!skill) {
|
|
6965
|
-
return {
|
|
7040
|
+
return {
|
|
7041
|
+
error: `Unknown skill: ${skillKey}. ${isSearchDisclosure(policy) ? "Call search_skills to get a valid key." : "Choose a key listed in <available_skills>."}`
|
|
7042
|
+
};
|
|
6966
7043
|
}
|
|
6967
7044
|
if (skill.isAvailable && !await skill.isAvailable()) {
|
|
6968
7045
|
return { error: `Skill ${skillKey} is not available in this workspace.` };
|
|
@@ -7051,7 +7128,9 @@ function createBindSkillToolsTool(deps) {
|
|
|
7051
7128
|
return tool;
|
|
7052
7129
|
}
|
|
7053
7130
|
function createSkillTools(deps) {
|
|
7054
|
-
|
|
7131
|
+
const tools = [createOpenSkillTool(deps), createBindSkillToolsTool(deps)];
|
|
7132
|
+
if (isSearchDisclosure(deps.policy)) tools.unshift(createSearchSkillsTool(deps));
|
|
7133
|
+
return tools;
|
|
7055
7134
|
}
|
|
7056
7135
|
|
|
7057
7136
|
// src/smart/subagents/types.ts
|
|
@@ -7731,7 +7810,8 @@ function createSmartAgent(opts) {
|
|
|
7731
7810
|
if (changed) toolSet.skillRegistryRef.__onToolsChanged?.();
|
|
7732
7811
|
}
|
|
7733
7812
|
const syncPlanFromRef = (state2) => syncPlanStateWith(stateRef, state2);
|
|
7734
|
-
const
|
|
7813
|
+
const catalogDisclosure = skillPolicy.disclosure !== "search";
|
|
7814
|
+
const availableSkills = skillsEnabled && catalogDisclosure ? await resolveAvailableSkills(skills, { modelTier: skillPolicy.modelTier }) : [];
|
|
7735
7815
|
const skillBlock = availableSkills.length > 0 ? buildSkillHeaderBlock(availableSkills) : void 0;
|
|
7736
7816
|
let subagentBlock;
|
|
7737
7817
|
if (subagentsEnabled) {
|
|
@@ -11008,6 +11088,7 @@ exports.createParallelTool = createParallelTool;
|
|
|
11008
11088
|
exports.createProvider = createProvider;
|
|
11009
11089
|
exports.createRegexGuardrail = createRegexGuardrail;
|
|
11010
11090
|
exports.createResolverNode = createResolverNode;
|
|
11091
|
+
exports.createSearchSkillsTool = createSearchSkillsTool;
|
|
11011
11092
|
exports.createSkillRegistryRef = createSkillRegistryRef;
|
|
11012
11093
|
exports.createSkillTools = createSkillTools;
|
|
11013
11094
|
exports.createSmartAgent = createSmartAgent;
|
|
@@ -11059,6 +11140,7 @@ exports.resolveUserQuestionState = resolveUserQuestionState;
|
|
|
11059
11140
|
exports.restoreSnapshot = restoreSnapshot;
|
|
11060
11141
|
exports.runSmartAgentEvalHarness = runSmartAgentEvalHarness;
|
|
11061
11142
|
exports.scoreItemsByRelevance = scoreItemsByRelevance;
|
|
11143
|
+
exports.searchSkills = searchSkills;
|
|
11062
11144
|
exports.seedChildMessages = seedChildMessages;
|
|
11063
11145
|
exports.selectTopIndicesInOrder = selectTopIndicesInOrder;
|
|
11064
11146
|
exports.setTokenCounter = setTokenCounter;
|