Agent SDK · Tools and sessions

Session.

Stateful multi-turn conversations with a session object.

A Session wraps an Agent with auto-managed conversationId and accumulates turn results. The server maintains conversation history server-side using the conversationId, so each turn has full context.

createSession(agent, options?)

TypeScript
import { createSession } from '@maincode-ai/matilda-agent-sdk';

const session = createSession({
  name: 'tutor',
  instructions: 'You are a patient programming tutor. Explain concepts simply.',
});

console.log('Conversation ID:', session.conversationId);

// Turn 1
const r1 = await session.run('What is a closure in JavaScript?');
console.log('Turn 1:', r1.finalOutput.slice(0, 100), '...');

// Turn 2 — the server remembers the previous exchange via conversationId
const r2 = await session.run('Can you show me a simple example?');
console.log('Turn 2:', r2.finalOutput.slice(0, 100), '...');

// The session accumulates all turn results
console.log('Total turns:', session.turns.length);
console.log('Last turn stream ID:', session.lastTurn?.streamId);

Session class

session.run(input, options?)

Runs a turn and accumulates the result in session.turns.

Fieldtypedescription
inputstringThe user's message.
optionsOmit<AgentRunOptions, 'conversationId'>Per-turn options. Merged with session defaults.

Returns Promise<AgentRunResult>.

session.stream(input, options?)

Streams a turn, yielding AgentRunEvent as they arrive. The result is accumulated in session.turns when the stream completes.

TypeScript
for await (const event of session.stream('Explain async/await in one paragraph.')) {
  if (event.type === 'message.delta') {
    process.stdout.write(event.delta);
  }
}

console.log('\n[Turns accumulated]:', session.turns.length);
console.log('[Final output cached]:', session.lastTurn?.finalOutput.slice(0, 60), '...');

session.conversationId

The auto-generated (or provided) conversation ID. Reused across all turns.

session.turns

A readonly array of AgentRunResult — one per completed turn.

session.lastTurn

Getter for the most recent AgentRunResult, or undefined if no turns have run.

SessionOptions

Extends Omit<AgentRunOptions, 'conversationId'>.

Fieldtypedescription
runnerRunnerCustom runner instance. Defaults to defaultRunner.
conversationIdstringExplicit conversation ID. Auto-generated when omitted.
(all AgentRunOptions fields)Session-level defaults applied to every turn.

Metadata passthrough

Metadata can be set at multiple levels: Agent construction, Session construction, or per-call. Per-call metadata merges with (and overrides) session defaults.

TypeScript
const session = createSession(
  {
    name: 'helper',
    instructions: ({ metadata }) =>
      `Environment: ${metadata.env ?? 'unknown'}. User: ${metadata.user ?? 'anonymous'}.`,
  },
  { metadata: { env: 'staging', user: 'demo-user' } },
);

// Session-level metadata is used by default
await session.run('Who am I?');

// Per-call metadata overrides session defaults
await session.run('Who am I now?', { metadata: { user: 'admin' } });
// → env=staging (from session), user=admin (overridden per-call)

Custom runner

A Session can use a custom Runner for dependency injection in tests or isolated configuration:

TypeScript
import { Runner, Session } from '@maincode-ai/matilda-agent-sdk';

const myRunner = new Runner();
const session = new Session(
  { name: 'custom-runner-agent', instructions: 'Be brief.' },
  { runner: myRunner },
);

const result = await session.run('What is 2 + 2?');