/**
* Agent module for LLM orchestration.
*
* This module handles:
* - LLM API calls (Anthropic, OpenAI)
* - Multi-step agent workflows
* - Tool execution within Logseq
*/
export interface AgentConfig {
provider: "anthropic" | "openai";
apiKey: string;
model: string;
}
export interface Message {
role: "user" | "assistant";
content: string;
}
/**
* Simple agent for single-turn LLM interactions.
* Extend this for multi-step agentic workflows.
*/
export class Agent {
private config: AgentConfig;
constructor(config: AgentConfig) {
this.config = config;
}
/**
* Send a message to the LLM and get a response.
*/
async chat(messages: Message[]): Promise<string> {
if (this.config.provider === "anthropic") {
return this.callAnthropic(messages);
} else {
return this.callOpenAI(messages);
}
}
private async callAnthropic(messages: Message[]): Promise<string> {
const response = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": this.config.apiKey,
"anthropic-version": "2023-06-01",
},
body: JSON.stringify({
model: this.config.model,
max_tokens: 4096,
messages: messages.map((m) => ({
role: m.role,
content: m.content,
})),
}),
});
if (!response.ok) {
throw new Error(`Anthropic API error: ${response.status}`);
}
const data = await response.json();
return data.content[0]?.text ?? "";
}
private async callOpenAI(messages: Message[]): Promise<string> {
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.config.apiKey}`,
},
body: JSON.stringify({
model: this.config.model,
messages: messages.map((m) => ({
role: m.role,
content: m.content,
})),
}),
});
if (!response.ok) {
throw new Error(`OpenAI API error: ${response.status}`);
}
const data = await response.json();
return data.choices[0]?.message?.content ?? "";
}
/**
* Summarize text content.
*/
async summarize(content: string): Promise<string> {
return this.chat([
{
role: "user",
content: `Please provide a concise summary of the following content:\n\n${content}`,
},
]);
}
/**
* Expand/elaborate on text content.
*/
async expand(content: string): Promise<string> {
return this.chat([
{
role: "user",
content: `Please expand on the following content with more details and examples:\n\n${content}`,
},
]);
}
/**
* Answer a question about content.
*/
async ask(question: string, context: string): Promise<string> {
return this.chat([
{
role: "user",
content: `Based on the following context, please answer the question.\n\nContext:\n${context}\n\nQuestion: ${question}`,
},
]);
}
}