Documentation/Direct LLM Access
v2.0.0-beta.1Snapshot bebdcd1Markdown ↗

Direct LLM Access

Direct LLM Access

Agent inherits runDirect() and streamDirect() methods from BaseAgent. These methods bypass all context management for simple, stateless LLM calls.

When to Use Direct Access

Use Case Recommended Method
Conversational agent with history run()
Task with memory and tools run() with context features
Per-call reasoning control run(input, { thinking })
Quick one-off query runDirect()
Embedding-like simplicity runDirect()
Testing/debugging runDirect()
Hybrid workflows Mix both

Basic Usage

typescript
const agent = Agent.create({ connector: 'openai', model: 'gpt-4.1' });

// Direct call - bypasses all context management
const response = await agent.runDirect('What is 2 + 2?');
console.log(response.output_text);  // "4"

// Conversation is NOT affected
console.log(agent.context.getConversation().length);  // 0

DirectCallOptions

typescript
interface DirectCallOptions {
  /** System instructions */
  instructions?: string;

  /** Include registered tools (default: false) */
  includeTools?: boolean;

  /** Explicit per-call definitions (used instead of registered tools) */
  tools?: Tool[];

  /** Tool-selection policy for explicit or included tools */
  toolChoice?: 'auto' | 'required' | { type: 'function'; function: { name: string } };

  /** Temperature for generation */
  temperature?: number;

  /** Maximum output tokens */
  maxOutputTokens?: number;

  /** Continue a provider-stored response/interaction */
  previousResponseId?: string;

  /** Vendor-agnostic structured (JSON) output */
  responseFormat?:
    | { type: 'json_object' }
    | { type: 'json_schema'; schema: Record<string, unknown>; name?: string; description?: string; strict?: boolean };

  /** Vendor-agnostic thinking/reasoning configuration */
  thinking?: {
    enabled: boolean;
    budgetTokens?: number;   // Fixed-budget models
    effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
  };

  /** Vendor-specific options */
  vendorOptions?: Record<string, unknown>;

  /** Provider-neutral prompt-cache policy */
  promptCache?: PromptCachePolicy;

  /** Provider-hosted tools (not executed by ToolManager) */
  nativeTools?: NativeToolRequest[];

  /** Explicit permission for retention-sensitive provider features */
  dataHandling?: DataHandlingPolicy;

  /** Skip the provider pre-flight context limit check (default: false) */
  skipContextLimitCheck?: boolean;
}

Examples

typescript
// With options
const response = await agent.runDirect('Summarize this text', {
  instructions: 'Be concise. Use bullet points.',
  temperature: 0.5,
  maxOutputTokens: 200,
});

// JSON response
const responseVariant2 = await agent.runDirect('List 3 fruits', {
  responseFormat: { type: 'json_object' },
  instructions: 'Return a JSON array of fruit names',
});

// Multimodal (text + image)
const responseVariant3 = await agent.runDirect([
  {
    type: 'message',
    role: 'user',
    content: [
      { type: 'input_text', text: 'What is in this image?' },
      { type: 'input_image', image_url: 'https://example.com/image.png' }
    ]
  }
]);

// With tools (single call - you handle tool calls manually)
const responseVariant4 = await agent.runDirect('Get the weather in Paris', {
  includeTools: true,
});
// If response contains tool_calls, you must execute them yourself
if (responseVariant4.output.some(item => item.type === 'function_call')) {
  // Handle tool calls manually
}

Streaming

typescript
// Stream responses for real-time output
for await (const event of agent.streamDirect('Tell me a story')) {
  if (event.type === 'response.output_text.delta') {
    process.stdout.write(event.delta);
  }
}

// With options
for await (const event of agent.streamDirect('Explain quantum computing', {
  instructions: 'Use simple terms',
  temperature: 0.7,
})) {
  // Handle events...
}

Per-Call RunOptions

run() and stream() accept an optional second argument to override agent-level config for a single invocation:

typescript
interface RunOptions {
  /** Vendor-agnostic thinking/reasoning configuration */
  thinking?: {
    enabled: boolean;
    budgetTokens?: number;         // Fixed-budget models
    effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
  };

