@cognipeer/agent-sdk 0.7.1 → 0.7.3

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/README.md CHANGED
@@ -36,6 +36,7 @@ Highlights:
36
36
  - **Planning mode** – adaptive system prompt + TODO tool supports full plan writes and version-safe partial updates.
37
37
  - **Unified reasoning surface** – one `reasoning` config controls provider-native reasoning and post-tool plain-text reflections.
38
38
  - **Structured output** – provide a Zod schema and the agent injects a finalize tool to capture JSON deterministically.
39
+ - **Skills / progressive disclosure** – expose cheap capability headers first, then bind skill tools on demand with `open_skill` and `bind_skill_tools`.
39
40
  - **Multi-agent and handoffs** – wrap agents as tools or transfer control mid-run with `asTool` / `asHandoff`.
40
41
  - **Human-in-the-loop** – `needsApproval` tools pause for review; `humanInTheLoop.askUser` enables a built-in `ask_user_question` tool that pauses with a structured multi-choice prompt and resumes from the user's answer.
41
42
  - **Usage + events** – normalize provider usage, surface `tool_call`, `tool_approval`, `user_question`, `plan`, `summarization`, `reflection`, `metadata`, and `handoff` events.
@@ -165,7 +166,33 @@ Tool-response retention is lazy and summarizer-driven:
165
166
  - `criticalTools` are never reduced. The built-in list covers `response`, `manage_todo_list`, and `get_tool_response`.
166
167
  - `maxToolResponseChars` / `maxToolResponseTokens` only drive an eager hard-cap truncation when a single tool output is big enough to blow up the very next model call. The truncated head always points at `get_tool_response` for recovery.
167
168
 
168
- The smart wrapper now supports runtime presets (`fast`, `balanced`, `deep`, `research`), custom profiles layered on top of a base preset, structured summarization, hybrid context compaction, configurable tool-response retention, in-memory fact storage, delegation limits, and an eval harness via `runSmartAgentEvalHarness(...)`.
169
+ The smart wrapper now supports runtime presets (`fast`, `balanced`, `deep`, `research`), custom profiles layered on top of a base preset, structured summarization, hybrid context compaction, skill-based progressive disclosure, configurable tool-response retention, in-memory fact storage, delegation limits, and an eval harness via `runSmartAgentEvalHarness(...)`.
170
+
171
+ For large or optional tool catalogs, pass `skills` instead of binding every tool directly:
172
+
173
+ ```ts
174
+ import { createSmartAgent, type Skill } from "@cognipeer/agent-sdk";
175
+
176
+ const pdfSkill: Skill = {
177
+ key: "builtin:pdf",
178
+ title: "PDF",
179
+ header: "read and summarize PDF files when the user references a PDF",
180
+ prompt: "Use pdf_read before pdf_summarize and preserve file ids in the answer.",
181
+ listToolIndex: () => [
182
+ { name: "pdf_read", description: "Extract PDF text by file id" },
183
+ { name: "pdf_summarize", description: "Summarize extracted PDF text" },
184
+ ],
185
+ bindTools: (names) => bindPdfTools(names),
186
+ };
187
+
188
+ const agent = createSmartAgent({
189
+ model,
190
+ skills: [pdfSkill],
191
+ skillPolicy: { maxOpenSkills: 2, maxBoundToolsPerSkill: 8, maxBoundToolsTotal: 24 },
192
+ });
193
+ ```
194
+
195
+ The model sees the skill header first. It calls `open_skill` to load the skill prompt and either bind a small skill immediately or get a tool index for `bind_skill_tools`.
169
196
 
170
197
  You can also define a custom profile by extending a built-in preset and overriding only the knobs you need:
171
198
 
package/dist/index.cjs CHANGED
@@ -3036,6 +3036,17 @@ function createToolsNode(initialTools, opts) {
3036
3036
  }
3037
3037
  const durationMs = Date.now() - start;
3038
3038
  const executionId = nanoid.nanoid();
