1#![allow(clippy::uninlined_format_args)]
2use openai_ergonomic::{Client, Error};
36use std::io::{self, Write};
37
38#[tokio::main]
39async fn main() -> Result<(), Box<dyn std::error::Error>> {
40 println!(" OpenAI Ergonomic - Basic Assistants API Example\n");
41
42 let client = match Client::from_env() {
44 Ok(client_builder) => {
45 println!(" Client initialized successfully");
46 client_builder.build()
47 }
48 Err(e) => {
49 eprintln!(" Failed to initialize client: {e}");
50 eprintln!(" Make sure OPENAI_API_KEY is set in your environment");
51 return Err(e.into());
52 }
53 };
54
55 check_implementation_status();
57
58 println!("\n Example 1: Creating an Assistant");
60 println!("==================================");
61
62 create_assistant_example(&client);
63 println!(" Assistant creation example completed");
64
65 println!("\n Example 2: Thread Management");
67 println!("==============================");
68
69 thread_management_example(&client);
70 println!(" Thread management example completed");
71
72 println!("\n Example 3: Message Handling");
74 println!("=============================");
75
76 match message_handling_example(&client).await {
77 Ok(()) => println!(" Message handling example completed"),
78 Err(e) => {
79 eprintln!(" Message handling example failed: {e}");
80 handle_api_error(&e);
81 }
82 }
83
84 println!("\n Example 4: Tool Integration");
86 println!("=============================");
87
88 match tool_integration_example(&client).await {
89 Ok(()) => println!(" Tool integration example completed"),
90 Err(e) => {
91 eprintln!(" Tool integration example failed: {e}");
92 handle_api_error(&e);
93 }
94 }
95
96 println!("\n Example 5: Complete Conversation Flow");
98 println!("========================================");
99
100 match conversation_flow_example(&client).await {
101 Ok(()) => println!(" Conversation flow example completed"),
102 Err(e) => {
103 eprintln!(" Conversation flow example failed: {e}");
104 handle_api_error(&e);
105 }
106 }
107
108 println!("\n All examples completed!");
109 println!("\n This example demonstrated the intended Assistants API usage:");
110 println!(" • Assistant creation with custom instructions");
111 println!(" • Thread lifecycle management");
112 println!(" • Message sending and retrieval");
113 println!(" • Run creation and status polling");
114 println!(" • Tool integration patterns");
115 println!(" • Error handling strategies");
116
117 println!("\n Implementation Status:");
118 println!(" • The Assistants API builders and response types are placeholders");
119 println!(" • This example serves as a design template for future implementation");
120 println!(" • Actual API calls will be available once the builders are implemented");
121
122 Ok(())
123}
124
125fn check_implementation_status() {
127 println!(" Implementation Status Check");
128 println!("=============================");
129 println!(" Client infrastructure: Ready");
130 println!(" Assistants builders: Not yet implemented");
131 println!(" Threads builders: Not yet implemented");
132 println!(" Assistants responses: Not yet implemented");
133 println!();
134 println!(" This example demonstrates the intended API design");
135 println!(" and will work once the builders are implemented.");
136}
137
138fn create_assistant_example(_client: &Client) {
140 println!("Creating a new assistant with custom instructions...");
141
142 println!(" [Simulated] Assistant created successfully!");
188 println!(" ID: asst_abc123def456");
189 println!(" Name: Math Tutor");
190 println!(" Model: gpt-4");
191 println!(" Tools: 2 configured (code_interpreter, calculate_fibonacci)");
192 println!(" Instructions: Custom math tutoring instructions set");
193
194 println!("\n Assistant Configuration:");
195 println!(" • Model: GPT-4 for advanced reasoning");
196 println!(" • Code Interpreter: Enabled for calculations");
197 println!(" • Custom Function: Fibonacci calculator");
198 println!(" • Metadata: Tagged for tracking");
199}
200
201fn thread_management_example(_client: &Client) {
203 println!("Creating and managing conversation threads...");
204
205 println!(" [Simulated] Thread created: thread_abc123xyz789");
242 println!(" Thread information:");
243 println!(" Status: Active");
244 println!(" Created: 2024-01-15T10:30:00Z");
245 println!(" Messages: 0 (new thread)");
246 println!(" Metadata: {{\"user_id\": \"user_123\", \"session\": \"math_help_session\"}}");
247
248 println!("\n Thread Management Features:");
249 println!(" • Unique thread ID for session tracking");
250 println!(" • Metadata for context preservation");
251 println!(" • Message history maintained automatically");
252 println!(" • Thread retrieval and listing capabilities");
253}
254
255async fn message_handling_example(_client: &Client) -> Result<(), Error> {
257 println!("Adding messages to thread and getting assistant responses...");
258
259 let thread_id = "thread_abc123xyz789"; println!(" [Simulated] Adding user message to thread: {thread_id}");
312 println!(" Message: 'Can you help me solve this equation: 2x + 5 = 13?'");
313 println!(" Message ID: msg_user123abc");
314
315 println!("\n [Simulated] Creating run for assistant response...");
316 print!(" Status: ");
317 io::stdout().flush()?;
318
319 let statuses = ["queued", "in_progress", "completed"];
321 for (i, status) in statuses.iter().enumerate() {
322 if i > 0 {
323 print!(" → ");
324 }
325 print!("{status}");
326 io::stdout().flush()?;
327 tokio::time::sleep(tokio::time::Duration::from_millis(800)).await;
328 }
329 println!();
330
331 println!("\n [Simulated] Assistant Response:");
332 println!(" I'd be happy to help you solve the equation 2x + 5 = 13!");
333 println!();
334 println!(" Let's solve this step by step:");
335 println!(" 1. Start with: 2x + 5 = 13");
336 println!(" 2. Subtract 5 from both sides: 2x = 13 - 5");
337 println!(" 3. Simplify: 2x = 8");
338 println!(" 4. Divide both sides by 2: x = 8/2");
339 println!(" 5. Final answer: x = 4");
340 println!();
341 println!(" To verify: 2(4) + 5 = 8 + 5 = 13 ");
342
343 println!("\n Message Flow Summary:");
344 println!(" • User message successfully added to thread");
345 println!(" • Run created and executed with assistant");
346 println!(" • Step-by-step mathematical solution provided");
347 println!(" • Response includes verification of the answer");
348
349 Ok(())
350}
351
352async fn tool_integration_example(_client: &Client) -> Result<(), Error> {
354 println!("Demonstrating tool integration with code interpreter and custom functions...");
355
356 let thread_id = "thread_abc123xyz789";
384 let assistant_id = "asst_abc123def456";
385
386 println!(" [Simulated] User request: Calculate 10th Fibonacci number with visualization");
388 println!(" Thread: {thread_id}, Assistant: {assistant_id}");
389
390 println!("\n [Simulated] Tool Execution Flow:");
391 println!(" 1. Custom Function Call: calculate_fibonacci(n=10)");
392 print!(" Result: ");
393 io::stdout().flush()?;
394 tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
395 println!("55");
396
397 println!("\n 2. Code Interpreter: Generating Fibonacci sequence visualization");
398 print!(" Status: ");
399 io::stdout().flush()?;
400 let code_steps = [
401 "importing libraries",
402 "generating sequence",
403 "creating plot",
404 "complete",
405 ];
406 for (i, step) in code_steps.iter().enumerate() {
407 if i > 0 {
408 print!(" → ");
409 }
410 print!("{step}");
411 io::stdout().flush()?;
412 tokio::time::sleep(tokio::time::Duration::from_millis(600)).await;
413 }
414 println!();
415
416 println!("\n [Simulated] Assistant Response with Tool Results:");
417 println!(" I've calculated the 10th Fibonacci number and created a visualization for you!");
418 println!();
419 println!(" Results:");
420 println!(" • The 10th Fibonacci number is: 55");
421 println!(" • Complete sequence (1-10): [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]");
422 println!();
423 println!(" I've also generated a graph showing the exponential growth pattern");
424 println!(" of the Fibonacci sequence. The visualization clearly shows how each");
425 println!(" number rapidly increases as the sequence progresses.");
426 println!();
427 println!(" Tools Used:");
428 println!(" 1. Custom fibonacci function for precise calculation");
429 println!(" 2. Code interpreter for data visualization");
430
431 println!("\n Tool Integration Benefits:");
432 println!(" • Custom functions provide domain-specific capabilities");
433 println!(" • Code interpreter enables dynamic computation and visualization");
434 println!(" • Seamless integration in conversation flow");
435 println!(" • Automatic tool selection based on user needs");
436
437 Ok(())
438}
439
440async fn conversation_flow_example(_client: &Client) -> Result<(), Error> {
442 println!("Demonstrating a complete conversation flow with an assistant...");
443
444 println!(" [Simulated] Creating new thread for complete conversation...");
446 let thread_id = "thread_conversation_demo";
447 println!(" Thread ID: {thread_id}");
448
449 let conversation = [
451 ("user", "Hi! I'm working on a project about mathematical sequences. Can you help?"),
452 ("assistant", "Hello! I'd be delighted to help you with mathematical sequences. What specific aspect of sequences are you working on? Are you interested in arithmetic sequences, geometric sequences, Fibonacci numbers, or perhaps something else?"),
453 ("user", "I'm particularly interested in the golden ratio and how it relates to Fibonacci numbers."),
454 ("assistant", "Excellent topic! The golden ratio (φ ≈ 1.618) has a beautiful relationship with Fibonacci numbers. Let me explain and demonstrate this connection."),
455 ("user", "Could you calculate the ratio between consecutive Fibonacci numbers to show this?"),
456 ];
457
458 println!("\n [Simulated] Conversation Flow:");
459 println!("================================");
460
461 for (i, (role, message)) in conversation.iter().enumerate() {
462 println!(
463 "\n{}. {}: {}",
464 i + 1,
465 if *role == "user" { "User" } else { "Assistant" },
466 message
467 );
468
469 if *role == "user" && i < conversation.len() - 1 {
470 print!(" [Processing");
472 for _ in 0..3 {
473 print!(".");
474 io::stdout().flush()?;
475 tokio::time::sleep(tokio::time::Duration::from_millis(400)).await;
476 }
477 println!("]");
478 }
479 }
480
481 println!("\n [Simulated] Final Response with Tool Integration:");
483 println!("Assistant: I'll calculate the ratios between consecutive Fibonacci numbers to demonstrate the golden ratio convergence!");
484
485 print!("\n [Using fibonacci function and code interpreter");
486 for _ in 0..4 {
487 print!(".");
488 io::stdout().flush()?;
489 tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
490 }
491 println!("]");
492
493 println!("\n Here are the ratios of consecutive Fibonacci numbers:");
494 let fib_ratios = [
495 (1, 1, 1.0),
496 (1, 2, 2.0),
497 (2, 3, 1.5),
498 (3, 5, 1.667),
499 (5, 8, 1.6),
500 (8, 13, 1.625),
501 (13, 21, 1.615),
502 (21, 34, 1.619),
503 (34, 55, 1.618),
504 (55, 89, 1.618),
505 ];
506
507 for (a, b, ratio) in fib_ratios {
508 println!(
509 " F({}) / F({}) = {} / {} = {:.3}",
510 fib_ratios.iter().position(|(x, _, _)| *x == a).unwrap() + 1,
511 fib_ratios.iter().position(|(x, _, _)| *x == b).unwrap() + 2,
512 b,
513 a,
514 ratio
515 );
516 }
517
518 println!("\n As you can see, the ratio converges to φ ≈ 1.618 (the golden ratio)!");
519 println!(" This demonstrates the beautiful mathematical relationship between");
520 println!(" the Fibonacci sequence and the golden ratio.");
521
522 println!("\n Complete Conversation Summary:");
523 println!(" • Natural conversation flow with context preservation");
524 println!(" • Assistant understanding of complex mathematical concepts");
525 println!(" • Seamless tool integration for calculations and demonstrations");
526 println!(" • Educational explanations with concrete examples");
527 println!(" • Multi-turn conversation maintaining context throughout");
528
529 Ok(())
530}
531
532fn handle_api_error(error: &Error) {
534 match error {
535 Error::Api {
536 status,
537 message,
538 error_type,
539 error_code,
540 } => {
541 eprintln!(" API Error [{status}]: {message}");
542 if let Some(error_type) = error_type {
543 eprintln!(" Type: {error_type}");
544 }
545 if let Some(error_code) = error_code {
546 eprintln!(" Code: {error_code}");
547 }
548
549 match *status {
551 400 => {
552 eprintln!(" Check your request parameters (assistant ID, thread ID, etc.)");
553 }
554 401 => eprintln!(" Check your API key: export OPENAI_API_KEY=\"your-key\""),
555 404 => eprintln!(" Assistant or thread not found - verify IDs are correct"),
556 429 => eprintln!(" Rate limited - assistants API has specific rate limits"),
557 500..=599 => eprintln!(" Server error - try again later"),
558 _ => {}
559 }
560 }
561 Error::InvalidRequest(msg) => {
562 eprintln!(" Invalid Request: {msg}");
563 eprintln!(" Check your assistant/thread/message parameters");
564 }
565 Error::Config(msg) => {
566 eprintln!(" Configuration Error: {msg}");
567 eprintln!(" Check your client configuration");
568 }
569 Error::Http(err) => {
570 eprintln!(" HTTP Error: {err}");
571 eprintln!(" Check your network connection");
572 }
573 Error::HttpMiddleware(err) => {
574 eprintln!(" HTTP Middleware Error: {err}");
575 eprintln!(" Check your network connection and middleware configuration");
576 }
577 Error::Json(err) => {
578 eprintln!(" JSON Error: {err}");
579 eprintln!(" Response parsing failed - may be a temporary issue");
580 }
581 Error::Authentication(msg) => {
582 eprintln!(" Authentication Error: {msg}");
583 eprintln!(" Check your API key and organization ID");
584 }
585 Error::RateLimit(msg) => {
586 eprintln!(" Rate Limit Error: {msg}");
587 eprintln!(" Assistants API has specific rate limits - wait before retrying");
588 }
589 Error::Builder(msg) => {
590 eprintln!(" Builder Error: {msg}");
591 eprintln!(" Check your assistant/thread builder configuration");
592 }
593 _ => {
594 eprintln!(" Unexpected Error: {error}");
595 eprintln!(" This may be a bug, please report it");
596 }
597 }
598}
599
600#[allow(dead_code)]
604fn poll_run_completion(_client: &Client, _thread_id: &str, _run_id: &str) -> MockRun {
605 MockRun {
608 id: "run_completed123".to_string(),
609 status: "completed".to_string(),
610 }
611}
612
613#[allow(dead_code)]
615struct MockRun {
616 id: String,
617 status: String,
618}
619
620#[allow(dead_code)]
621impl MockRun {
622 fn id(&self) -> &str {
623 &self.id
624 }
625
626 fn status(&self) -> &str {
627 &self.status
628 }
629}