  /** Temperature override */
  temperature?: number;

  /** Vendor-specific options (shallow-merged with agent-level vendorOptions) */
  vendorOptions?: Record<string, unknown>;

  /** Provider-neutral prompt-cache policy */
  promptCache?: PromptCachePolicy;

  /** Provider-hosted tools (not executed by ToolManager) */
  nativeTools?: NativeToolRequest[];

  /** Explicit permission for retention-sensitive provider features */
  dataHandling?: DataHandlingPolicy;

  /** Resume an incomplete provider decode on the first request of this run */
  continuationToken?: string;

  /** Vendor-agnostic structured (JSON) output override for this call */
  responseFormat?:
    | { type: 'json_object' }
    | { type: 'json_schema'; schema: Record<string, unknown>; name?: string; description?: string; strict?: boolean };
}
typescript
// Override reasoning effort per call
const deep = await agent.run('Prove this theorem', {
  thinking: { enabled: true, effort: 'high' },
});

const quick = await agent.run('What is 2+2?', {
  thinking: { enabled: true, effort: 'low' },
});

// Override temperature per call
const creative = await agent.run('Write a poem', { temperature: 0.9 });

// Streaming with per-call options
for await (const event of agent.stream('Analyze this', {
  thinking: { enabled: true, budgetTokens: 16384 },
})) {
  // ...
}

RunOptions take precedence over agent-level config. vendorOptions are shallow-merged (per-call keys override agent-level keys). Advanced inference options replace their agent-level value as a whole; see Advanced Inference for the complete contract.

Thinking / Reasoning

Vendor-agnostic reasoning configuration that maps to each provider's native API:

Provider effort maps to budgetTokens maps to
OpenAI reasoning.effort N/A
Anthropic output_config.effort thinking.budget_tokens on fixed-budget models
Google Gemini thinking level (the exact supported subset is model-dependent) thinkingConfig.thinkingBudget on fixed-budget models
typescript
// Agent-level (applies to all calls)
const agent = Agent.create({
  connector: 'openai', model: 'o3-mini',
  thinking: { enabled: true, effort: 'medium' },
});

// Per-call override
await agent.run('Complex analysis', { thinking: { enabled: true, effort: 'high' } });
await agent.run('Simple lookup', { thinking: { enabled: true, effort: 'low' } });

// Anthropic with budget tokens
const agent2 = Agent.create({ connector: 'anthropic', model: 'claude-sonnet-4-6' });
await agent2.run('Deep reasoning task', { thinking: { enabled: true, budgetTokens: 16384 } });

// runDirect() also supports thinking
await agent.runDirect('Quick Q', { thinking: { enabled: true, effort: 'low' } });

The normalized thinking.enabled flag gates both its nested effort and budget. Anthropic also supports native effort independently of thinking; use vendorOptions: { effort: 'low' | 'medium' | 'high' | ... } when that distinct provider behavior is intended while normalized thinking is disabled.

Comparison: run() vs runDirect()

Aspect run() runDirect()
History tracking ✅ Automatic ❌ None
WorkingMemory ✅ Available ❌ Not used
Context preparation ✅ Full preparation ❌ None
Agentic loop ✅ Executes tools automatically ❌ Single call only
Compaction ✅ Auto-compacts when needed ❌ None
Overhead Full context management Minimal

Hybrid Workflows

You can mix both approaches in the same agent:

typescript
const agent = Agent.create({
  connector: 'openai',
  model: 'gpt-4.1',
  tools: [weatherTool, searchTool],
});

// Use run() for complex interactions with tool use
await agent.run('Search for the latest news and summarize');

// Use runDirect() for quick follow-ups that don't need context
const clarification = await agent.runDirect(
  'What is a good synonym for "excellent"?',
  { temperature: 0.3 }
);

// Back to run() for continued conversation
await agent.run('Now tell me more about the first item');

Documentation snapshot · 2026-11-02Suggest a correction ↗

Search documentation

Type to search the v2 documentation.