Skip to content

Chat Completions

Chat completions are the primary API for interacting with AI models. Both runtimes provide a unified interface that works across all 37 providers.

let client = AiClient::new("openai/gpt-4o").await?;
let response = client.chat()
.user("Hello, world!")
.execute()
.await?;
println!("{}", response.content);
client = await AiClient.create("openai/gpt-4o")
response = await client.chat() \
.user("Hello, world!") \
.execute()
print(response.content)
import { AiClient } from '@hiddenpath/ai-lib-ts';
const client = await AiClient.new('openai/gpt-4o');
const response = await client
.chat()
.user('Hello, world!')
.execute();
console.log(response.content);

Set the model’s behavior:

// Rust
client.chat()
.system("You are a helpful coding assistant. Always include code examples.")
.user("Explain closures")
.execute().await?;
# Python
await client.chat() \
.system("You are a helpful coding assistant.") \
.user("Explain closures") \
.execute()
// TypeScript
await client
.chat()
.system('You are a helpful coding assistant.')
.user('Explain closures')
.execute();

Pass conversation history:

// Rust
use ai_lib_rust::{Message, MessageRole};
let messages = vec![
Message::system("You are a tutor."),
Message::user("What is recursion?"),
Message::assistant("Recursion is when a function calls itself..."),
Message::user("Can you show an example?"),
];
client.chat().messages(messages).execute().await?;
# Python
from ai_lib_python import Message
messages = [
Message.system("You are a tutor."),
Message.user("What is recursion?"),
Message.assistant("Recursion is when a function calls itself..."),
Message.user("Can you show an example?"),
]
await client.chat().messages(messages).execute()
// TypeScript
import { Message } from '@hiddenpath/ai-lib-ts';
const messages = [
Message.system('You are a tutor.'),
Message.user('What is recursion?'),
Message.assistant('Recursion is when a function calls itself...'),
Message.user('Can you show an example?'),
];
await client.chat().messages(messages).execute();
ParameterTypeDescription
temperaturefloatRandomness (0.0 = deterministic, 2.0 = creative)
max_tokensintMaximum response length
top_pfloatNucleus sampling (alternative to temperature)
stopstring[]Sequences that stop generation
// Rust
client.chat()
.user("Write a poem")
.temperature(0.9)
.max_tokens(200)
.top_p(0.95)
.execute().await?;
# Python
await client.chat() \
.user("Write a poem") \
.temperature(0.9) \
.max_tokens(200) \
.top_p(0.95) \
.execute()
// TypeScript
await client
.chat()
.user('Write a poem')
.temperature(0.9)
.maxTokens(200)
.topP(0.95)
.execute();

For real-time output, use streaming:

// Rust
let mut stream = client.chat()
.user("Tell me a story")
.stream()
.execute_stream()
.await?;
while let Some(event) = stream.next().await {
if let StreamingEvent::ContentDelta { text, .. } = event? {
print!("{text}");
std::io::stdout().flush()?;
}
}
# Python
async for event in client.chat() \
.user("Tell me a story") \
.stream():
if event.is_content_delta:
print(event.as_content_delta.text, end="", flush=True)
// TypeScript
for await (const event of client.chat()
.user('Tell me a story')
.stream()) {
if (event.isContentDelta) {
process.stdout.write(event.asContentDelta.text);
}
}

Track usage for cost management:

// Rust
let (response, stats) = client.chat()
.user("Hello")
.execute_with_stats()
.await?;
println!("Prompt tokens: {}", stats.prompt_tokens);
println!("Completion tokens: {}", stats.completion_tokens);
println!("Latency: {}ms", stats.latency_ms);
# Python
response, stats = await client.chat() \
.user("Hello") \
.execute_with_stats()
print(f"Tokens: {stats.total_tokens}")
print(f"Latency: {stats.latency_ms}ms")
// TypeScript
const { response, stats } = await client
.chat()
.user('Hello')
.executeWithStats();
console.log(`Tokens: ${stats.totalTokens}`);
console.log(`Latency: ${stats.latencyMs}ms`);

The same code works across all providers:

// Just change the model identifier
let client = AiClient::new("anthropic/claude-3-5-sonnet").await?;
let client = AiClient::new("deepseek/deepseek-chat").await?;
let client = AiClient::new("gemini/gemini-2.0-flash").await?;
# Python - same pattern
client = await AiClient.create("anthropic/claude-3-5-sonnet")
client = await AiClient.create("deepseek/deepseek-chat")
client = await AiClient.create("gemini/gemini-2.0-flash")
// TypeScript - same pattern
const client = await AiClient.new('anthropic/claude-3-5-sonnet');
const client = await AiClient.new('deepseek/deepseek-chat');
const client = await AiClient.new('gemini/gemini-2.0-flash');

The protocol manifest handles endpoint URLs, authentication, parameter mapping, and streaming format differences automatically.