> cohere-core-workflow-b
Build tool-use agents and function calling with Cohere API v2. Use when implementing multi-step agents, function calling, or building autonomous tool-using workflows with Cohere. Trigger with phrases like "cohere tool use", "cohere agents", "cohere function calling", "cohere multi-step".
curl "https://skillshub.wtf/jeremylongshore/claude-code-plugins-plus-skills/cohere-core-workflow-b?format=md"Cohere Tool Use & Agents (Core Workflow B)
Overview
Build multi-step tool-using agents with Cohere's Chat API v2. The model decides which tools to call, you execute them, and feed results back in a loop until the task is complete.
Prerequisites
- Completed
cohere-install-authsetup - Understanding of
cohere-core-workflow-a(RAG) - Command R7B or newer model (required for tool use)
Instructions
Step 1: Define Tools
import { CohereClientV2 } from 'cohere-ai';
const cohere = new CohereClientV2();
// Define tools the model can call
const tools = [
{
type: 'function' as const,
function: {
name: 'get_weather',
description: 'Get current weather for a city',
parameters: {
type: 'object' as const,
properties: {
city: { type: 'string', description: 'City name' },
unit: { type: 'string', enum: ['celsius', 'fahrenheit'], description: 'Temperature unit' },
},
required: ['city'],
},
},
},
{
type: 'function' as const,
function: {
name: 'search_database',
description: 'Search internal database for records',
parameters: {
type: 'object' as const,
properties: {
query: { type: 'string', description: 'Search query' },
limit: { type: 'number', description: 'Max results' },
},
required: ['query'],
},
},
},
];
Step 2: Implement Tool Executors
// Map tool names to actual implementations
const toolExecutors: Record<string, (args: any) => Promise<string>> = {
get_weather: async ({ city, unit = 'celsius' }) => {
// Replace with real weather API call
return JSON.stringify({
city,
temperature: unit === 'celsius' ? 22 : 72,
unit,
condition: 'partly cloudy',
});
},
search_database: async ({ query, limit = 5 }) => {
// Replace with real database query
return JSON.stringify({
results: [
{ id: 1, title: `Result for: ${query}`, relevance: 0.95 },
],
total: 1,
});
},
};
Step 3: Single-Step Tool Use
async function singleStepToolUse(userMessage: string) {
// 1. Send message with tools
const response = await cohere.chat({
model: 'command-a-03-2025',
messages: [{ role: 'user', content: userMessage }],
tools,
});
// 2. Check if model wants to call tools
if (response.finishReason === 'TOOL_CALL') {
const toolCalls = response.message?.toolCalls ?? [];
// 3. Execute each tool call
const toolResults = await Promise.all(
toolCalls.map(async (tc) => {
const executor = toolExecutors[tc.function.name];
const args = JSON.parse(tc.function.arguments);
const result = await executor(args);
return {
call: tc,
outputs: [{ result }],
};
})
);
// 4. Send tool results back for final answer
const finalResponse = await cohere.chat({
model: 'command-a-03-2025',
messages: [
{ role: 'user', content: userMessage },
{ role: 'assistant', toolCalls },
{ role: 'tool', toolCallId: toolCalls[0].id, content: toolResults[0].outputs[0].result },
],
tools,
});
return finalResponse.message?.content?.[0]?.text ?? '';
}
// No tool call — direct response
return response.message?.content?.[0]?.text ?? '';
}
Step 4: Multi-Step Agent Loop
async function agentLoop(userMessage: string, maxSteps = 5) {
const messages: any[] = [{ role: 'user', content: userMessage }];
for (let step = 0; step < maxSteps; step++) {
const response = await cohere.chat({
model: 'command-a-03-2025',
messages,
tools,
});
// If model is done (no tool calls), return the answer
if (response.finishReason !== 'TOOL_CALL') {
return response.message?.content?.[0]?.text ?? '';
}
// Model wants to call tools
const toolCalls = response.message?.toolCalls ?? [];
messages.push({ role: 'assistant', toolCalls });
// Execute tools (parallel if multiple)
for (const tc of toolCalls) {
const executor = toolExecutors[tc.function.name];
if (!executor) {
messages.push({ role: 'tool', toolCallId: tc.id, content: `Error: Unknown tool ${tc.function.name}` });
continue;
}
try {
const args = JSON.parse(tc.function.arguments);
const result = await executor(args);
messages.push({ role: 'tool', toolCallId: tc.id, content: result });
} catch (err) {
messages.push({ role: 'tool', toolCallId: tc.id, content: `Error: ${(err as Error).message}` });
}
}
console.log(`Step ${step + 1}: executed ${toolCalls.length} tool(s)`);
}
return 'Agent reached max steps without completing.';
}
// Usage
const answer = await agentLoop("What's the weather in Tokyo and search for 'Tokyo events'?");
console.log(answer);
Step 5: Force Tool Use
// Force the model to use at least one tool
const response = await cohere.chat({
model: 'command-a-03-2025',
messages: [{ role: 'user', content: 'Look up the weather in Paris' }],
tools,
toolChoice: 'REQUIRED', // REQUIRED = must use tool, NONE = cannot use tools
});
// toolChoice options:
// - omitted: model decides freely
// - 'REQUIRED': must call at least one tool
// - 'NONE': cannot call any tools (text-only response)
Step 6: Streaming Tool Use
async function streamWithTools(userMessage: string) {
const stream = await cohere.chatStream({
model: 'command-a-03-2025',
messages: [{ role: 'user', content: userMessage }],
tools,
});
const toolCalls: any[] = [];
for await (const event of stream) {
switch (event.type) {
case 'tool-call-start':
console.log(`Tool call: ${event.delta?.message?.toolCalls?.function?.name}`);
break;
case 'tool-call-delta':
// Streaming tool arguments
break;
case 'content-delta':
process.stdout.write(event.delta?.message?.content?.text ?? '');
break;
}
}
}
Output
- Single-step tool calls with automatic execution
- Multi-step agent loop handling sequential reasoning
- Parallel tool execution for independent calls
- Streaming with tool-call events
Error Handling
| Error | Cause | Solution |
|---|---|---|
tool not found | Mismatched tool name | Verify tools array matches executors |
invalid arguments | Schema mismatch | Check tool parameter types |
| Infinite loop | Model keeps calling tools | Set maxSteps limit |
TOOL_CALL with no toolCalls | Edge case | Check response.message?.toolCalls length |
Resources
Next Steps
For common errors, see cohere-common-errors.
> related_skills --same-repo
> fathom-cost-tuning
Optimize Fathom API usage and plan selection. Trigger with phrases like "fathom cost", "fathom pricing", "fathom plan".
> fathom-core-workflow-b
Sync Fathom meeting data to CRM and build automated follow-up workflows. Use when integrating Fathom with Salesforce, HubSpot, or custom CRMs, or creating automated post-meeting email summaries. Trigger with phrases like "fathom crm sync", "fathom salesforce", "fathom follow-up", "fathom post-meeting workflow".
> fathom-core-workflow-a
Build a meeting analytics pipeline with Fathom transcripts and summaries. Use when extracting insights from meetings, building CRM sync, or creating automated meeting follow-up workflows. Trigger with phrases like "fathom analytics", "fathom meeting pipeline", "fathom transcript analysis", "fathom action items sync".
> fathom-common-errors
Diagnose and fix Fathom API errors including auth failures and missing data. Use when API calls fail, transcripts are empty, or webhooks are not firing. Trigger with phrases like "fathom error", "fathom not working", "fathom api failure", "fix fathom".