ADKClient Reference
Agent execution, streaming, sessions, async requests, and skill generation via the ADK service
Updated 2026-11-03
Verified 2026-11-03
ADKClient communicates with the Cosmos ADK service for agent execution. It supports synchronous converse, WebSocket streaming (v2), session management, async background requests, direct LLM calls, and skill generation.
Access it via cosmos.adkClient after creating a CosmosClient.
Synchronous Converse
Send a message and receive a complete response. The ADK handles the full agentic loop — tool execution, session creation, and multi-turn reasoning — server-side.
import type { ADKConverseRequest, ADKConverseResponse } from '@cosmos/sdk';
const response: ADKConverseResponse = await cosmos.adkClient.converse({
agent_id: 'agent-uuid',
agent_version: '1.0',
user_id: 'user-123',
query: 'What were our Q1 sales?',
channel: 'chat',
language: 'en',
reasoning_event: true,
});
console.log(response.response.content);
console.log('Session ID:', response.session_id);
console.log('Final?', response.response.is_final);
// Reasoning events (if requested)
for (const event of response.events ?? []) {
console.log(`[${event.event}]`, event.files ?? '');
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | One of agent_id/app_id | Agent UUID |
agent_version | string | No | Version string (e.g., "1.0") |
app_id | string | One of agent_id/app_id | App UUID |
user_id | string | Yes | Unique user identifier |
query | string | Yes | User message |
channel | string | No | "chat", "voice", "whatsapp" |
language | string | No | Target language |
user_data | Record<string, unknown> | No | Custom context merged into session state |
reasoning_event | boolean | No | Include reasoning events in response |
WebSocket Streaming (ADK v2)
For real-time streaming with local tool callbacks, use CosmosClient.sendMessageViaADK() which manages an ADKV2StreamSession internally.
const result = await cosmos.sendMessageViaADK(null, 'Analyze this data', {
agentId: 'agent-uuid',
agentVersion: '1.0',
providerId: 'azure_openai',
modelId: 'gpt-4o',
temperature: 0.7,
maxOutputTokens: 2048,
skills: [{ id: 'skill-uuid', version: '1.0' }],
sessionState: { projectId: 'project-uuid', workbench: 'sap-adt' },
additionalInstructions: 'Prefer concise answers.',
additionalCollectionIds: ['collection-uuid'],
excludeTools: ['tool-to-skip'],
appName: 'support-workbench',
onChunk: (text) => process.stdout.write(text),
onToolCallArgsDelta: (name, jsonPath, delta) => console.log(name, jsonPath, delta),
});
console.log('\nSession:', result.sessionId);
console.log('End conversation?', result.endConversation);
sessionState is optional. Use it when a server-side consumer app needs project, workbench, or request context persisted in the initial ADK session state.
ADKV2StreamSession (Low-Level)
For full control, use ADKV2StreamSession directly:
import { ADKV2StreamSession } from '@cosmos/sdk';
const session = new ADKV2StreamSession(
'ws://localhost:8103/api/v1/adk/converse/v2', // local ADK; use wss://<adk-host>/... when deployed
orgId,
() => cosmos.auth.getAccessToken(),
cosmos.toolManager.getLocalHandlers(),
projectId, // optional; sent as X-Project-Id on the handshake
);
const result = await session.startAndRun(
{
userId: 'user-123',
query: 'Hello',
agentId: 'agent-uuid',
agentVersion: '1.0',
sessionState: { projectId: 'project-uuid' },
},
{
onChunk: (text) => process.stdout.write(text),
onToolStart: (name) => console.log(`\n🔧 ${name}...`),
onToolComplete: (name, result) => console.log(`✅ ${name} done`),
onToolCallArgsDelta: (name, path, delta) => console.log(name, path, delta),
onReasoning: (content) => console.log(`💭 ${content}`),
onError: (code, msg, fatal) => console.error(`Error [${code}]: ${msg}`),
},
);
// Follow-up turn on same WebSocket
const result2 = await session.sendQuery('Tell me more', {
onChunk: (text) => process.stdout.write(text),
});
// Cancel current turn
session.cancel();
// Clean up
session.close();
V2 Server Events
The WebSocket sends the following events:
| Event | Description |
|---|---|
session | Session ID assigned |
chunk | Streamed text content |
tool_call | Request to execute a local tool (SDK handles automatically) |
tool_call_args_delta | Partial tool-call arguments while the model is still generating |
tool_start | Server-side tool execution started |
tool_complete | Server-side tool execution completed |
reasoning | Intermediate reasoning content |
custom_event | Service-defined extension event |
plan_proposed, plan_step_start, plan_step_complete | Plan/execute progress events |
turn_complete | Turn finished, includes usage and session ID |
error | Error occurred (may be fatal or non-fatal) |
skillIds is deprecated. Use versioned skills entries for new code. Plan approval/rejection helper APIs are not exposed; consume plan progress through callbacks.
Send Options
ADKV2SendOptions groups request fields and turn callbacks:
| Group | Options |
|---|---|
| Agent selection | agentId, agentVersion, or prompt-only mode with systemPrompt, providerId, modelId |
| Prompt and context | additionalInstructions, additionalCollectionIds, skills (versioned { id, version }), skillIds (deprecated), sessionState, images, imageAttachments |
| Tools | tools, excludeTools, mcpServers, clientToolTimeoutSeconds (server default 120 seconds), maxToolRoundtrips, toolResultMaxBytes |
| Generation | temperature, maxOutputTokens, executionMode ('direct' or 'plan_execute'), reasoningEvent, sessionProfile ('chat' or 'coding') |
| Scope and labels | executionContext (appId, scope, optional manifestHash, resources), observabilityMetadata, channel, appName |
| Callbacks | onChunk, onCustomEvent, onToolCall, onToolStart, onToolComplete, onToolCallArgsDelta, onReasoning, onError(code, message, fatal), onCostNotice, onPlanProposed, onPlanStepStart, onPlanStepComplete, onUsage |
executionContextis the app/scope boundary ADK uses to check agent execution and knowledge-base access against scoped RBAC. SetmanifestHashwhen the caller pins an execution manifest.reasoningEvent: trueis required foronReasoningto receive model thinking content.sessionProfile: 'coding'keeps more tool responses visible in replay and defaultstoolResultMaxBytesto 51200 bytes. Successful tool results larger thantoolResultMaxBytesare truncated with a hint to use ranged reads.0means unlimited.maxToolRoundtripscaps the local tool calls the SDK executes per turn; further calls return a budget-exhausted error to the model.
Context Compaction and Usage
ADK owns context compaction and history filtering for the session. The SDK does not send compaction or retention controls on the start frame.
Use onUsage to observe context growth. It fires as each model response reports usage, before turn_complete:
await cosmos.sendMessageViaADK(sessionId, 'Continue', {
onUsage: (usage) => {
// promptTokens is the live context size of the call that just completed
console.log(usage.promptTokens, usage.completionTokens);
console.log(usage.cumulativePromptTokens, usage.cumulativeCompletionTokens);
// contextLimit: model context window reported by ADK
// tokenThreshold: compaction trigger, only when the session has one configured
console.log(usage.contextLimit, usage.tokenThreshold);
},
});
Tool Results and Errors
The SDK executes tool_call requests with locally registered handlers and replies with a tool_result frame (call_id, name, result, and error when the tool failed).
| Handler outcome | result sent | error sent |
|---|---|---|
{ ok: true, data } | data (strings as-is, other values JSON-encoded) | Not sent |
{ ok: false, error: { code, message } } | JSON of the error object | error.message, or 'Tool failed' when no message is set |
| Handler throws | JSON of { code: 'TOOL_EXECUTION_FAILED', message } | The thrown error's message |
| No handler registered | JSON of { code: 'TOOL_NOT_FOUND', message } | No handler registered for tool: <name> |
When error is present, ADK returns {"error": "<message>"} to the model as the tool response, so the model sees the real failure reason instead of a generic failure. The legacy is_error flag is no longer sent. ADK also produces error responses itself when a client tool times out (see clientToolTimeoutSeconds), is cancelled, or the connection closes.
Runtime Notes
The SDK targets Node.js 18+ and also runs under Bun. The ADK WebSocket handshake passes tls: { ecdhCurve: 'X25519:P-256:P-384' }. Bun forwards this to its TLS layer, which pins classical ECDH key exchange so corporate TLS interception proxies that reset Bun's default post-quantum ClientHello do not break the connection. Node's ws ignores the option. Certificate validation is not affected.
Session Management
List Sessions
const sessions = await cosmos.adkClient.listSessions({
user_id: 'user-123',
agent_id: 'agent-uuid',
limit: 20,
});
for (const session of sessions) {
console.log(`${session.id} — ${session.app_name} — ${session.create_time}`);
}
Get Session Events
const events = await cosmos.adkClient.getSessionEvents(sessionId, {
skip: 0,
limit: 50,
});
for (const event of events) {
console.log(`[${event.author}] ${event.timestamp}`, event.content);
}
Update Session Metadata
await cosmos.adkClient.updateSessionMetadata(sessionId, {
name: 'Q1 Sales Analysis',
pinned: true,
tags: ['sales', 'q1'],
});
Event Injection
Inject external context or system messages into an existing session:
await cosmos.adkClient.addEvent({
app_name: 'my-app',
user_id: 'user-123',
session_id: sessionId,
content: 'New data has been uploaded to the knowledge base.',
state_delta: { kb_updated: true },
});
Direct LLM Calls
Bypass agent logic and call an LLM directly through the ADK:
const llmResponse = await cosmos.adkClient.callLLM({
provider: 'azure_openai',
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Translate "hello" to French.' },
],
temperature: 0.3,
max_tokens: 100,
});
console.log(llmResponse.message.content);
Async Requests
Submit agent requests that run in the background. Useful for long-running tasks.
Submit
const { request_id } = await cosmos.adkClient.submitAsync({
agent_id: 'agent-uuid',
agent_version: '1.0',
user_id: 'user-123',
query: 'Generate a comprehensive market analysis report',
callback_url: 'https://my-app.com/webhooks/adk',
callback_method: 'POST',
});
console.log('Queued:', request_id);
Poll for Status
const status = await cosmos.adkClient.getAsyncStatus(request_id);
console.log(status.status); // 'queued' | 'processing' | 'completed' | 'failed'
if (status.status === 'completed') {
console.log(status.response?.content);
}
Poll Until Done (Helper)
const final = await cosmos.adkClient.pollAsyncUntilDone(request_id, 2000, 120_000);
if (final.status === 'completed') {
console.log(final.response?.content);
} else {
console.error(final.error_message);
}
List Async Requests
const list = await cosmos.adkClient.listAsyncRequests({
user_id: 'user-123',
status: 'completed',
limit: 10,
});
console.log(`${list.total} total, showing ${list.requests.length}`);
Skill Generation
Generate skill proposals from a conversation, agent prompt, or free-text description:
// From a description
const result = await cosmos.generateSkills({
source: 'description',
description: 'A skill that helps users debug failing API calls',
maxSkills: 3,
});
for (const proposal of result.proposals) {
console.log(`${proposal.name}: ${proposal.description}`);
console.log(` Rationale: ${proposal.rationale}`);
console.log(` Instructions: ${proposal.instructions.slice(0, 100)}...`);
}
// From an existing agent prompt
const result2 = await cosmos.generateSkills({
source: 'agent_prompt',
agentId: 'agent-uuid',
agentVersion: '1.0',
});
Type Reference
All ADK types are exported from the package root:
import type {
ADKConverseRequest,
ADKConverseResponse,
ADKConverseResponsePayload,
ADKReasoningEvent,
ADKAddEventRequest,
ADKAddEventResponse,
ADKSession,
ADKSessionEvent,
ADKSessionsListParams,
ADKSessionEventsParams,
ADKAsyncSubmitRequest,
ADKAsyncSubmitResponse,
ADKAsyncRequestStatus,
ADKAsyncStatusResponse,
ADKAsyncListParams,
ADKAsyncListResponse,
ADKV2SendOptions,
ADKV2ExecutionContext,
ADKV2ImageAttachment,
ADKV2TurnCallbacks,
ADKV2TurnResult,
ADKV2ToolDefinition,
ADKV2ToolEventMeta,
ADKV2Usage,
GenerateSkillsInput,
SkillProposal,
GenerateSkillsResponse,
} from '@cosmos/sdk';
See Also
- Quick Start — install and first call
- CosmosClient Reference — main client and configuration
- Code Examples — recipes for common patterns
- Auto-generated API reference — TypeDoc for ADKClient