@cognipeer/agent-sdk 0.8.4 → 0.8.6
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 +113 -42
- 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 +112 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -808,6 +808,28 @@ function normalizeUsage(raw) {
|
|
|
808
808
|
};
|
|
809
809
|
return normalized;
|
|
810
810
|
}
|
|
811
|
+
function recordUsage(state, modelName, normalized) {
|
|
812
|
+
const usageState = state.usage || { perRequest: [], totals: {} };
|
|
813
|
+
const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
814
|
+
const cachedInput = normalized.prompt_tokens_details?.cached_tokens;
|
|
815
|
+
usageState.perRequest.push({
|
|
816
|
+
id,
|
|
817
|
+
modelName,
|
|
818
|
+
usage: normalized,
|
|
819
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
820
|
+
turn: usageState.perRequest.length + 1,
|
|
821
|
+
cachedInput
|
|
822
|
+
});
|
|
823
|
+
const previous = usageState.totals[modelName] || { input: 0, output: 0, total: 0, cachedInput: 0 };
|
|
824
|
+
usageState.totals[modelName] = {
|
|
825
|
+
input: previous.input + (Number(normalized.prompt_tokens) || 0),
|
|
826
|
+
output: previous.output + (Number(normalized.completion_tokens) || 0),
|
|
827
|
+
total: previous.total + (Number(normalized.total_tokens) || 0),
|
|
828
|
+
cachedInput: previous.cachedInput + (Number(cachedInput) || 0)
|
|
829
|
+
};
|
|
830
|
+
state.usage = usageState;
|
|
831
|
+
return id;
|
|
832
|
+
}
|
|
811
833
|
function num(...vals) {
|
|
812
834
|
for (const v of vals) {
|
|
813
835
|
if (v === 0) return 0;
|
|
@@ -2946,24 +2968,7 @@ function createAgentCoreNode(opts) {
|
|
|
2946
2968
|
messageList: messagesWithResponse
|
|
2947
2969
|
});
|
|
2948
2970
|
if (normalized) {
|
|
2949
|
-
|
|
2950
|
-
const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
2951
|
-
const turn = usageState.perRequest.length + 1;
|
|
2952
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2953
|
-
const cachedInputTok = normalized.prompt_tokens_details?.cached_tokens;
|
|
2954
|
-
usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
|
|
2955
|
-
const inputTok = normalized.prompt_tokens;
|
|
2956
|
-
const outputTok = normalized.completion_tokens;
|
|
2957
|
-
const totalTok = normalized.total_tokens;
|
|
2958
|
-
const key = modelName;
|
|
2959
|
-
const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
|
|
2960
|
-
usageState.totals[key] = {
|
|
2961
|
-
input: agg.input + (Number(inputTok) || 0),
|
|
2962
|
-
output: agg.output + (Number(outputTok) || 0),
|
|
2963
|
-
total: agg.total + (Number(totalTok) || 0),
|
|
2964
|
-
cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
|
|
2965
|
-
};
|
|
2966
|
-
state.usage = usageState;
|
|
2971
|
+
recordUsage(state, modelName, normalized);
|
|
2967
2972
|
}
|
|
2968
2973
|
return { messages: messagesWithResponse, usage: state.usage };
|
|
2969
2974
|
};
|
|
@@ -5746,24 +5751,7 @@ function createAgentNode(opts) {
|
|
|
5746
5751
|
messageList: messagesWithResponse
|
|
5747
5752
|
});
|
|
5748
5753
|
if (normalized) {
|
|
5749
|
-
|
|
5750
|
-
const id = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
5751
|
-
const turn = usageState.perRequest.length + 1;
|
|
5752
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
5753
|
-
const cachedInputTok = normalized.prompt_tokens_details.cached_tokens;
|
|
5754
|
-
usageState.perRequest.push({ id, modelName, usage: normalized, timestamp, turn, cachedInput: cachedInputTok });
|
|
5755
|
-
const inputTok = normalized.prompt_tokens;
|
|
5756
|
-
const outputTok = normalized.completion_tokens;
|
|
5757
|
-
const totalTok = normalized.total_tokens;
|
|
5758
|
-
const key = modelName;
|
|
5759
|
-
const agg = usageState.totals[key] || { input: 0, output: 0, total: 0, cachedInput: 0 };
|
|
5760
|
-
usageState.totals[key] = {
|
|
5761
|
-
input: agg.input + (Number(inputTok) || 0),
|
|
5762
|
-
output: agg.output + (Number(outputTok) || 0),
|
|
5763
|
-
total: agg.total + (Number(totalTok) || 0),
|
|
5764
|
-
cachedInput: agg.cachedInput + (Number(cachedInputTok) || 0)
|
|
5765
|
-
};
|
|
5766
|
-
state.usage = usageState;
|
|
5754
|
+
recordUsage(state, modelName, normalized);
|
|
5767
5755
|
}
|
|
5768
5756
|
return { messages: messagesWithResponse, usage: state.usage };
|
|
5769
5757
|
};
|
|
@@ -6207,6 +6195,7 @@ ${canonicalFacts.length > 0 ? canonicalFacts.map((fact) => `- ${fact.key}: ${fac
|
|
|
6207
6195
|
outputTokensActual = normalized.completion_tokens;
|
|
6208
6196
|
totalTokensActual = normalized.total_tokens;
|
|
6209
6197
|
cachedInputTokens = normalized.prompt_tokens_details?.cached_tokens;
|
|
6198
|
+
recordUsage(state, getModelName(model) || "unknown_model", normalized);
|
|
6210
6199
|
}
|
|
6211
6200
|
} catch (err) {
|
|
6212
6201
|
durationMs = Date.now() - startTime;
|
|
@@ -6922,6 +6911,42 @@ async function resolveAvailableSkills(skills, opts = {}) {
|
|
|
6922
6911
|
}
|
|
6923
6912
|
return out;
|
|
6924
6913
|
}
|
|
6914
|
+
var WORD_SPLIT = /[^\p{L}\p{N}]+/u;
|
|
6915
|
+
var MIN_TERM_LENGTH = 3;
|
|
6916
|
+
var FIELD_WEIGHTS = { key: 4, title: 3, header: 2 };
|
|
6917
|
+
var wordsOf = (text) => text.toLowerCase().split(WORD_SPLIT).filter((word) => word.length >= 2);
|
|
6918
|
+
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);
|
|
6919
|
+
function searchSkills(skills, query, limit = 10) {
|
|
6920
|
+
const cap = Math.max(1, limit);
|
|
6921
|
+
const normalized = (query || "").trim().toLowerCase();
|
|
6922
|
+
const terms = [
|
|
6923
|
+
...new Set(normalized.split(WORD_SPLIT).filter((term) => term.length >= MIN_TERM_LENGTH))
|
|
6924
|
+
];
|
|
6925
|
+
if (terms.length === 0) return skills.slice(0, cap);
|
|
6926
|
+
const scored = skills.map((skill, index) => {
|
|
6927
|
+
const fields = {
|
|
6928
|
+
key: wordsOf(skill.key),
|
|
6929
|
+
title: wordsOf(skill.title || ""),
|
|
6930
|
+
header: wordsOf(skill.header || "")
|
|
6931
|
+
};
|
|
6932
|
+
const exact = skill.key.toLowerCase() === normalized || (skill.title || "").toLowerCase() === normalized;
|
|
6933
|
+
let score = exact ? 100 : 0;
|
|
6934
|
+
let coverage = 0;
|
|
6935
|
+
for (const term of terms) {
|
|
6936
|
+
let hit = false;
|
|
6937
|
+
for (const [field, weight] of Object.entries(FIELD_WEIGHTS)) {
|
|
6938
|
+
if (fields[field].some((word) => termHitsWord(term, word))) {
|
|
6939
|
+
score += weight;
|
|
6940
|
+
hit = true;
|
|
6941
|
+
}
|
|
6942
|
+
}
|
|
6943
|
+
if (hit) coverage += 1;
|
|
6944
|
+
}
|
|
6945
|
+
return { skill, score, coverage, index };
|
|
6946
|
+
}).filter((entry) => entry.score > 0);
|
|
6947
|
+
scored.sort((a, b) => b.coverage - a.coverage || b.score - a.score || a.index - b.index);
|
|
6948
|
+
return scored.slice(0, cap).map((entry) => entry.skill);
|
|
6949
|
+
}
|
|
6925
6950
|
function buildSkillHeaderBlock(skills) {
|
|
6926
6951
|
if (skills.length === 0) return "";
|
|
6927
6952
|
const lines = skills.map((skill) => `- ${skill.key}: ${skill.header}`);
|
|
@@ -6945,24 +6970,65 @@ function dedupeToolsByName(tools) {
|
|
|
6945
6970
|
|
|
6946
6971
|
// src/smart/skills/skillTools.ts
|
|
6947
6972
|
var MAX_RETURNED_INDEX = 40;
|
|
6948
|
-
var
|
|
6973
|
+
var DEFAULT_SEARCH_LIMIT = 10;
|
|
6974
|
+
var MAX_SEARCH_LIMIT = 25;
|
|
6975
|
+
var isSearchDisclosure = (policy) => policy.disclosure === "search";
|
|
6976
|
+
var keySource = (policy) => isSearchDisclosure(policy) ? "search_skills" : "<available_skills>";
|
|
6977
|
+
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
6978
|
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.";
|
|
6979
|
+
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
6980
|
function findSkill(deps, key) {
|
|
6951
6981
|
return deps.skills.find((skill) => skill.key === key);
|
|
6952
6982
|
}
|
|
6983
|
+
function createSearchSkillsTool(deps) {
|
|
6984
|
+
const tool = createTool({
|
|
6985
|
+
name: "search_skills",
|
|
6986
|
+
description: SEARCH_SKILLS_DESCRIPTION,
|
|
6987
|
+
schema: zod.z.object({
|
|
6988
|
+
query: zod.z.string().optional().describe("What you are trying to do, in a few words. Omit to list available skills."),
|
|
6989
|
+
limit: zod.z.number().int().positive().optional().describe(`Max results to return (default ${DEFAULT_SEARCH_LIMIT}).`)
|
|
6990
|
+
}).strict(),
|
|
6991
|
+
func: async ({ query, limit }) => {
|
|
6992
|
+
const { skills, policy, registryRef: ref } = tool._deps;
|
|
6993
|
+
const available = await resolveAvailableSkills(skills, { modelTier: policy.modelTier });
|
|
6994
|
+
if (available.length === 0) {
|
|
6995
|
+
return { skills: [], total: 0, hint: "No skills are available in this workspace." };
|
|
6996
|
+
}
|
|
6997
|
+
const capped = Math.min(limit || DEFAULT_SEARCH_LIMIT, MAX_SEARCH_LIMIT);
|
|
6998
|
+
const matches = searchSkills(available, query, capped);
|
|
6999
|
+
const missed = matches.length === 0;
|
|
7000
|
+
const shown = missed ? available.slice(0, capped) : matches;
|
|
7001
|
+
return {
|
|
7002
|
+
skills: shown.map((skill) => ({
|
|
7003
|
+
skillKey: skill.key,
|
|
7004
|
+
title: skill.title,
|
|
7005
|
+
header: skill.header,
|
|
7006
|
+
...ref.openedSkillKeys.includes(skill.key) ? { alreadyOpen: true } : {}
|
|
7007
|
+
})),
|
|
7008
|
+
total: available.length,
|
|
7009
|
+
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."
|
|
7010
|
+
};
|
|
7011
|
+
}
|
|
7012
|
+
});
|
|
7013
|
+
tool._deps = deps;
|
|
7014
|
+
tool.__source = "smart-skills";
|
|
7015
|
+
return tool;
|
|
7016
|
+
}
|
|
6953
7017
|
function createOpenSkillTool(deps) {
|
|
6954
7018
|
const tool = createTool({
|
|
6955
7019
|
name: "open_skill",
|
|
6956
|
-
description:
|
|
7020
|
+
description: openSkillDescription(deps.policy),
|
|
6957
7021
|
schema: zod.z.object({
|
|
6958
|
-
skillKey: zod.z.string().min(1).describe(
|
|
7022
|
+
skillKey: zod.z.string().min(1).describe(`A key from ${keySource(deps.policy)}.`),
|
|
6959
7023
|
query: zod.z.string().optional().describe("What you need from the skill \u2014 used to rank a large skill's tools.")
|
|
6960
7024
|
}).strict(),
|
|
6961
7025
|
func: async ({ skillKey, query }) => {
|
|
6962
7026
|
const { registryRef: ref, policy } = tool._deps;
|
|
6963
7027
|
const skill = findSkill(tool._deps, skillKey);
|
|
6964
7028
|
if (!skill) {
|
|
6965
|
-
return {
|
|
7029
|
+
return {
|
|
7030
|
+
error: `Unknown skill: ${skillKey}. ${isSearchDisclosure(policy) ? "Call search_skills to get a valid key." : "Choose a key listed in <available_skills>."}`
|
|
7031
|
+
};
|
|
6966
7032
|
}
|
|
6967
7033
|
if (skill.isAvailable && !await skill.isAvailable()) {
|
|
6968
7034
|
return { error: `Skill ${skillKey} is not available in this workspace.` };
|
|
@@ -7051,7 +7117,9 @@ function createBindSkillToolsTool(deps) {
|
|
|
7051
7117
|
return tool;
|
|
7052
7118
|
}
|
|
7053
7119
|
function createSkillTools(deps) {
|
|
7054
|
-
|
|
7120
|
+
const tools = [createOpenSkillTool(deps), createBindSkillToolsTool(deps)];
|
|
7121
|
+
if (isSearchDisclosure(deps.policy)) tools.unshift(createSearchSkillsTool(deps));
|
|
7122
|
+
return tools;
|
|
7055
7123
|
}
|
|
7056
7124
|
|
|
7057
7125
|
// src/smart/subagents/types.ts
|
|
@@ -7731,7 +7799,8 @@ function createSmartAgent(opts) {
|
|
|
7731
7799
|
if (changed) toolSet.skillRegistryRef.__onToolsChanged?.();
|
|
7732
7800
|
}
|
|
7733
7801
|
const syncPlanFromRef = (state2) => syncPlanStateWith(stateRef, state2);
|
|
7734
|
-
const
|
|
7802
|
+
const catalogDisclosure = skillPolicy.disclosure !== "search";
|
|
7803
|
+
const availableSkills = skillsEnabled && catalogDisclosure ? await resolveAvailableSkills(skills, { modelTier: skillPolicy.modelTier }) : [];
|
|
7735
7804
|
const skillBlock = availableSkills.length > 0 ? buildSkillHeaderBlock(availableSkills) : void 0;
|
|
7736
7805
|
let subagentBlock;
|
|
7737
7806
|
if (subagentsEnabled) {
|
|
@@ -11008,6 +11077,7 @@ exports.createParallelTool = createParallelTool;
|
|
|
11008
11077
|
exports.createProvider = createProvider;
|
|
11009
11078
|
exports.createRegexGuardrail = createRegexGuardrail;
|
|
11010
11079
|
exports.createResolverNode = createResolverNode;
|
|
11080
|
+
exports.createSearchSkillsTool = createSearchSkillsTool;
|
|
11011
11081
|
exports.createSkillRegistryRef = createSkillRegistryRef;
|
|
11012
11082
|
exports.createSkillTools = createSkillTools;
|
|
11013
11083
|
exports.createSmartAgent = createSmartAgent;
|
|
@@ -11059,6 +11129,7 @@ exports.resolveUserQuestionState = resolveUserQuestionState;
|
|
|
11059
11129
|
exports.restoreSnapshot = restoreSnapshot;
|
|
11060
11130
|
exports.runSmartAgentEvalHarness = runSmartAgentEvalHarness;
|
|
11061
11131
|
exports.scoreItemsByRelevance = scoreItemsByRelevance;
|
|
11132
|
+
exports.searchSkills = searchSkills;
|
|
11062
11133
|
exports.seedChildMessages = seedChildMessages;
|
|
11063
11134
|
exports.selectTopIndicesInOrder = selectTopIndicesInOrder;
|
|
11064
11135
|
exports.setTokenCounter = setTokenCounter;
|