Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 1x | /**
* AgentKits — Agent Loop
*
* Autonomous agent with tool calling, memory, and multi-step reasoning.
*
* Usage:
* import { createAgent } from 'agentkits/agent';
* import { defineTool } from 'agentkits';
* const agent = createAgent({
* provider: 'gemini', apiKey: '...',
* tools: [searchTool, calcTool],
* });
* const result = await agent.run('Find the weather in Beijing');
*/
import { createToolChat, defineTool, type ToolChatConfig, type ToolDefinition } from '../tools/index.js';
import type { ChatMessage } from '../llm/index.js';
// ── Types ──────────────────────────────────────────────────────────
export interface AgentConfig extends Omit<ToolChatConfig, 'tools'> {
tools?: ToolDefinition[];
/** System prompt */
system?: string;
/** Memory: persist messages across runs */
memory?: boolean;
/** Callback for each step */
onStep?: (step: AgentStep) => void;
}
export interface AgentStep {
index: number;
type: 'tool_call' | 'tool_result' | 'answer';
content: string;
toolName?: string;
timestamp: number;
}
export interface AgentResult {
answer: string;
steps: AgentStep[];
toolCalls: number;
rounds: number;
}
export interface AgentClient {
/** Run agent with a task */
run(task: string): Promise<AgentResult>;
/** Get conversation history */
readonly history: ChatMessage[];
/** Clear memory */
reset(): void;
/** Current config */
readonly config: Readonly<AgentConfig>;
}
// ── Main ──────────────────────────────────────────────────────────
export function createAgent(config: AgentConfig): AgentClient {
const {
tools = [],
system,
memory = false,
onStep,
...toolChatConfig
} = config;
let conversationHistory: ChatMessage[] = [];
const defaultSystem = system ?? `You are a helpful AI assistant with access to tools.
Think step by step. Use tools when needed. Provide a clear final answer.`;
const client: AgentClient = {
async run(task) {
const toolChat = createToolChat({
...toolChatConfig,
tools,
});
const response = await toolChat.run(task, { system: defaultSystem });
const steps: AgentStep[] = [];
let stepIdx = 0;
// Log tool calls
for (const tc of response.toolCalls) {
const step: AgentStep = {
index: stepIdx++,
type: 'tool_call',
content: `${tc.name}(${JSON.stringify(tc.arguments)})`,
toolName: tc.name,
timestamp: Date.now(),
};
steps.push(step);
onStep?.(step);
}
// Log tool results
for (const tr of response.toolResults) {
const step: AgentStep = {
index: stepIdx++,
type: 'tool_result',
content: tr.result,
toolName: tr.toolCallId,
timestamp: Date.now(),
};
steps.push(step);
onStep?.(step);
}
// Final answer
const answerStep: AgentStep = {
index: stepIdx++,
type: 'answer',
content: response.content,
timestamp: Date.now(),
};
steps.push(answerStep);
onStep?.(answerStep);
if (memory) {
conversationHistory.push(
{ role: 'user', content: task },
{ role: 'assistant', content: response.content },
);
}
return {
answer: response.content,
steps,
toolCalls: response.toolCalls.length,
rounds: response.rounds,
};
},
get history() { return [...conversationHistory]; },
reset() { conversationHistory = []; },
get config() { return config; },
};
return client;
}
export { defineTool } from '../tools/index.js';
export type { ToolDefinition } from '../tools/index.js';
|