> ## Documentation Index
> Fetch the complete documentation index at: https://docs.svantic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Calling other agents

# Calling other agents

This guide covers how to call another A2A agent — another Svantic agent, a public third-party agent, or a local agent you're developing against.

The main tool is [`RemoteAgent`](../reference/remote-agent). It handles discovery, authentication, and the A2A protocol so you can focus on the call.

## One-shot structured call

Use `invoke_capability` when you know exactly which capability you want and the shape of its arguments:

```typescript theme={null}
import { RemoteAgent } from '@svantic/sdk';

const invoice = await RemoteAgent.connect(
  'https://api.svantic.com/agents/invoice-agent',
);

const result = await invoice.invoke_capability('lookup_invoice', {
  invoice_id: 'inv_123',
});

console.log(result);
```

The SDK unwraps the A2A `DataPart` envelope for you — `result` is whatever the remote handler returned.

## Natural-language prompt

Use `send` when you want the remote agent to plan its own work (only useful against [smart agents](./smart-agents)):

```typescript theme={null}
const billing = await RemoteAgent.connect('https://api.svantic.com/agents/billing-assistant');
const response = await billing.send('Refund invoice inv_123 for $42.');
```

`response` is an A2A `Message` or `Task`. Inspect `.parts` to extract text or data parts.

## Streaming responses

`send_stream` yields A2A events as they arrive — use it for anything that emits intermediate progress (plans, tool calls, partial outputs):

```typescript theme={null}
for await (const event of billing.send_stream('Summarize this month\'s invoices')) {
  if (event.kind === 'message' && event.parts?.[0]?.kind === 'text') {
    process.stdout.write(event.parts[0].text ?? '');
  }
}
```

Event types: `Message`, `Task`, `TaskStatusUpdateEvent`, `TaskArtifactUpdateEvent`.

## Rich messages (files, context, metadata)

Use [`MessageBuilder`](../reference/message-builder) when plain text isn't enough — attachments, session context, form replies, direct routing:

```typescript theme={null}
import { MessageBuilder, RemoteAgent } from '@svantic/sdk';

const docs = await RemoteAgent.connect('https://api.svantic.com/agents/docs-agent');

const msg = new MessageBuilder('Summarize this contract')
  .with_context_id(session_id)
  .with_file({
    name: 'msa.pdf',
    mime_type: 'application/pdf',
    size: 82_400,
    file_id: uploaded_file_id,
  })
  .build();

for await (const event of docs.send_stream_message(msg)) {
  console.log(event);
}
```

Upload files to Svantic first (`POST /files/upload`) and pass the returned `file_id` — the platform resolves it to LLM-native format at call time.

## Continuing a conversation

Pass a `context_id` (usually the Svantic `session_id`) to keep turns on the same conversation thread:

```typescript theme={null}
await billing.send('What was my last charge?', session_id);
await billing.send('Refund it.', session_id); // same conversation
```

## Inspecting before calling

Use [`AgentDiscovery`](../reference/agent-discovery) to fetch just the agent card:

```typescript theme={null}
import { AgentDiscovery } from '@svantic/sdk';

const discovery = new AgentDiscovery();
const card = await discovery.discover('https://api.svantic.com/agents/invoice-agent');

for (const skill of card.skills ?? []) {
  console.log(skill.name, '—', skill.description);
}
```

`RemoteAgent` discovers internally, so you don't need `AgentDiscovery` to call — use it only when inspection is the goal (e.g. building a capability picker).

## Authenticating

Most calls to Svantic-hosted agents go through your own agent's session (the caller's JWT is forwarded automatically when you're inside a capability handler or smart-agent turn). For standalone scripts calling a remote that requires auth, pass a bearer token:

```typescript theme={null}
await RemoteAgent.connect(url, bearer_token);
```

## Error handling

`invoke_capability`, `send`, and the stream methods reject or throw on transport, auth, or remote-side errors. Catch and inspect the message — the SDK preserves the A2A error payload in the thrown `Error`.

## See also

* [`RemoteAgent`](../reference/remote-agent)
* [`MessageBuilder`](../reference/message-builder)
* [`AgentDiscovery`](../reference/agent-discovery)
