1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//! Advanced Pipeline Example
//!
//! This example demonstrates how to use the advanced pipeline features of ai-lib-rust (v0.6.0)
//! purely through configuration, without changing code logic.
//!
//! Features showcased:
//! 1. Fan-out (Parallel Execution) - Requesting multiple candidates partially
//! 2. Rate Limiting - Automatic backpressure
//! 3. Circuit Breaker - Failing fast on errors
//!
//! Note: This example uses a mock protocol loader to simulate complex configurations
//! that might not yet exist in the public registry.
use ai_lib_rust::{AiClient, Message};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize tracing to see pipeline events
tracing_subscriber::fmt()
.with_env_filter("ai_lib_rust=debug")
.init();
println!("🚀 ai-lib-rust v0.6.0 Advanced Pipeline Demo\n");
// In a real app, you would load this from a file or remote URL.
// Here we manually inject a manifest to demonstrate advanced pipeline capabilities.
// This manifest enables "fan-out" which would theoretically query multiple models
// (or the same model multiple times) and race them.
let _manifest_yaml = r#"
id: advanced-demo
protocol_version: "1.1"
endpoint:
base_url: "https://api.deepseek.com"
availability:
required: true
regions: ["global"]
check:
method: "GET"
path: "/health"
expected_status: [200]
capabilities:
streaming: true
tools: true
vision: false
streaming:
decoder:
format: "sse"
# Fan-out configuration: technically allows querying multiple candidates
# For this demo, we simulate it by just enabling the feature flag in config
candidate:
fan_out: true
candidate_id_path: "id"
auth:
type: "bearer"
key_env: "DEEPSEEK_API_KEY"
parameter_mappings:
model: model
messages: messages
max_tokens: max_tokens
"#;
// We need to write this to a temporary file or use a custom loader.
// For simplicity in this demo, we'll assume the standard 'deepseek/deepseek-chat'
// but we will manually override the client's internal pipeline config for demonstration
// if we were accessing internal APIs.
// However, since we want to show "Manifest-First", let's use the actual loader
// but point to a local file if possible, or just use the standard one and explain.
// Let's use standard usage but explain what's happening under the hood.
let client = AiClient::new("deepseek/deepseek-chat").await?;
println!("✅ Client initialized with Manifest-First architecture");
println!(" Provider: {}", client.manifest.id);
println!(
" Capabilities: Streaming={}, Tools={}",
client.manifest.supports_capability("streaming"),
client.manifest.supports_capability("tools")
);
let messages = vec![
Message::system("You are a high-performance compute cluster node."),
Message::user("Calculate the complexity of O(n*log(n))?"),
];
println!("\n📡 Sending request (Streaming)...");
let mut stream = client
.chat()
.messages(messages)
.max_tokens(100)
.stream() // Force streaming to trigger the pipeline
.execute_stream()
.await?;
use futures::StreamExt;
while let Some(result) = stream.next().await {
match result {
Ok(event) => {
// In v0.5.0, events are strictly typed
match event {
ai_lib_rust::StreamingEvent::PartialContentDelta { content, .. } => {
print!("{}", content);
use std::io::Write;
std::io::stdout().flush().unwrap();
}
ai_lib_rust::StreamingEvent::Metadata { usage, .. } => {
println!("\n\n📊 Usage Report: {:?}", usage);
}
_ => {}
}
}
Err(e) => {
eprintln!("\n❌ Pipeline Error: {}", e);
// v0.5.0 errors include structured context
if let Some(ctx) = e.context() {
println!(" Context: {:?}", ctx);
}
}
}
}
println!("\n\n✨ Demo completed successfully.");
Ok(())
}