@cognipeer/agent-sdk 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.cjs +95 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -13
- package/dist/index.d.ts +73 -13
- package/dist/index.mjs +93 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4573,6 +4573,7 @@ function resolveUserQuestionState(state, resolution) {
|
|
|
4573
4573
|
ctx
|
|
4574
4574
|
};
|
|
4575
4575
|
}
|
|
4576
|
+
var ASK_USER_TOOL_NAME = "ask_user_question";
|
|
4576
4577
|
var DEFAULT_DESCRIPTION_WITH_FREETEXT = "Pause the agent and surface a structured prompt to the human user when you genuinely cannot proceed without their input. Group up to 4 closely related questions into a single call. Prefer concrete options the user can pick over open-ended free-text \u2014 list `options` whenever you can anticipate the choices. The user may type a custom answer for any question. Do not use this tool for things you can deduce from the conversation, the system prompt, or another tool. After the user answers, their selections come back as the tool result.";
|
|
4577
4578
|
var DEFAULT_DESCRIPTION_NO_FREETEXT = "Pause the agent and surface a structured multi-choice prompt to the human user when you genuinely cannot proceed without their input. Group up to 4 closely related questions into a single call. Every question MUST include at least two `options` \u2014 free-text answers are disabled for this agent. Do not use this tool for things you can deduce from the conversation, the system prompt, or another tool. After the user picks, their selections come back as the tool result.";
|
|
4578
4579
|
function buildOptionSchema() {
|
|
@@ -4608,7 +4609,7 @@ function createAskUserQuestionTool(stateRef, config) {
|
|
|
4608
4609
|
const description = config.promptOverride ?? (allowFreeText ? DEFAULT_DESCRIPTION_WITH_FREETEXT : DEFAULT_DESCRIPTION_NO_FREETEXT);
|
|
4609
4610
|
const questionSchema = buildQuestionSchema(allowFreeText);
|
|
4610
4611
|
const askUser = createTool({
|
|
4611
|
-
name:
|
|
4612
|
+
name: ASK_USER_TOOL_NAME,
|
|
4612
4613
|
description,
|
|
4613
4614
|
schema: zod.z.object({
|
|
4614
4615
|
questions: zod.z.array(questionSchema).min(1).max(4).describe("1-4 related questions to ask in a single pause.")
|
|
@@ -4624,7 +4625,7 @@ function createAskUserQuestionTool(stateRef, config) {
|
|
|
4624
4625
|
const entry = {
|
|
4625
4626
|
id: nanoid.nanoid(),
|
|
4626
4627
|
toolCallId,
|
|
4627
|
-
toolName:
|
|
4628
|
+
toolName: ASK_USER_TOOL_NAME,
|
|
4628
4629
|
questions,
|
|
4629
4630
|
status: "pending",
|
|
4630
4631
|
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4980,14 +4981,15 @@ function createAgent(opts) {
|
|
|
4980
4981
|
})();
|
|
4981
4982
|
const askUserOnQuestion = typeof opts.humanInTheLoop?.askUser === "object" ? opts.humanInTheLoop?.askUser?.onQuestion : void 0;
|
|
4982
4983
|
const askUserStateRef = askUserConfig ? { pendingUserQuestions: void 0, ctx: void 0, __onEvent: void 0, __currentToolCallId: void 0 } : void 0;
|
|
4983
|
-
|
|
4984
|
+
const hasTool = (name) => toolsBase.some((tool) => tool?.name === name);
|
|
4985
|
+
if (askUserConfig && askUserStateRef && !hasTool(ASK_USER_TOOL_NAME)) {
|
|
4984
4986
|
toolsBase.push(createAskUserQuestionTool(askUserStateRef, askUserConfig));
|
|
4985
4987
|
}
|
|
4986
4988
|
const soManager = opts.outputSchema ? new StructuredOutputManager(opts.outputSchema, resolveStrategy(opts.model)) : void 0;
|
|
4987
4989
|
if (soManager) {
|
|
4988
4990
|
const modelCapabilities = getModelCapabilities(opts.model);
|
|
4989
4991
|
const responseTool = soManager.getResponseTool();
|
|
4990
|
-
if (responseTool && modelCapabilities.structuredOutput !== "native") {
|
|
4992
|
+
if (responseTool && modelCapabilities.structuredOutput !== "native" && !hasTool(responseTool.name)) {
|
|
4991
4993
|
toolsBase.push(responseTool);
|
|
4992
4994
|
}
|
|
4993
4995
|
}
|
|
@@ -6920,6 +6922,42 @@ async function resolveAvailableSkills(skills, opts = {}) {
|
|
|
6920
6922
|
}
|
|
6921
6923
|
return out;
|
|
6922
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
|
+
}
|
|
6923
6961
|
function buildSkillHeaderBlock(skills) {
|
|
6924
6962
|
if (skills.length === 0) return "";
|
|
6925
6963
|
const lines = skills.map((skill) => `- ${skill.key}: ${skill.header}`);
|
|
@@ -6943,24 +6981,65 @@ function dedupeToolsByName(tools) {
|
|
|
6943
6981
|
|
|
6944
6982
|
// src/smart/skills/skillTools.ts
|
|
6945
6983
|
var MAX_RETURNED_INDEX = 40;
|
|
6946
|
-
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.`;
|
|
6947
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.';
|
|
6948
6991
|
function findSkill(deps, key) {
|
|
6949
6992
|
return deps.skills.find((skill) => skill.key === key);
|
|
6950
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
|
+
}
|
|
6951
7028
|
function createOpenSkillTool(deps) {
|
|
6952
7029
|
const tool = createTool({
|
|
6953
7030
|
name: "open_skill",
|
|
6954
|
-
description:
|
|
7031
|
+
description: openSkillDescription(deps.policy),
|
|
6955
7032
|
schema: zod.z.object({
|
|
6956
|
-
skillKey: zod.z.string().min(1).describe(
|
|
7033
|
+
skillKey: zod.z.string().min(1).describe(`A key from ${keySource(deps.policy)}.`),
|
|
6957
7034
|
query: zod.z.string().optional().describe("What you need from the skill \u2014 used to rank a large skill's tools.")
|
|
6958
7035
|
}).strict(),
|
|
6959
7036
|
func: async ({ skillKey, query }) => {
|
|
6960
7037
|
const { registryRef: ref, policy } = tool._deps;
|
|
6961
7038
|
const skill = findSkill(tool._deps, skillKey);
|
|
6962
7039
|
if (!skill) {
|
|
6963
|
-
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
|
+
};
|
|
6964
7043
|
}
|
|
6965
7044
|
if (skill.isAvailable && !await skill.isAvailable()) {
|
|
6966
7045
|
return { error: `Skill ${skillKey} is not available in this workspace.` };
|
|
@@ -7049,7 +7128,9 @@ function createBindSkillToolsTool(deps) {
|
|
|
7049
7128
|
return tool;
|
|
7050
7129
|
}
|
|
7051
7130
|
function createSkillTools(deps) {
|
|
7052
|
-
|
|
7131
|
+
const tools = [createOpenSkillTool(deps), createBindSkillToolsTool(deps)];
|
|
7132
|
+
if (isSearchDisclosure(deps.policy)) tools.unshift(createSearchSkillsTool(deps));
|
|
7133
|
+
return tools;
|
|
7053
7134
|
}
|
|
7054
7135
|
|
|
7055
7136
|
// src/smart/subagents/types.ts
|
|
@@ -7729,7 +7810,8 @@ function createSmartAgent(opts) {
|
|
|
7729
7810
|
if (changed) toolSet.skillRegistryRef.__onToolsChanged?.();
|
|
7730
7811
|
}
|
|
7731
7812
|
const syncPlanFromRef = (state2) => syncPlanStateWith(stateRef, state2);
|
|
7732
|
-
const
|
|
7813
|
+
const catalogDisclosure = skillPolicy.disclosure !== "search";
|
|
7814
|
+
const availableSkills = skillsEnabled && catalogDisclosure ? await resolveAvailableSkills(skills, { modelTier: skillPolicy.modelTier }) : [];
|
|
7733
7815
|
const skillBlock = availableSkills.length > 0 ? buildSkillHeaderBlock(availableSkills) : void 0;
|
|
7734
7816
|
let subagentBlock;
|
|
7735
7817
|
if (subagentsEnabled) {
|
|
@@ -10947,6 +11029,7 @@ function createProvider(config) {
|
|
|
10947
11029
|
}
|
|
10948
11030
|
}
|
|
10949
11031
|
|
|
11032
|
+
exports.ASK_USER_TOOL_NAME = ASK_USER_TOOL_NAME;
|
|
10950
11033
|
exports.AnthropicProvider = AnthropicProvider;
|
|
10951
11034
|
exports.AzureProvider = AzureProvider;
|
|
10952
11035
|
exports.BaseProvider = BaseProvider;
|
|
@@ -11005,6 +11088,7 @@ exports.createParallelTool = createParallelTool;
|
|
|
11005
11088
|
exports.createProvider = createProvider;
|
|
11006
11089
|
exports.createRegexGuardrail = createRegexGuardrail;
|
|
11007
11090
|
exports.createResolverNode = createResolverNode;
|
|
11091
|
+
exports.createSearchSkillsTool = createSearchSkillsTool;
|
|
11008
11092
|
exports.createSkillRegistryRef = createSkillRegistryRef;
|
|
11009
11093
|
exports.createSkillTools = createSkillTools;
|
|
11010
11094
|
exports.createSmartAgent = createSmartAgent;
|
|
@@ -11056,6 +11140,7 @@ exports.resolveUserQuestionState = resolveUserQuestionState;
|
|
|
11056
11140
|
exports.restoreSnapshot = restoreSnapshot;
|
|
11057
11141
|
exports.runSmartAgentEvalHarness = runSmartAgentEvalHarness;
|
|
11058
11142
|
exports.scoreItemsByRelevance = scoreItemsByRelevance;
|
|
11143
|
+
exports.searchSkills = searchSkills;
|
|
11059
11144
|
exports.seedChildMessages = seedChildMessages;
|
|
11060
11145
|
exports.selectTopIndicesInOrder = selectTopIndicesInOrder;
|
|
11061
11146
|
exports.setTokenCounter = setTokenCounter;
|