3039
+ if (output && typeof output === "object" && Array.isArray(output.__runtimeToolsDelta)) {
3040
+ const delta = output.__runtimeToolsDelta;
3041
+ delete output.__runtimeToolsDelta;
3042
+ const currentRuntime = state.agent || runtime;
3043
+ const currentTools = currentRuntime?.tools ?? [];
3044
+ const present = new Set(currentTools.map((tool2) => tool2?.name));
3045
+ const additions = delta.filter((tool2) => tool2 && tool2.name && !present.has(tool2.name));
3046
+ if (additions.length > 0 && currentRuntime) {
3047
+ state.agent = { ...currentRuntime, tools: [...currentTools, ...additions] };
3048
+ }
3049
+ }
3039
3050
  if (output && typeof output === "object" && output.__handoff && output.__handoff.runtime) {
3040
3051
  toolHistory.push({ executionId, toolName, args, output: "handoff:ok", rawOutput: output, timestamp: (/* @__PURE__ */ new Date()).toISOString(), tool_call_id: tc.id, status: "handoff" });
3041
3052
  push({ role: "tool", content: "ok", tool_call_id: tc.id || `${tc.name}_${toolCount}`, name: tc.name });
@@ -6193,6 +6204,190 @@ async function writeSummaryFactsToMemory(store, config, summary, sourceTurn) {
6193
6204
  return store.get(config.memory.scope, { limit: config.context.lastTurnsToKeep + summary.stable_facts.length });
6194
6205
  }
6195
6206
 
6207
+ // src/smart/skills/types.ts
6208
+ var DEFAULT_SKILL_POLICY = {
6209
+ maxOpenSkills: 4,
6210
+ maxBoundToolsPerSkill: 12,
6211
+ maxBoundToolsTotal: 40
6212
+ };
6213
+ var SMALL_TIER_SKILL_POLICY = {
6214
+ maxOpenSkills: 1,
6215
+ maxBoundToolsPerSkill: 6,
6216
+ maxBoundToolsTotal: 18,
6217
+ modelTier: "small"
6218
+ };
6219
+ function createSkillRegistryRef() {
6220
+ return { openedSkillKeys: [], boundSkillTools: [] };
6221
+ }
6222
+
6223
+ // src/smart/skills/registry.ts
6224
+ function composeToolSets(input) {
6225
+ const without = [...input.base, ...input.boundSkillTools];
6226
+ const withRec = input.recoveryTool ? [...without, input.recoveryTool] : [...without];
6227
+ return { toolsWithoutRecovery: without, toolsWithRecovery: withRec };
6228
+ }
6229
+ function appendBoundTools(ref, newTools, policy) {
6230
+ const present = new Set(ref.boundSkillTools.map((tool) => tool.name));
6231
+ const added = [];
6232
+ for (const tool of newTools) {
6233
+ if (ref.boundSkillTools.length >= policy.maxBoundToolsTotal) break;
6234
+ if (present.has(tool.name)) continue;
6235
+ present.add(tool.name);
6236
+ ref.boundSkillTools.push(tool);
6237
+ added.push(tool);
6238
+ }
6239
+ return added;
6240
+ }
6241
+ function canOpenSkill(ref, policy) {
6242
+ if (ref.openedSkillKeys.length >= policy.maxOpenSkills) {
6243
+ return { ok: false, reason: `max ${policy.maxOpenSkills} skill(s) already open` };
6244
+ }
6245
+ if (ref.boundSkillTools.length >= policy.maxBoundToolsTotal) {
6246
+ return { ok: false, reason: "skill tool budget exhausted" };
6247
+ }
6248
+ return { ok: true };
6249
+ }
6250
+ async function resolveAvailableSkills(skills, opts = {}) {
6251
+ const out = [];
6252
+ for (const skill of skills) {
6253
+ if (skill.minModelTier === "large" && opts.modelTier === "small") continue;
6254
+ const available = skill.isAvailable ? await skill.isAvailable() : true;
6255
+ if (available) out.push(skill);
6256
+ }
6257
+ return out;
6258
+ }
6259
+ function buildSkillHeaderBlock(skills) {
6260
+ if (skills.length === 0) return "";
6261
+ const lines = skills.map((skill) => `- ${skill.key}: ${skill.header}`);
6262
+ return [
6263
+ "<available_skills>",
6264
+ "Open a skill with open_skill(skillKey) to load its tools on demand. Only open what the task needs; close nothing \u2014 opened skills stay available for the rest of the run.",
6265
+ ...lines,
6266
+ "</available_skills>"
6267
+ ].join("\n");
6268
+ }
6269
+ function dedupeToolsByName(tools) {
6270
+ const seen = /* @__PURE__ */ new Set();
6271
+ const out = [];
6272
+ for (const tool of tools) {
6273
+ if (seen.has(tool.name)) continue;
6274
+ seen.add(tool.name);
6275
+ out.push(tool);
6276
+ }
6277
+ return out;
6278
+ }
6279
+
6280
+ // src/smart/skills/skillTools.ts
6281
+ var MAX_RETURNED_INDEX = 40;
6282
+ var OPEN_SKILL_DESCRIPTION = "Load a capability on demand. Pass a skillKey from <available_skills>. 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.";
6283
+ 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.";
6284
+ function findSkill(deps, key) {
6285
+ return deps.skills.find((skill) => skill.key === key);
6286
+ }
6287
+ function createOpenSkillTool(deps) {
6288
+ const tool = createTool({
6289
+ name: "open_skill",
6290
+ description: OPEN_SKILL_DESCRIPTION,
6291
+ schema: zod.z.object({
6292
+ skillKey: zod.z.string().min(1).describe("A key from <available_skills>."),
6293
+ query: zod.z.string().optional().describe("What you need from the skill \u2014 used to rank a large skill's tools.")
6294
+ }).strict(),
6295
+ func: async ({ skillKey, query }) => {
6296
+ const { registryRef: ref, policy } = tool._deps;
6297
+ const skill = findSkill(tool._deps, skillKey);
6298
+ if (!skill) {
6299
+ return { error: `Unknown skill: ${skillKey}. Choose a key listed in <available_skills>.` };
6300
+ }
6301
+ if (skill.isAvailable && !await skill.isAvailable()) {
6302
+ return { error: `Skill ${skillKey} is not available in this workspace.` };
6303
+ }
6304
+ const alreadyOpen = ref.openedSkillKeys.includes(skillKey);
6305
+ if (!alreadyOpen) {
6306
+ const guard = canOpenSkill(ref, policy);
6307
+ if (!guard.ok) {
6308
+ return {
6309
+ error: `Cannot open ${skillKey}: ${guard.reason}. Work with the skills already open.`
6310
+ };
6311
+ }
6312
+ ref.openedSkillKeys.push(skillKey);
6313
+ }
6314
+ const prompt = typeof skill.prompt === "function" ? await skill.prompt() : skill.prompt;
6315
+ const index = await skill.listToolIndex();
6316
+ if (index.length <= policy.maxBoundToolsPerSkill) {
6317
+ const bound = await skill.bindTools();
6318
+ const added = appendBoundTools(ref, bound, policy);
6319
+ if (added.length > 0) ref.__onToolsChanged?.();
6320
+ return {
6321
+ skillKey,
6322
+ prompt,
6323
+ needsSandbox: Boolean(skill.needsSandbox),
6324
+ boundTools: added.map((t) => t.name),
6325
+ // Inject the bound tools into the live runtime for this loop.
6326
+ __runtimeToolsDelta: added
6327
+ };
6328
+ }
6329
+ let defaultBound = [];
6330
+ let defaultAdded = [];
6331
+ if ((!query || query.trim().length < 3) && skill.defaultBindNames?.length) {
6332
+ const bound = await skill.bindTools(skill.defaultBindNames.slice(0, policy.maxBoundToolsPerSkill));
6333
+ defaultAdded = appendBoundTools(ref, bound, policy);
6334
+ if (defaultAdded.length > 0) ref.__onToolsChanged?.();
6335
+ defaultBound = defaultAdded.map((t) => t.name);
6336
+ }
6337
+ const headers = query && query.trim().length >= 3 && skill.rankToolHeaders ? await skill.rankToolHeaders(query, index) : index;
6338
+ return {
6339
+ skillKey,
6340
+ prompt,
6341
+ needsSandbox: Boolean(skill.needsSandbox),
6342
+ boundTools: defaultBound,
6343
+ toolIndex: headers.slice(0, MAX_RETURNED_INDEX).map((h) => ({ name: h.name, description: h.description })),
6344
+ hint: "Call bind_skill_tools(skillKey, toolNames) with only the tools you need.",
6345
+ ...defaultAdded.length > 0 ? { __runtimeToolsDelta: defaultAdded } : {}
6346
+ };
6347
+ }
6348
+ });
6349
+ tool._deps = deps;
6350
+ tool.__source = "smart-skills";
6351
+ return tool;
6352
+ }
6353
+ function createBindSkillToolsTool(deps) {
6354
+ const tool = createTool({
6355
+ name: "bind_skill_tools",
6356
+ description: BIND_SKILL_TOOLS_DESCRIPTION,
6357
+ schema: zod.z.object({
6358
+ skillKey: zod.z.string().min(1),
6359
+ toolNames: zod.z.array(zod.z.string().min(1)).min(1).describe("Tool names from the skill's index.")
6360
+ }).strict(),
6361
+ func: async ({ skillKey, toolNames }) => {
6362
+ const { registryRef: ref, policy } = tool._deps;
6363
+ const skill = findSkill(tool._deps, skillKey);
6364
+ if (!skill) {
6365
+ return { error: `Unknown skill: ${skillKey}.` };
6366
+ }
6367
+ if (!ref.openedSkillKeys.includes(skillKey)) {
6368
+ return { error: `Call open_skill("${skillKey}") before binding its tools.` };
6369
+ }
6370
+ const capped = toolNames.slice(0, policy.maxBoundToolsPerSkill);
6371
+ const bound = await skill.bindTools(capped);
6372
+ const added = appendBoundTools(ref, bound, policy);
6373
+ if (added.length > 0) ref.__onToolsChanged?.();
6374
+ return {
6375
+ skillKey,
6376
+ boundTools: added.map((t) => t.name),
6377
+ requested: capped.length,
6378
+ truncated: toolNames.length > capped.length,
6379
+ ...added.length > 0 ? { __runtimeToolsDelta: added } : {}
6380
+ };
6381
+ }
6382
+ });
6383
+ tool._deps = deps;
6384
+ tool.__source = "smart-skills";
6385
+ return tool;
6386
+ }
6387
+ function createSkillTools(deps) {
6388
+ return [createOpenSkillTool(deps), createBindSkillToolsTool(deps)];
6389
+ }
6390
+
6196
6391
  // src/smart/index.ts
6197
6392
  function createSmartAgent(opts) {
6198
6393
  const resolved = normalizeSmartAgentOptions(opts);
@@ -6227,6 +6422,9 @@ function createSmartAgent(opts) {
6227
6422
  if (askUserConfig) {
6228
6423
  factoryToolsWithoutRecovery.push(createAskUserQuestionTool(factoryStateRef, askUserConfig));
6229
6424
  }
6425
+ const skills = opts.skills ?? [];
6426
+ const skillPolicy = opts.skillPolicy ?? DEFAULT_SKILL_POLICY;
6427
+ const skillsEnabled = skills.length > 0;
6230
6428
  const soManagerFactory = opts.outputSchema ? new StructuredOutputManager(opts.outputSchema, resolveStrategy(opts.model)) : void 0;
6231
6429
  const modelCapabilities = opts.outputSchema ? getModelCapabilities(opts.model) : void 0;
6232
6430
  const responseFinalizeTool = soManagerFactory && modelCapabilities?.structuredOutput !== "native" ? soManagerFactory.getResponseTool() : void 0;
@@ -6234,12 +6432,31 @@ function createSmartAgent(opts) {
6234
6432
  const ref = { toolHistory: void 0, toolHistoryArchived: void 0, todoList: void 0, planVersion: 0, adherenceScore: 0 };
6235
6433
  const ctxTools = createContextTools(ref, { planningEnabled, includeGetToolResponse: false });
6236
6434
  const recoveryTool = createGetToolResponseTool(ref);
6237
- const base2 = [...userTools, ...ctxTools];
6238
- if (responseFinalizeTool) base2.push(responseFinalizeTool);
6239
- if (askUserConfig) base2.push(createAskUserQuestionTool(ref, askUserConfig));
6240
- const without = base2;
6241
- const withRec = [...without, recoveryTool];
6242
- return { stateRef: ref, toolsWithoutRecovery: without, toolsWithRecovery: withRec };
6435
+ const coreBase = [...userTools, ...ctxTools];
6436
+ if (responseFinalizeTool) coreBase.push(responseFinalizeTool);
6437
+ if (askUserConfig) coreBase.push(createAskUserQuestionTool(ref, askUserConfig));
6438
+ if (!skillsEnabled) {
6439
+ const without = coreBase;
6440
+ const withRec = [...without, recoveryTool];
6441
+ return { stateRef: ref, toolsWithoutRecovery: without, toolsWithRecovery: withRec };
6442
+ }
6443
+ const toolSet = { stateRef: ref, toolsWithoutRecovery: [], toolsWithRecovery: [] };
6444
+ const skillRegistryRef = createSkillRegistryRef();
6445
+ const skillMetaTools = createSkillTools({ registryRef: skillRegistryRef, skills, policy: skillPolicy });
6446
+ const baseWithMeta = [...coreBase, ...skillMetaTools];
6447
+ const rebuild = () => {
6448
+ const composed = composeToolSets({
6449
+ base: baseWithMeta,
6450
+ boundSkillTools: skillRegistryRef.boundSkillTools,
6451
+ recoveryTool
6452
+ });
6453
+ toolSet.toolsWithoutRecovery = composed.toolsWithoutRecovery;
6454
+ toolSet.toolsWithRecovery = composed.toolsWithRecovery;
6455
+ };
6456
+ skillRegistryRef.__onToolsChanged = rebuild;
6457
+ toolSet.skillRegistryRef = skillRegistryRef;
6458
+ rebuild();
6459
+ return toolSet;
6243
6460
  };
6244
6461
  const base = createAgent({ ...runtimeOpts, tools: factoryToolsWithoutRecovery });
6245
6462
  base.__runtime.runtimeProfile = resolved.runtimeProfile;
@@ -6290,9 +6507,9 @@ function createSmartAgent(opts) {
6290
6507
  planVersion: ref.planVersion || state.planVersion || 1
6291
6508
  };
6292
6509
  }
6293
- function systemMessage2() {
6510
+ function systemMessage2(extraBlock) {
6294
6511
  const sys = buildSystemPrompt(
6295
- [opts.systemPrompt, runtimeHint, structuredOutputHint].filter(Boolean).join("\n"),
6512
+ [opts.systemPrompt, runtimeHint, structuredOutputHint, extraBlock].filter(Boolean).join("\n"),
6296
6513
  planningEnabled,
6297
6514
  opts.name || "Agent",
6298
6515
  opts.todoListPrompt
@@ -6342,8 +6559,10 @@ function createSmartAgent(opts) {
6342
6559
  stateRef.planVersion = input.planVersion || input.plan?.version || 0;
6343
6560
  stateRef.adherenceScore = input.plan?.adherenceScore || 0;
6344
6561
  const syncPlanFromRef = (state2) => syncPlanStateWith(stateRef, state2);
6562
+ const availableSkills = skillsEnabled ? await resolveAvailableSkills(skills, { modelTier: skillPolicy.modelTier }) : [];
6563
+ const skillBlock = availableSkills.length > 0 ? buildSkillHeaderBlock(availableSkills) : void 0;
6345
6564
  const alreadyHasSystem = Array.isArray(input.messages) && input.messages[0]?.role === "system";
6346
- const seedMessages = alreadyHasSystem ? [...input.messages || []] : [systemMessage2(), ...input.messages || []];
6565
+ const seedMessages = alreadyHasSystem ? [...input.messages || []] : [systemMessage2(skillBlock), ...input.messages || []];
6347
6566
  let state = syncRuntimeTools(await syncMemory({ ...input, messages: seedMessages }), seedMessages, toolSet);
6348
6567
  let lastResult = null;
6349
6568
  let rawMessages = [...seedMessages];
@@ -7609,7 +7828,7 @@ var AnthropicProvider = class extends BaseProvider {
7609
7828
  const { system, messages } = this.splitSystemMessages(request.messages);
7610
7829
  const body = {
7611
7830
  model: request.model || this.defaultModel,
7612
- messages: messages.map((m) => this.toAnthropicMessage(m)),
7831
+ messages: this.toAnthropicMessages(messages),
7613
7832
  max_tokens: request.maxTokens ?? 4096,
7614
7833
  stream
7615
7834
  };
@@ -7665,20 +7884,44 @@ var AnthropicProvider = class extends BaseProvider {
7665
7884
  messages: rest
7666
7885
  };
7667
7886
  }
7668
- toAnthropicMessage(m) {
7669
- if (m.role === "tool" && m.toolCallId) {
7670
- const content = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
7671
- return {
7672
- role: "user",
7673
- content: [
7674
- {
7675
- type: "tool_result",
7676
- tool_use_id: m.toolCallId,
7677
- content
7678
- }
7679
- ]
7680
- };
7887
+ /**
7888
+ * Converts unified messages to Anthropic format, coalescing consecutive
7889
+ * tool-result messages into a single `user` turn.
7890
+ *
7891
+ * The unified message list carries one `role: "tool"` entry per tool call
7892
+ * (mirroring OpenAI's shape). Anthropic's Messages API expects every
7893
+ * `tool_result` block answering a single assistant turn's `tool_use`
7894
+ * block(s) to be batched into ONE `user` message rather than sent as
7895
+ * separate consecutive `user` messages.
7896
+ */
7897
+ toAnthropicMessages(messages) {
7898
+ const result = [];
7899
+ let mergingToolResults = false;
7900
+ for (const m of messages) {
7901
+ if (m.role === "tool" && m.toolCallId) {
7902
+ const toolResult = this.toAnthropicToolResult(m);
7903
+ if (mergingToolResults) {
7904
+ result[result.length - 1].content.push(toolResult);
7905
+ } else {
7906
+ result.push({ role: "user", content: [toolResult] });
7907
+ mergingToolResults = true;
7908
+ }
7909
+ continue;
7910
+ }
7911
+ mergingToolResults = false;
7912
+ result.push(this.toAnthropicMessage(m));
7681
7913
  }
7914
+ return result;
7915
+ }
7916
+ toAnthropicToolResult(m) {
7917
+ const content = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
7918
+ return {
7919
+ type: "tool_result",
7920
+ tool_use_id: m.toolCallId,
7921
+ content
7922
+ };
7923
+ }
7924
+ toAnthropicMessage(m) {
7682
7925
  if (m.role === "assistant" && m.toolCalls?.length) {
7683
7926
  const content = [];
7684
7927
  appendReasoningBlocks(content, m.reasoning?.blocks);
@@ -8063,7 +8306,7 @@ var BedrockProvider = class extends BaseProvider {
8063
8306
  buildConverseBody(request) {
8064
8307
  const { system, messages } = this.splitSystemMessages(request.messages);
8065
8308
  const body = {
8066
- messages: messages.map((m) => this.toBedrockMessage(m))
8309
+ messages: this.toBedrockMessages(messages)
8067
8310
  };
8068
8311
  if (system.length > 0) {
8069
8312
  const systemBlocks = system.map((s) => ({ text: s }));
@@ -8113,22 +8356,47 @@ var BedrockProvider = class extends BaseProvider {
8113
8356
  }
8114
8357
  return { system, messages: rest };
8115
8358
  }
8116
- toBedrockMessage(m) {
8117
- if (m.role === "tool" && m.toolCallId) {
8118
- const text = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
8119
- return {
8120
- role: "user",
8121
- content: [
8122
- {
8123
- toolResult: {
8124
- toolUseId: m.toolCallId,
8125
- content: [{ text }],
8126
- status: "success"
8127
- }
8128
- }
8129
- ]
8130
- };
8359
+ /**
8360
+ * Converts unified messages to Bedrock Converse format, coalescing
8361
+ * consecutive tool-result messages into a single `user` turn.
8362
+ *
8363
+ * The unified message list carries one `role: "tool"` entry per tool call
8364
+ * (mirroring OpenAI's shape). Bedrock's Converse API requires every
8365
+ * `toolResult` block answering a single assistant turn's `toolUse`
8366
+ * block(s) to be batched into ONE `user` message — sending them as
8367
+ * separate consecutive `user` messages triggers: "Expected toolResult
8368
+ * blocks at messages.N.content for the following Ids: ...".
8369
+ */
8370
+ toBedrockMessages(messages) {
8371
+ const result = [];
8372
+ let mergingToolResults = false;
8373
+ for (const m of messages) {
8374
+ if (m.role === "tool" && m.toolCallId) {
8375
+ const toolResult = this.toBedrockToolResult(m);
8376
+ if (mergingToolResults) {
8377
+ result[result.length - 1].content.push(toolResult);
8378
+ } else {
8379
+ result.push({ role: "user", content: [toolResult] });
8380
+ mergingToolResults = true;
8381
+ }
8382
+ continue;
8383
+ }
8384
+ mergingToolResults = false;
8385
+ result.push(this.toBedrockMessage(m));
8131
8386
  }
8387
+ return result;
8388
+ }
8389
+ toBedrockToolResult(m) {
8390
+ const text = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
8391
+ return {
8392
+ toolResult: {
8393
+ toolUseId: m.toolCallId,
8394
+ content: [{ text }],
8395
+ status: "success"
8396
+ }
8397
+ };
8398
+ }
8399
+ toBedrockMessage(m) {
8132
8400
  if (m.role === "assistant" && m.toolCalls?.length) {
8133
8401
  const content2 = [];
8134
8402
  appendBedrockReasoning(content2, m.reasoning?.blocks);
@@ -8434,12 +8702,24 @@ var VertexProvider = class extends BaseProvider {
8434
8702
  buildContents(messages) {
8435
8703
  const systemParts = [];
8436
8704
  const contents = [];
8705
+ let mergingToolResults = false;
8437
8706
  for (const m of messages) {
8438
8707
  if (m.role === "system") {
8439
8708
  const text = typeof m.content === "string" ? m.content : m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
8440
8709
  if (text) systemParts.push(text);
8441
8710
  continue;
8442
8711
  }
8712
+ if (m.role === "tool" && m.toolCallId) {
8713
+ const part = this.toGeminiFunctionResponsePart(m);
8714
+ if (mergingToolResults) {
8715
+ contents[contents.length - 1].parts.push(part);
8716
+ } else {
8717
+ contents.push({ role: "user", parts: [part] });
8718
+ mergingToolResults = true;
8719
+ }
8720
+ continue;
8721
+ }
8722
+ mergingToolResults = false;
8443
8723
  contents.push(this.toGeminiContent(m));
8444
8724
  }
8445
8725
  return {
@@ -8447,27 +8727,22 @@ var VertexProvider = class extends BaseProvider {
8447
8727
  contents
8448
8728
  };
8449
8729
  }
8450
- toGeminiContent(m) {
8451
- if (m.role === "tool" && m.toolCallId) {
8452
- const text = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
8453
- let response;
8454
- try {
8455
- response = JSON.parse(text);
8456
- } catch {
8457
- response = { result: text };
8458
- }
8459
- return {
8460
- role: "user",
8461
- parts: [
8462
- {
8463
- functionResponse: {
8464
- name: m.name ?? m.toolCallId,
8465
- response
8466
- }
8467
- }
8468
- ]
8469
- };
8730
+ toGeminiFunctionResponsePart(m) {
8731
+ const text = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
8732
+ let response;
8733
+ try {
8734
+ response = JSON.parse(text);
8735
+ } catch {
8736
+ response = { result: text };
8470
8737
  }
8738
+ return {
8739
+ functionResponse: {
8740
+ name: m.name ?? m.toolCallId,
8741
+ response
8742
+ }
8743
+ };
8744
+ }
8745
+ toGeminiContent(m) {
8471
8746
  if (m.role === "assistant" && m.toolCalls?.length) {
8472
8747
  const parts2 = [];
8473
8748
  if (typeof m.content === "string" && m.content) {
@@ -9129,25 +9404,32 @@ exports.AzureProvider = AzureProvider;
9129
9404
  exports.BaseProvider = BaseProvider;
9130
9405
  exports.BedrockProvider = BedrockProvider;
9131
9406
  exports.DEFAULT_PROFILE_CONFIGS = DEFAULT_PROFILE_CONFIGS;
9407
+ exports.DEFAULT_SKILL_POLICY = DEFAULT_SKILL_POLICY;
9132
9408
  exports.GuardrailPhase = GuardrailPhase;
9133
9409
  exports.InMemoryMemoryStore = InMemoryMemoryStore;
9134
9410
  exports.NativeJsonSchemaStrategy = NativeJsonSchemaStrategy;
9135
9411
  exports.OpenAICompatibleProvider = OpenAICompatibleProvider;
9136
9412
  exports.OpenAIProvider = OpenAIProvider;
9137
9413
  exports.ProviderError = ProviderError;
9414
+ exports.SMALL_TIER_SKILL_POLICY = SMALL_TIER_SKILL_POLICY;
9138
9415
  exports.StructuredOutputManager = StructuredOutputManager;
9139
9416
  exports.ToolBasedStrategy = ToolBasedStrategy;
9140
9417
  exports.VertexProvider = VertexProvider;
9141
9418
  exports.agentVerdictRule = agentVerdictRule;
9419
+ exports.appendBoundTools = appendBoundTools;
9420
+ exports.buildSkillHeaderBlock = buildSkillHeaderBlock;
9142
9421
  exports.buildSystemPrompt = buildSystemPrompt;
9422
+ exports.canOpenSkill = canOpenSkill;
9143
9423
  exports.captureSnapshot = captureSnapshot;
9144
9424
  exports.codePresenceRule = codePresenceRule;
9145
9425
  exports.cognipeerSink = cognipeerSink;
9426
+ exports.composeToolSets = composeToolSets;
9146
9427
  exports.countApproxTokens = countApproxTokens;
9147
9428
  exports.countMessagesTokens = countMessagesTokens;
9148
9429
  exports.createAgent = createAgent;
9149
9430
  exports.createAgentNode = createAgentNode;
9150
9431
  exports.createAskUserQuestionTool = createAskUserQuestionTool;
9432
+ exports.createBindSkillToolsTool = createBindSkillToolsTool;
9151
9433
  exports.createCodeGuardrail = createCodeGuardrail;
9152
9434
  exports.createContextSummarizeNode = createContextSummarizeNode;
9153
9435
  exports.createContextTools = createContextTools;
@@ -9155,15 +9437,19 @@ exports.createGetToolResponseTool = createGetToolResponseTool;
9155
9437
  exports.createGuardrail = createGuardrail;
9156
9438
  exports.createJsonGuardrail = createJsonGuardrail;
9157
9439
  exports.createManageTodoTool = createManageTodoTool;
9440
+ exports.createOpenSkillTool = createOpenSkillTool;
9158
9441
  exports.createProvider = createProvider;
9159
9442
  exports.createRegexGuardrail = createRegexGuardrail;
9160
9443
  exports.createResolverNode = createResolverNode;
9444
+ exports.createSkillRegistryRef = createSkillRegistryRef;
9445
+ exports.createSkillTools = createSkillTools;
9161
9446
  exports.createSmartAgent = createSmartAgent;
9162
9447
  exports.createTool = createTool;
9163
9448
  exports.createToolLimitFinalizeNode = createToolLimitFinalizeNode;
9164
9449
  exports.createToolsNode = createToolsNode;
9165
9450
  exports.customCallbackRule = customCallbackRule;
9166
9451
  exports.customSink = customSink;
9452
+ exports.dedupeToolsByName = dedupeToolsByName;
9167
9453
  exports.defaultTokenCounter = defaultTokenCounter;
9168
9454
  exports.emptyUsage = emptyUsage;
9169
9455
  exports.evaluateGuardrails = evaluateGuardrails;
@@ -9186,6 +9472,7 @@ exports.normalizeSmartAgentOptions = normalizeSmartAgentOptions;
9186
9472
  exports.otlpSink = otlpSink;
9187
9473
  exports.readMemoryFacts = readMemoryFacts;
9188
9474
  exports.regexRule = regexRule;
9475
+ exports.resolveAvailableSkills = resolveAvailableSkills;
9189
9476
  exports.resolveMemoryStore = resolveMemoryStore;
9190
9477
  exports.resolveReasoning = resolveReasoning;
9191
9478
  exports.resolveStrategy = resolveStrategy;