@evolutese/sdk
v1.0.0
Published
Node.js SDK for building agent-powered backends with Evolutese — Express, Next.js, streaming, and agent catalog
Readme
@evolutese/sdk
Node.js SDK for building agent-powered backends with Evolutese. Integrates with Express and Next.js — handles routing, LLM calls, streaming, and agent catalog out of the box.
Installation
npm install @evolutese/sdkQuick start
import { EvoluteseClient } from '@evolutese/sdk';
const client = new EvoluteseClient({
provider: 'google', // 'openai' | 'anthropic' | 'google' | 'ollama' | 'openrouter'
model: 'gemini-2.5-flash',
apiKey: process.env.LLM_API_KEY,
});
await client.init(); // loads agents from ./agents/ and bootstraps the runtime
// Call an intent directly
const result = await client.execute({
tenant_id: 'acme',
intent: 'invoice.draft_invoice',
values: { customer: 'Alice', amount: 200 },
});
// Or let the LLM route from free text
const result = await client.execute({
tenant_id: 'acme',
text: 'Create an invoice for Alice for 200 EUR',
});Express
import express from 'express';
import { EvoluteseClient, createExpressHandler, createExpressRestHandler, createCatalogExpressHandler } from '@evolutese/sdk';
const client = new EvoluteseClient({ provider: 'openai', model: 'gpt-4o', apiKey: process.env.OPENAI_API_KEY });
async function bootstrap() {
await client.init();
const app = express();
app.use(express.json());
app.post('/api/assistant', createExpressHandler(client)); // SSE streaming
app.post('/api/assistant/sync', createExpressRestHandler(client)); // REST JSON
app.get('/api/agents', createCatalogExpressHandler()); // agent catalog
app.listen(4000);
}
bootstrap();Next.js App Router
// app/api/assistant/route.ts
import { EvoluteseClient, createNextRoute } from '@evolutese/sdk';
const client = new EvoluteseClient({ provider: 'openai', model: 'gpt-4o', apiKey: process.env.OPENAI_API_KEY });
await client.init();
export const POST = createNextRoute(client); // SSE via Web Streams
// export const POST = createNextRestRoute(client); // REST JSONThread management
Free-text responses include a threadId in the result. Pass it back to continue the same conversation, or call clearThread to reset it:
const result = await client.execute({ tenant_id: 'acme', text: 'List all tasks' });
// result.threadId — persist this to continue the conversation
// Continue a thread
const next = await client.execute({
tenant_id: 'acme',
text: 'Mark the first one as done',
threadId: result.threadId,
});
// Reset a thread
await client.clearThread(result.threadId);Streaming
await client.stream(
{ tenant_id: 'acme', text: 'List all customers' },
(event) => {
console.log(event.type, event.data);
}
);Environment variables
provider, model, and apiKey can be omitted from the constructor and set via env vars instead:
| Variable | Purpose |
|----------|---------|
| LLM_PROVIDER | Provider id (openai, google, anthropic, ollama, openrouter) |
| LLM_API_KEY | API key for the configured provider |
| LLM_MODEL | Model name |
Constructor options take precedence over env vars.
Agent loading
By default agents are loaded from <cwd>/agents/. Override with agentsDir:
const client = new EvoluteseClient({
agentsDir: path.join(__dirname, '../agents'),
// ...
});Pass inline definitions to skip the filesystem entirely (required for Cloudflare Workers and other edge runtimes):
import accountingYaml from './agents/accounting.yml?raw'; // bundler raw import
const client = new EvoluteseClient({
agents: [accountingYaml], // YAML strings
// agents: [{ id: 'accounting', ... }], // or parsed AgentDefinition objects
// ...
});When agents is provided, agentsDir is ignored.
Connectors
Register connectors at init to wire agents to real infrastructure:
import { buildMongoConnectorFromConfig } from '@evolutese/connectors';
const client = new EvoluteseClient({
provider: 'openai',
model: 'gpt-4o',
apiKey: process.env.LLM_API_KEY,
connectors: {
mongo: await buildMongoConnectorFromConfig({
connectionString: process.env.MONGO_URI,
dbName: 'myapp',
}),
},
});
await client.init();Programmatic agents (no YAML)
import { EvoluteseClient, defineAgent } from '@evolutese/sdk';
const def = defineAgent('greeter')
.name('Greeter')
.action({ id: 'send', connector: 'mail', params: { to: '{{email}}', subject: 'Hi!', body: '{{body}}' } })
.intent({ name: 'greet', type: 'workflow', steps: [{ id: 's1', action: 'send' }] })
.build();
// One-shot — registered and removed automatically
const result = await client.runAgent(def, 'greet', { email: '[email protected]', body: 'Hello!' });
// Persistent — stays in registry for the process lifetime
client.registerAgent(def);
await client.execute({ tenant_id: 'default', intent: 'greeter.greet', values: { email: '[email protected]', body: 'Hello!' } });Local models (Ollama)
const client = new EvoluteseClient({ provider: 'ollama', model: 'gemma3' });
await client.init(); // no API key requiredLicense
MIT
