Skip to content

Latest Rust SDK #97

Merged
sawradip merged 4 commits into
mainfrom
rad/rust_sdk_v2
Nov 17, 2025
Merged

Latest Rust SDK #97
sawradip merged 4 commits into
mainfrom
rad/rust_sdk_v2

Conversation

@RadeenXALNW
Copy link
Copy Markdown
Collaborator

@RadeenXALNW RadeenXALNW commented Nov 16, 2025

New rust sdk comes with sync and async of both streaming and non streaming as well as fixed the argument for both streaming and non streaming. Now runs with run and run_stream

Summary by CodeRabbit

  • New Features

    • Added synchronous/blocking client API for Rust SDK
    • Configuration builder pattern for simplified client initialization
  • Documentation

    • Completely redesigned Rust SDK README with configuration overview and usage examples
    • Added publishing guide for Rust SDK release workflow
    • New example implementations demonstrating async, sync, and builder patterns
  • Chores

    • Rust SDK version bumped to 0.1.34
    • Updated templates and test scripts

sawradip and others added 4 commits November 15, 2025 20:53
- Introduced RunAgentClientConfig struct for improved configuration management.
- Updated client initialization to support builder pattern for optional parameters.
- Enhanced documentation with examples for creating clients using both direct construction and builder pattern.
- Improved error handling and logging for local agent configuration.
- Added support for enabling/disabling database registry lookup in client configuration.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 16, 2025

Walkthrough

This PR introduces a configuration-driven architecture for the Rust SDK, replacing direct constructor parameters with a RunAgentClientConfig struct. Key additions include a new blocking (synchronous) API wrapper, enhanced structured error handling via an "Execution" variant, streamlined response deserialization supporting multiple payload formats, and comprehensive documentation updates. Constants are simplified, and all examples and test scripts are updated to use the new configuration pattern.

Changes

Cohort / File(s) Change Summary
Configuration Model (RunAgentClientConfig)
runagent-rust/runagent/src/client/runagent_client.rs, runagent-rust/runagent/src/client/mod.rs, runagent-rust/runagent/src/lib.rs
Introduces new RunAgentClientConfig struct with builder-pattern methods (with_local, with_address, with_api_key, etc.); replaces RunAgentClient::new to accept config instead of positional parameters; adds initialize_architecture and create_remote_clients helpers; wires extra_params field through client.
Blocking/Synchronous API
runagent-rust/runagent/src/blocking.rs, runagent-rust/runagent/src/lib.rs
New blocking module providing synchronous RunAgentClient wrapper backed by Tokio runtime; introduces BlockingStream iterator for streaming responses via background thread polling; re-exports both as BlockingRunAgentClient and BlockingStream.
Error Handling Enhancement
runagent-rust/runagent/src/types/errors.rs
Adds new Execution enum variant to RunAgentError with code, message, suggestion, details fields; includes constructor RunAgentError::execution(); extends retryability logic for specific error codes.
Response Deserialization & Payload Handling
runagent-rust/runagent/src/utils/serializer.rs, runagent-rust/runagent/src/client/rest_client.rs, runagent-rust/runagent/src/client/socket_client.rs
Adds prepare_for_deserialization() method to handle JSON string parsing; expands deserialize_object() to support multiple payload shapes (type/payload, legacy content, strings); reworks get_agent_architecture() to parse success/data/error envelope with structured error mapping.
Constants Simplification
runagent-rust/runagent/src/constants.rs
Removes legacy CLI-oriented constants (TEMPLATE_REPO_URL, Framework enum, etc.); introduces client-focused constants (DEFAULT_BASE_URL, DEFAULT_API_PREFIX, DEFAULT_TIMEOUT_SECONDS, AGENT_CONFIG_FILE_NAME).
Configuration & Database
runagent-rust/runagent/src/db/service.rs, runagent-rust/runagent/src/types/schema.rs, runagent-rust/runagent/src/utils/config.rs
Updates database path resolution via runtime Lazy static LOCAL_CACHE_DIRECTORY; removes file-based config persistence; transitions setup() to environment-based config loading; removes public APIs for config file manipulation (set_base_url, set_api_key, backup, clear).
Examples - New Async/Sync Patterns
runagent-rust/runagent/examples/async_example.rs, runagent-rust/runagent/examples/sync_example.rs, runagent-rust/runagent/examples/direct_construction.rs, runagent-rust/runagent/examples/direct_construction_omitted.rs, runagent-rust/runagent/examples/test_deserialize.rs
Introduces five new example files demonstrating async/sync client creation via RunAgentClientConfig, builder pattern usage, direct struct construction with defaults, and deserialization example.
Test Scripts - Config Migration
test_scripts/rust/test_*/src/main.rs (8 files: ag2, agno, autogen, crewai, langchain, langgraph, letta, parlant)
Updates all test scripts to use RunAgentClientConfig-based RunAgentClient::new() instead of positional parameters; migrates from run_with_args() to run() method calls.
Lead Agent Backend
examples/lead-agent/backend-rust/src/main.rs
Replaces direct client construction with RunAgentClientConfig; switches run_with_args(&[], &params) to run(&params); adds payload extraction logic for unwrapping "payload" field from RunAgent result; updates RUNAGENT_ID constant value.
Configuration Files
examples/lead-agent/lead-score-flow/runagent.config.json, templates/agno/default/runagent.config.json, test_scripts/python/client_test_agno.py
Updates agent_id values and metadata (agent_name, description) in config files; no structural changes.
Documentation & Publishing
runagent-rust/runagent/README.md, runagent-rust/PUBLISH.md, sdk_checklist.md, runagent-rust/runagent/Cargo.toml
Comprehensive README rewrite focusing on RunAgentClientConfig pattern, builder API, streaming vs. non-streaming guardrails, error handling; adds new PUBLISH.md release workflow guide; extends sdk_checklist.md with Architecture Metadata Contract; version bump to 0.1.34.
Backend Python Template
templates/agno/default/simple_assistant.py
Non-streaming response now extracts content via priority chain (response.content → messages last item → response.text); streaming yields dictionaries with "content" field.
Dependency Changes
test_scripts/rust/test_agno/Cargo.toml
Switches RunAgent dependency from crates.io (0.1.33) to local path.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Config as RunAgentClientConfig
    participant AsyncClient as RunAgentClient (Async)
    participant BlockingClient as RunAgentClient (Blocking)
    participant Runtime as Tokio Runtime
    participant RestClient
    participant SocketClient

    User->>Config: Build with RunAgentClientConfig { agent_id, entrypoint_tag, ... }
    
    rect rgb(200, 230, 255)
    Note over User,SocketClient: Async Path
    User->>AsyncClient: RunAgentClient::new(config).await
    AsyncClient->>RestClient: initialize_architecture()
    RestClient-->>AsyncClient: AgentArchitecture
    AsyncClient->>User: Ready
    User->>AsyncClient: run(&params).await
    AsyncClient->>SocketClient: Send message
    SocketClient->>SocketClient: deserialize_object() with prepare_for_deserialization()
    SocketClient-->>AsyncClient: Value
    AsyncClient-->>User: RunAgentResult<Value>
    end

    rect rgb(200, 255, 230)
    Note over User,Runtime: Blocking Path (New)
    User->>BlockingClient: RunAgentClient::new(config)?
    BlockingClient->>Runtime: Spawn embedded runtime
    BlockingClient->>AsyncClient: Initialize async client
    BlockingClient->>User: Ready
    User->>BlockingClient: run(&params)?
    BlockingClient->>Runtime: Block on async call
    Runtime->>AsyncClient: run().await
    AsyncClient-->>Runtime: Result
    Runtime-->>BlockingClient: Extract result
    BlockingClient-->>User: RunAgentResult<Value>
    end

    rect rgb(255, 240, 200)
    Note over AsyncClient: Error Handling (Enhanced)
    AsyncClient->>AsyncClient: Parse response envelope
    alt success: true
        AsyncClient->>AsyncClient: Extract & deserialize data
    else success: false
        AsyncClient->>AsyncClient: Create RunAgentError::Execution { code, message, suggestion }
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Key areas requiring extra attention:
    • runagent-rust/runagent/src/blocking.rs — New synchronous wrapper with background thread polling and MPSC channel coordination; verify thread safety and lifecycle management
    • runagent-rust/runagent/src/client/runagent_client.rs — Major architectural shift in client initialization (config-driven), architecture resolution, and response payload handling; cross-check deserialization logic paths
    • runagent-rust/runagent/src/utils/config.rs — Removal of file-based persistence; confirm environment-based loading and validation adequately replaces prior behavior
    • runagent-rust/runagent/src/types/errors.rs — New Execution variant integration; verify retryability conditions and error propagation across call sites
    • Response deserialization chains in socket_client.rs, rest_client.rs, and serializer.rs — Multiple payload shape handling and fallback logic; ensure all cases are tested
    • Test/example scripts consistency — 8+ test files updated in parallel; spot-check representative examples for correctness of config pattern

Possibly related PRs

  • fix rust example ui #82 — Modifies examples/lead-agent/backend-rust/src/main.rs around RUNAGENT_ID handling and RunAgent client result parsing; shares direct code-level overlap with this PR's agent backend changes.
  • Sawra/sdk_fix_ts #93 — Modifies rest_client.rs to rework get_agent_architecture with success/data/error envelope parsing; directly related to this PR's response envelope handling.
  • Sawra/util fix #85 — Modifies client response deserialization in runagent_client.rs to handle string-encoded payloads and nested result_data; overlaps with this PR's payload extraction and deserialization enhancements.

Suggested reviewers

  • sawradip

🐰 Hops with glee upon a branch so high,
Configuration blooms where parameters once did fly!
Blocking paths now dance with async grace,
Errors structured, deserialization in place.
From lead-scoring rust to templates anew—
The SDK emerges, redesigned and true! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Latest Rust SDK' is vague and generic, using non-descriptive terminology that fails to convey the specific nature of this substantial changeset involving config-based client initialization, blocking APIs, and argument handling fixes. Consider a more specific title like 'Refactor Rust SDK to use RunAgentClientConfig and add blocking API' to clearly communicate the primary architectural changes and new features being introduced.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch rad/rust_sdk_v2

Tip

📝 Customizable high-level summaries are now available!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide custom instructions to shape the summary (bullet lists, tables, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example:

"Create a concise high-level summary as a bullet-point list. Then include a Markdown table showing lines added and removed by each contributing author."


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
test_scripts/rust/test_agno/Cargo.toml (1)

6-14: Avoid absolute, user-specific path for the runagent dependency

The runagent dependency now points to an absolute path under /home/azureuser/..., which will not resolve on other machines or CI environments:

runagent = { path = "/home/azureuser/runagent/runagent-rust/runagent" }

For shared test scripts, prefer either:

  • A relative path within the repo (e.g., path = "../../../runagent-rust/runagent"), or
  • A versioned crates.io dependency once the new SDK is published.

Also, the comment “from crates.io” is now misleading and should be updated or removed.

test_scripts/rust/test_parlant/src/main.rs (1)

1-36: Critical: Duplicate main function will cause compilation error.

This file defines a main function, but there's another main function at Line 47. Rust programs can only have one entry point. Additionally, imports are duplicated at Line 1 and Line 42.

To fix this issue, either:

  1. Keep only one main function and combine the tests
  2. Convert one example to a separate binary or test case
  3. Comment out one of the main functions (though this is not ideal)

Recommended approach - combine into one main:

 use runagent::{RunAgentClient, RunAgentClientConfig};
 use serde_json::json;
 use futures::StreamExt;

 #[tokio::main]
 async fn main() -> Result<(), Box<dyn std::error::Error>> {
     println!("🧪 Testing Parlant Agent with Rust SDK");
     println!("=======================================");
     
     let agent_id = "9c39620c-c309-4478-a44e-2a45e254a9fb";
     
-    // ============================================
-    // NON-STREAMING TESTS
-    // ============================================
-    
-    // Test 1: Simple Chat
+    // Test 1: Non-Streaming Simple Chat
     println!("\n1️⃣ Testing Simple Chat");
     
     let simple_client = RunAgentClient::new(RunAgentClientConfig {
         agent_id: agent_id.to_string(),
         entrypoint_tag: "parlant_simple".to_string(),
         local: Some(true),
         ..RunAgentClientConfig::default()
     }).await?;
     
     let simple_response = simple_client.run(&[
         ("message", json!("What's the weather like in Paris?"))
     ]).await?;
     
     println!("✅ Simple Chat Response:");
     println!("{}", serde_json::to_string_pretty(&simple_response)?);
     
+    // Test 2: Streaming Chat
+    println!("\n2️⃣ Testing Streaming Chat");
+    println!("{}", "-".repeat(30));
+    
+    let stream_client = RunAgentClient::new(RunAgentClientConfig {
+        agent_id: agent_id.to_string(),
+        entrypoint_tag: "parlant_stream".to_string(),
+        local: Some(true),
+        ..RunAgentClientConfig::default()
+    }).await?;
+
+    let mut stream = stream_client.run_stream(&[
+        ("message", json!("can you tell me the sum of 10 to 20."))
+    ]).await?;
+
+    println!("✅ Streaming Response:");
+    while let Some(chunk_result) = stream.next().await {
+        match chunk_result {
+            Ok(chunk) => {
+                print!("{}", chunk);
+            },
+            Err(e) => {
+                println!("❌ Stream Error: {}", e);
+                break;
+            }
+        }
+    }
     
     Ok(())
 }
-
-
-
-// ############################streaming##################################
-
-use runagent::{RunAgentClient, RunAgentClientConfig};
-use serde_json::json;
-use futures::StreamExt;
-
-#[tokio::main]
-async fn main() -> Result<(), Box<dyn std::error::Error>> {
-    println!("🧪 Testing Parlant Agent with Rust SDK");
-    println!("=======================================");
-    
-    // Replace with the actual agent ID from `runagent serve`
-    let agent_id = "9c39620c-c309-4478-a44e-2a45e254a9fb";
-    
-    // Test 5: Streaming Chat
-    println!("\n5️⃣ Testing Streaming Chat");
-    println!("{}", "-".repeat(30));
-    
-    let stream_client = RunAgentClient::new(RunAgentClientConfig {
-        agent_id: agent_id.to_string(),
-        entrypoint_tag: "parlant_stream".to_string(),
-        local: Some(true),
-        ..RunAgentClientConfig::default()
-    }).await?;
-
-    let mut stream = stream_client.run_stream(&[
-        ("message", json!("can you tell me the sum of 10 to 20."))
-    ]).await?;
-
-    println!("✅ Streaming Response:");
-    while let Some(chunk_result) = stream.next().await {
-        match chunk_result {
-            Ok(chunk) => {
-                print!("{}", chunk);
-            },
-            Err(e) => {
-                println!("❌ Stream Error: {}", e);
-                break;
-            }
-        }
-    }
-    
-    Ok(())
-}
test_scripts/rust/test_crewai/src/main.rs (1)

4-6: Multiple main functions will cause compilation failure—consolidate or split into separate binary targets

The file contains two #[tokio::main] async fn main() functions (lines 4–5 and 40–41), which creates a duplicate entry point error in a single binary crate. Additionally, both main functions configure RunAgentClient with local: Some(true) and no explicit host/port, creating an undocumented dependency on registry/DB lookup for agent resolution.

Options to resolve:

  • Remove or comment out one main function to keep a single entry point
  • Split into separate binary targets (one for non-streaming, one for streaming tests)
  • Add conditional compilation (#[cfg(...)]) to gate one of the functions
  • If keeping both, clarify the registry requirement in documentation or add explicit host/port configuration
test_scripts/rust/test_autogen/src/main.rs (1)

4-6: Remove one main function or split into separate binaries; add host/port to client configs or document registry requirement.

The file contains two #[tokio::main] async fn main() functions (lines 5 and 46) without cfg gating or binary separation in Cargo.toml. This will cause a duplicate main compilation error.

Both client configurations use local: Some(true) but omit host and port (lines 16–21 and 55–60), which requires the agent to be registered in the registry/database for resolution. Either:

  • Add host and port values matching your running AutoGen agent
  • Or document that the db feature must be enabled and the agent must be pre-registered
test_scripts/rust/test_ag2/src/main.rs (1)

4-6: Fix compilation error: two #[tokio::main] functions in single binary crate

The file defines two #[tokio::main] async fn main() functions (lines 4 and 47), which will fail to compile in a single binary crate. Rust allows only one main entry point.

Options to fix:

  • Split into separate binaries with [[bin]] sections in Cargo.toml
  • Gate one with #[cfg(...)] conditional compilation
  • Merge both into a single main function

Additionally, both RunAgentClientConfig instances set local: Some(true) (lines 19 and 55) without explicitly providing host/port. Verify this matches your expected runtime configuration, particularly if the registry/DB lookup path may be unavailable or if you intend to connect to a specific localhost address.

runagent-rust/runagent/src/client/runagent_client.rs (1)

297-338: Architecture initialization validates entrypoint but doesn’t handle missing entrypoints key

initialize_architecture stores the fetched architecture and calls validate_entrypoint, which:

  • Scans architecture["entrypoints"] for the configured tag.
  • Logs available tags and returns a validation error when the tag isn’t found.

However, when entrypoints is missing or not an array, validate_entrypoint silently returns Ok(()). The README suggests ARCHITECTURE_MISSING should be raised when data.entrypoints is missing.

To align behavior with the docs and make misconfigured agents easier to debug, consider adding an explicit check:

  • If entrypoints is absent or not an array, return an appropriate RunAgentError (e.g., Execution with ARCHITECTURE_MISSING or config/validation) rather than silently succeeding.
🧹 Nitpick comments (17)
templates/agno/default/simple_assistant.py (1)

20-31: Update the comment to reflect all checked attributes.

The comment on line 21 mentions .content and .messages attributes but doesn't mention .text, which is also checked on line 27. Consider updating the comment to accurately reflect all fallback paths.

The defensive cascading approach with multiple fallbacks is appropriate for a template, as it handles various response object formats robustly.

Apply this diff to update the comment:

-    # Extract the actual content from the response object
-    # The response object has a .content attribute or .messages attribute
+    # Extract the actual content from the response object
+    # Try in order: .content, .messages[-1].content, .text, or string fallback
     if hasattr(response, 'content'):
sdk_checklist.md (1)

150-150: Move repository hygiene requirements into the Implementation Checklist.

Lines 150 introduces new repository hygiene requirements (README, PUBLISH.md) that logically belong in the "Implementation Checklist (Per New SDK)" section (line 125). This co-locates all per-SDK deliverables in one place and makes it easier for contributors to verify completeness.

runagent-rust/PUBLISH.md (1)

1-49: Rust SDK publishing checklist is clear and actionable

The release steps (version bump, fmt/clippy/test, cargo package, then cargo publish plus tagging) form a solid, reproducible workflow for publishing runagent. This should make future releases much less error‑prone.

If you care about copy style, you could vary the phrasing of the three “Update ...” bullets in the Version Bump section, but that’s purely cosmetic.

examples/lead-agent/backend-rust/src/main.rs (2)

11-15: Importing RunAgentClientConfig and updating RUNAGENT_ID is fine; consider configurability

Bringing in RunAgentClientConfig matches the new SDK API, and the updated RUNAGENT_ID is straightforward. For a production deployment, you might eventually want to source the agent ID from configuration or environment rather than a hard‑coded constant, but this is acceptable for an example backend.


150-192: run() usage and payload unwrapping logic are robust

Switching to client.run(&params).await aligns with the updated SDK, and the follow‑up logic to:

  • log the raw result,
  • extract a "payload" field when present, and
  • fall back to parsing stringified JSON,

is defensive without risking panics—parse failures just return the original result. This should handle both structured and string‑wrapped responses gracefully.

runagent-rust/runagent/src/types/errors.rs (2)

3-49: Execution error variant and constructor look solid; consider loosening the generic constraint

The new Execution variant with structured code, message, suggestion, and details: Option<Value> is a good extension point and the display format is clear. The execution constructor is fine, but using a single S: Into<String> for both code and message forces them to be the same type; it can be more ergonomic to allow different types (e.g., &'static str for code and String for message).

You could simplify call‑sites by changing the signature to something like separate generics or impl Into<String> per parameter so callers can freely mix &str and String.

Also applies to: 125-138


147-172: Retryability semantics for Execution errors are clear and narrowly scoped

Extending category() with "execution" and treating only Execution errors with codes "CONNECTION_ERROR" or "SERVER_ERROR" as retryable keeps the behavior predictable and backward compatible with existing variants. This is a reasonable design, especially if these codes map to server-defined semantics.

It might be worth adding unit tests specifically for Execution (category, Display, and is_retryable) to prevent regressions as new codes are introduced.

runagent-rust/runagent/src/utils/config.rs (2)

39-59: Env-based load and base_url normalization are reasonable; be explicit about expected input shape

Loading api_key and base_url from ENV_RUNAGENT_API_KEY / ENV_RUNAGENT_BASE_URL and auto‑prefixing non‑http(s) URLs with https:// is a sensible default and should reduce misconfigurations. One thing to consider is documenting (in crate docs or README) that bare hosts like api.example.com will be treated as https://api.example.com, so users aren’t surprised by implicit TLS.

The comment about “stored in SQLite” is forward-looking; if configuration isn’t actually persisted to SQLite yet, clarifying that this function only reads from env (and that DB integration lives elsewhere) would avoid confusion.


62-97: setup behavior is clear but _save being ignored and auth being a stub should be documented

The updated setup path—merging env‑derived config with optional api_key/base_url, enforcing presence of an API key, and normalizing the base URL—looks fine. However:

  • _save is intentionally ignored; callers expecting persistence may be surprised.
  • test_authentication is currently a stub that returns Ok(true) whenever an API key is set, so the Authentication error branch is effectively unreachable for now.

Explicitly documenting in the public API (doc comments or higher-level docs) that setup does not persist to disk and that authentication checks are placeholders will set more accurate expectations until the SQLite-backed implementation is wired in.

runagent-rust/runagent/examples/test_deserialize.rs (1)

4-17: Consider using ? operator for consistency with other examples.

While unwrap() is acceptable in example code, using the ? operator would be more consistent with the error handling patterns shown in other examples and demonstrate best practices.

-fn main() {
-    let serializer = CoreSerializer::new(10.0).unwrap();
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    let serializer = CoreSerializer::new(10.0)?;
     
     // Test the exact structure we're getting
     let test_response = json!({
         "payload": "\"Hello, world!\"",
         "type": "string"
     });
     
     println!("Input: {}", test_response);
-    let result = serializer.deserialize_object(test_response).unwrap();
+    let result = serializer.deserialize_object(test_response)?;
     println!("Result: {}", result);
     println!("Result is string: {}", result.is_string());
+    Ok(())
 }
test_scripts/rust/test_agno/src/main.rs (1)

1-62: Consider: Cleanup commented-out code.

The file contains extensive commented-out examples showing different usage patterns (sync/async, streaming/non-streaming). While these may serve as reference, consider:

  • Moving them to separate example files
  • Adding them to documentation
  • Removing if no longer needed

This would improve maintainability.

runagent-rust/runagent/src/utils/serializer.rs (1)

59-99: Clarify string payload handling and add targeted tests

The extended deserialize_object logic for {type, payload} and string responses is reasonable, but a couple of points are worth tightening up:

  • For {type, payload} where payload is a JSON string, you return the parsed Value directly rather than feeding it through reconstruct_nested_json. If those payloads can themselves be serialized {strategy, content} wrappers, you may want to run the parsed value through reconstruct_nested_json to keep behavior consistent with the non-string payload path.
  • There are no tests covering:
    • {type, payload} with string vs non-string payload,
    • top-level string JSON (both valid JSON and non-JSON),
    • legacy {content} structures when wrapped inside {type, payload}.

Consider adding small unit tests for these shapes and, if needed, routing the parsed string payload through reconstruct_nested_json for full symmetry with other paths.

runagent-rust/runagent/src/lib.rs (1)

258-279: Blocking module docs vs exports: confirm RunAgentClientConfig re-export

The new blocking wrapper and exports look good overall (pub mod blocking; plus pub use blocking::{RunAgentClient as BlockingRunAgentClient, BlockingStream};), but the example in the blocking docs uses:

use runagent::blocking::{RunAgentClient, RunAgentClientConfig};

For that to compile, the blocking module needs to publicly re-export RunAgentClientConfig (e.g., pub use crate::client::RunAgentClientConfig;). If RunAgentClientConfig is only exported from the crate root, it would be clearer either to:

  • Re-export RunAgentClientConfig from runagent::blocking, or
  • Change the example to use runagent::{BlockingRunAgentClient as RunAgentClient, RunAgentClientConfig};.

Worth confirming the actual exports in blocking.rs and aligning the example with them.

Also applies to: 282-287

runagent-rust/runagent/src/constants.rs (1)

1-22: Align timeout constant and reuse API prefix where possible

DEFAULT_TIMEOUT_SECONDS is documented as the default execution timeout (5 minutes, value 300), but the HTTP client and WebSocket stream both hardcode 600 seconds. This mismatch can confuse users and future maintainers.

Consider either:

  • Updating DEFAULT_TIMEOUT_SECONDS to 600 and using it in RestClient/WebSocket payloads, or
  • Adjusting the docs/name to match current behavior.

Similarly, DEFAULT_API_PREFIX could be used instead of repeated "/api/v1" literals in client constructors to keep things in sync.

runagent-rust/runagent/README.md (1)

278-287: Double‑check that documented troubleshooting codes are actually emitted

The troubleshooting table relies on specific codes (STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT, AGENT_NOT_FOUND_LOCAL/REMOTE, AUTHENTICATION_ERROR, ARCHITECTURE_MISSING). Some of these depend on server responses or helper mapping in lower-level clients.

It would be good to confirm that every code listed here is actually produced by the current Rust client + backend paths; otherwise, consider pruning or annotating entries that are not yet wired up to avoid confusing users.

runagent-rust/runagent/src/client/runagent_client.rs (2)

31-115: Config struct is well‑designed; consider implementing Default trait

RunAgentClientConfig cleanly centralizes all construction options and the builder methods (with_local, with_address, with_api_key, etc.) make typical flows ergonomic.

You currently provide a pub fn default() -> Self associated function mainly to support ..RunAgentClientConfig::default() in examples. Implementing the standard Default trait instead (and keeping a default() inherent method only if you really need it) would integrate better with Rust conventions and tooling, while preserving the same usage pattern via RunAgentClientConfig::default().

Not urgent, but worth considering as this type is now the primary entry point for the SDK.


543-563: Remote client creation: reuse constants and clarify scheme fallback

create_remote_clients does the right thing in general:

  • Uses RestClient::new(base_url, api_key, Some("/api/v1")).
  • Derives the WebSocket base URL from the HTTP base (https://wss://, http://ws://, else wss://{base_url}).
  • Falls back to RestClient::default() / SocketClient::default() when no override is provided.

Two minor improvements:

  1. Reuse DEFAULT_API_PREFIX here instead of the "/api/v1" literal to keep everything in sync with constants.rs.
  2. Consider whether the default of wss://{base_url} for scheme‑less URLs is what you want (vs. ws://). If this is intentional, maybe add a short doc comment stating that scheme‑less base URLs are treated as secure by default.

These are small but make the behavior more explicit and maintainable.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 242a84a and 735e86a.

📒 Files selected for processing (38)
  • examples/lead-agent/backend-rust/src/main.rs (5 hunks)
  • examples/lead-agent/lead-score-flow/runagent.config.json (1 hunks)
  • runagent-rust/PUBLISH.md (1 hunks)
  • runagent-rust/examples/async_example.rs (1 hunks)
  • runagent-rust/examples/direct_construction.rs (1 hunks)
  • runagent-rust/examples/sync_example.rs (1 hunks)
  • runagent-rust/runagent/Cargo.toml (1 hunks)
  • runagent-rust/runagent/README.md (1 hunks)
  • runagent-rust/runagent/examples/async_example.rs (1 hunks)
  • runagent-rust/runagent/examples/direct_construction.rs (1 hunks)
  • runagent-rust/runagent/examples/direct_construction_omitted.rs (1 hunks)
  • runagent-rust/runagent/examples/sync_example.rs (1 hunks)
  • runagent-rust/runagent/examples/test_deserialize.rs (1 hunks)
  • runagent-rust/runagent/src/blocking.rs (1 hunks)
  • runagent-rust/runagent/src/client/mod.rs (1 hunks)
  • runagent-rust/runagent/src/client/rest_client.rs (1 hunks)
  • runagent-rust/runagent/src/client/runagent_client.rs (5 hunks)
  • runagent-rust/runagent/src/client/socket_client.rs (2 hunks)
  • runagent-rust/runagent/src/constants.rs (1 hunks)
  • runagent-rust/runagent/src/db/service.rs (1 hunks)
  • runagent-rust/runagent/src/lib.rs (8 hunks)
  • runagent-rust/runagent/src/types/errors.rs (5 hunks)
  • runagent-rust/runagent/src/types/schema.rs (2 hunks)
  • runagent-rust/runagent/src/utils/config.rs (4 hunks)
  • runagent-rust/runagent/src/utils/serializer.rs (1 hunks)
  • sdk_checklist.md (2 hunks)
  • templates/agno/default/runagent.config.json (2 hunks)
  • templates/agno/default/simple_assistant.py (1 hunks)
  • test_scripts/python/client_test_agno.py (1 hunks)
  • test_scripts/rust/test_ag2/src/main.rs (4 hunks)
  • test_scripts/rust/test_agno/Cargo.toml (1 hunks)
  • test_scripts/rust/test_agno/src/main.rs (1 hunks)
  • test_scripts/rust/test_autogen/src/main.rs (4 hunks)
  • test_scripts/rust/test_crewai/src/main.rs (4 hunks)
  • test_scripts/rust/test_langchain/src/main.rs (2 hunks)
  • test_scripts/rust/test_langgraph/src/main.rs (2 hunks)
  • test_scripts/rust/test_letta/src/main.rs (2 hunks)
  • test_scripts/rust/test_parlant/src/main.rs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (23)
runagent-rust/runagent/src/client/socket_client.rs (2)
runagent-rust/runagent/src/utils/serializer.rs (2)
  • prepare_for_deserialization (38-48)
  • deserialize_object (58-100)
runagent-rust/runagent/src/types/errors.rs (1)
  • server (91-95)
runagent-rust/examples/direct_construction.rs (1)
runagent-rust/runagent/src/client/runagent_client.rs (2)
  • new (97-109)
  • new (194-295)
runagent-rust/runagent/examples/sync_example.rs (3)
runagent-rust/examples/async_example.rs (1)
  • main (9-26)
runagent-rust/runagent/src/blocking.rs (4)
  • agent_id (136-138)
  • entrypoint_tag (141-143)
  • new (50-57)
  • new (190-217)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • agent_id (523-525)
  • entrypoint_tag (528-530)
  • new (97-109)
  • new (194-295)
runagent-rust/examples/async_example.rs (3)
runagent-rust/examples/direct_construction.rs (1)
  • main (9-27)
runagent-rust/examples/sync_example.rs (1)
  • main (9-26)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • agent_id (523-525)
  • entrypoint_tag (528-530)
  • new (97-109)
  • new (194-295)
runagent-rust/runagent/examples/direct_construction_omitted.rs (2)
runagent-rust/runagent/examples/direct_construction.rs (1)
  • main (9-27)
runagent-rust/runagent/src/client/runagent_client.rs (3)
  • new (97-109)
  • new (194-295)
  • default (115-127)
runagent-rust/runagent/examples/test_deserialize.rs (1)
runagent-rust/runagent/src/utils/serializer.rs (4)
  • serde_json (41-41)
  • serde_json (68-68)
  • serde_json (92-92)
  • new (15-19)
test_scripts/rust/test_langchain/src/main.rs (1)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • new (97-109)
  • new (194-295)
  • agent_id (523-525)
  • default (115-127)
test_scripts/rust/test_letta/src/main.rs (2)
runagent-rust/runagent/src/blocking.rs (3)
  • new (50-57)
  • new (190-217)
  • agent_id (136-138)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • new (97-109)
  • new (194-295)
  • agent_id (523-525)
  • default (115-127)
runagent-rust/runagent/src/types/errors.rs (4)
examples/lead-agent/backend-rust/src/main.rs (3)
  • serde_json (161-161)
  • serde_json (168-168)
  • serde_json (175-175)
runagent-rust/runagent/src/client/rest_client.rs (1)
  • serde_json (71-71)
runagent-rust/runagent/src/utils/serializer.rs (3)
  • serde_json (41-41)
  • serde_json (68-68)
  • serde_json (92-92)
runagent-rust/runagent/src/types/responses.rs (1)
  • error (27-35)
examples/lead-agent/backend-rust/src/main.rs (1)
runagent-rust/runagent/src/client/runagent_client.rs (3)
  • new (97-109)
  • new (194-295)
  • default (115-127)
test_scripts/rust/test_langgraph/src/main.rs (2)
runagent-rust/runagent/src/blocking.rs (3)
  • new (50-57)
  • new (190-217)
  • agent_id (136-138)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • new (97-109)
  • new (194-295)
  • agent_id (523-525)
  • default (115-127)
runagent-rust/runagent/src/client/rest_client.rs (3)
runagent-rust/runagent/src/types/errors.rs (2)
  • validation (77-81)
  • execution (126-138)
runagent-rust/runagent/src/utils/config.rs (1)
  • base_url (135-137)
runagent-rust/runagent/src/types/responses.rs (1)
  • success (17-25)
test_scripts/rust/test_ag2/src/main.rs (2)
runagent-rust/runagent/src/blocking.rs (3)
  • new (50-57)
  • new (190-217)
  • agent_id (136-138)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • new (97-109)
  • new (194-295)
  • agent_id (523-525)
  • default (115-127)
test_scripts/rust/test_agno/src/main.rs (2)
runagent-rust/runagent/src/blocking.rs (2)
  • new (50-57)
  • new (190-217)
runagent-rust/runagent/src/client/runagent_client.rs (3)
  • new (97-109)
  • new (194-295)
  • default (115-127)
runagent-rust/runagent/src/blocking.rs (3)
runagent-rust/runagent/src/client/runagent_client.rs (12)
  • new (97-109)
  • new (194-295)
  • run (341-343)
  • run_with_args (346-477)
  • run_stream (480-485)
  • run_stream_with_args (488-507)
  • get_agent_architecture (510-512)
  • health_check (515-520)
  • agent_id (523-525)
  • entrypoint_tag (528-530)
  • extra_params (533-535)
  • is_local (538-540)
runagent-rust/runagent/src/client/socket_client.rs (2)
  • new (25-38)
  • run_stream (71-181)
runagent-rust/runagent/src/types/errors.rs (1)
  • connection (84-88)
test_scripts/rust/test_parlant/src/main.rs (2)
runagent-rust/runagent/src/blocking.rs (3)
  • new (50-57)
  • new (190-217)
  • agent_id (136-138)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • new (97-109)
  • new (194-295)
  • agent_id (523-525)
  • default (115-127)
runagent-rust/runagent/src/utils/config.rs (3)
runagent-rust/runagent/src/types/errors.rs (1)
  • config (119-123)
runagent-rust/runagent/src/client/rest_client.rs (1)
  • default (44-51)
runagent-rust/runagent/src/client/socket_client.rs (1)
  • default (41-55)
test_scripts/rust/test_crewai/src/main.rs (2)
runagent-rust/runagent/src/blocking.rs (3)
  • new (50-57)
  • new (190-217)
  • agent_id (136-138)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • new (97-109)
  • new (194-295)
  • agent_id (523-525)
  • default (115-127)
runagent-rust/runagent/examples/direct_construction.rs (1)
runagent-rust/runagent/src/client/runagent_client.rs (2)
  • new (97-109)
  • new (194-295)
runagent-rust/examples/sync_example.rs (2)
runagent-rust/examples/async_example.rs (1)
  • main (9-26)
runagent-rust/runagent/src/blocking.rs (4)
  • agent_id (136-138)
  • entrypoint_tag (141-143)
  • new (50-57)
  • new (190-217)
runagent-rust/runagent/examples/async_example.rs (2)
runagent-rust/examples/async_example.rs (1)
  • main (9-26)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • agent_id (523-525)
  • entrypoint_tag (528-530)
  • new (97-109)
  • new (194-295)
test_scripts/rust/test_autogen/src/main.rs (2)
runagent-rust/runagent/src/blocking.rs (3)
  • new (50-57)
  • new (190-217)
  • agent_id (136-138)
runagent-rust/runagent/src/client/runagent_client.rs (4)
  • new (97-109)
  • new (194-295)
  • agent_id (523-525)
  • default (115-127)
runagent-rust/runagent/src/client/runagent_client.rs (7)
runagent-rust/runagent/src/blocking.rs (2)
  • new (50-57)
  • new (190-217)
runagent-rust/runagent/src/lib.rs (3)
  • new (349-351)
  • with_api_key (365-368)
  • with_base_url (382-385)
runagent-rust/runagent/src/client/rest_client.rs (2)
  • new (21-41)
  • default (44-51)
runagent-rust/runagent/src/client/socket_client.rs (2)
  • new (25-38)
  • default (41-55)
runagent-rust/runagent/src/utils/serializer.rs (1)
  • new (15-19)
runagent-rust/runagent/src/utils/config.rs (3)
  • default (26-36)
  • api_key (130-132)
  • base_url (135-137)
runagent-rust/runagent/src/types/errors.rs (2)
  • config (119-123)
  • validation (77-81)
🪛 LanguageTool
runagent-rust/PUBLISH.md

[style] ~15-~15: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...t/Cargo.toml(workspace) if needed. 3. Update the version badge/examples inrunagent...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (39)
templates/agno/default/simple_assistant.py (1)

33-39: LGTM!

The streaming function correctly yields serializable dictionaries with extracted content. The defensive attribute checking is consistent with the non-streaming version and appropriate for a template.

runagent-rust/runagent/Cargo.toml (1)

3-3: Version bump looks consistent with the Rust SDK changes

Incrementing the crate version to 0.1.34 aligns with the new public API surface introduced in this PR.

runagent-rust/runagent/src/types/schema.rs (1)

8-8: Home‑based default DB path is a reasonable improvement

Deriving the SQLite file path from the user’s home directory (~/.runagent/runagent_local.db) instead of a fixed relative path makes the default more stable across working directories. The fallback to . when no home dir is found is also a sensible safe default.

No issues from this change on its own.

Also applies to: 283-290

examples/lead-agent/backend-rust/src/main.rs (3)

111-117: Config‑based remote client initialization looks correct

Using RunAgentClient::new(RunAgentClientConfig { agent_id: RUNAGENT_ID.to_string(), entrypoint_tag: "lead_score_flow".to_string(), local: Some(false), ..RunAgentClientConfig::default() }) cleanly adopts the new constructor and relies on RUNAGENT_API_KEY for credentials as intended for cloud usage. Error handling on initialization is appropriate.


221-227: Local client initialization via RunAgentClientConfig is consistent

For score_single, constructing the client with local: Some(true) and otherwise relying on RunAgentClientConfig::default() matches the intended local‑agent flow and mirrors the remote setup above. Initialization errors are correctly surfaced as 500 responses.


260-272: Updated run() call in score_single preserves behavior

Changing to client.run(&params).await while keeping the existing 500‑on‑error behavior maintains semantics with the new SDK API. Returning result directly as JSON is appropriate here since the single‑candidate scoring endpoint can expose the SDK’s response format as‑is.

examples/lead-agent/lead-score-flow/runagent.config.json (1)

1-31: Agent ID change is structurally fine; ensure it matches the deployed agent

Only agent_id was updated, with the rest of the config unchanged. From a schema/format perspective this is fine; just double‑check that this UUID corresponds to the intended deployed agent for the lead-score flow so the example targets the right backend.

runagent-rust/examples/sync_example.rs (1)

1-27: LGTM! Clear synchronous example.

The blocking API example is well-structured and demonstrates the config-based initialization pattern effectively. The hardcoded agent_id and local address are appropriate for an example file.

runagent-rust/runagent/src/client/mod.rs (1)

8-8: LGTM! API surface extended appropriately.

The re-export of RunAgentClientConfig alongside RunAgentClient is necessary for the config-driven initialization pattern introduced in this PR.

runagent-rust/runagent/examples/async_example.rs (1)

1-27: LGTM! Well-structured async example.

The async example properly demonstrates the recommended usage pattern with tokio. The structure and documentation are clear and consistent with the synchronous variant.

runagent-rust/examples/async_example.rs (1)

1-27: LGTM! Consistent async example.

The example is well-structured and demonstrates the async API usage clearly. The code is consistent with the other examples in the PR.

runagent-rust/runagent/src/db/service.rs (3)

46-48: LGTM! Environment-driven configuration.

The use of LOCAL_CACHE_DIRECTORY for default path resolution is a good improvement, allowing users to customize the cache location via environment variable while maintaining a sensible default.


50-54: LGTM! Proper directory creation with error handling.

The code correctly ensures the parent directory exists before attempting database operations, with appropriate error context.


22-24: Original deprecation claim is incorrect; dirs::home_dir() is not deprecated.

The dirs crate is actively maintained with releases continuing through version 6.0.0, and home_dir() is documented and present in the API. The confusion may stem from std::env::home_dir() (Rust stdlib), which is deprecated, but dirs::home_dir() is a separate, actively maintained function.

The current implementation using dirs::home_dir() with version 5.0 is appropriate and not subject to deprecation concerns.

Likely an incorrect or invalid review comment.

runagent-rust/runagent/src/client/socket_client.rs (2)

103-104: LGTM: Serializer clone for async stream.

Cloning the serializer for use in the async stream is the correct approach, as the stream closure needs ownership of the serializer to handle message deserialization.


135-151: Excellent: Unified deserialization logic.

The enhanced deserialization logic correctly uses the common CoreSerializer methods (prepare_for_deserialization and deserialize_object) to handle various payload formats including {type, payload} structures and JSON-encoded strings. Error handling is appropriate with descriptive messages and stream termination on failure.

runagent-rust/runagent/examples/sync_example.rs (1)

1-26: LGTM: Clear blocking API example.

The synchronous example demonstrates the blocking API usage well with appropriate configuration for local agent execution. The builder pattern and comments make it easy to understand.

test_scripts/rust/test_agno/src/main.rs (1)

66-81: LGTM: Config-based construction is correct.

The active example correctly demonstrates the new RunAgentClientConfig-based construction pattern with struct literal syntax and ..RunAgentClientConfig::default() for unspecified fields.

test_scripts/rust/test_letta/src/main.rs (1)

51-78: LGTM: Streaming example with config-based construction.

The streaming example correctly uses RunAgentClientConfig and demonstrates proper stream processing with error handling. The pattern is consistent with the broader SDK migration.

test_scripts/rust/test_langgraph/src/main.rs (1)

36-56: LGTM: Config-based construction with complex inputs.

The example correctly demonstrates the new config pattern and showcases the SDK's ability to handle complex nested JSON structures as input parameters.

runagent-rust/runagent/src/client/rest_client.rs (3)

223-235: Excellent: Enhanced diagnostic logging and error messages.

The added logging and enhanced error messages with URL context will significantly improve debugging when agents are not found. The error message provides actionable guidance to users.


237-248: Good: Structured error handling for missing data.

The logic correctly returns data on success and provides a helpful Execution error with remediation suggestions when data is unexpectedly missing. The inclusion of the full response in error details aids debugging.


250-290: Excellent: Comprehensive error parsing with fallbacks.

The error parsing logic robustly handles multiple response formats:

  • Structured error objects with code/message/suggestion
  • Plain string errors
  • Fallback to message field
  • Backward compatibility with responses lacking success field

This provides a much better error experience with actionable information.

test_scripts/rust/test_langchain/src/main.rs (1)

56-80: LGTM: Streaming example with proper config pattern.

The streaming example correctly uses RunAgentClientConfig with the struct literal initialization pattern. Stream processing and error handling follow best practices.

test_scripts/rust/test_parlant/src/main.rs (2)

20-25: Config pattern is correct.

The RunAgentClientConfig construction uses the correct struct literal pattern with defaults. This code would work fine once the duplicate main function issue is resolved.


58-63: Consistent config pattern.

The second RunAgentClientConfig usage follows the same correct pattern as the first, demonstrating consistent usage across streaming and non-streaming scenarios.

runagent-rust/runagent/src/utils/serializer.rs (1)

33-48: Helper for pre-parsing JSON strings looks good

The prepare_for_deserialization helper cleanly handles JSON-encoded strings vs already-parsed values without altering error behavior, which is appropriate for a preprocessing step.

test_scripts/rust/test_ag2/src/main.rs (1)

16-21: Config-based client construction and run/run_stream usage look consistent

The switch to RunAgentClient::new(RunAgentClientConfig { ... }).await? with run / run_stream taking a slice of (key, json!(...)) arguments aligns with the new API and keeps the non-streaming and streaming paths consistent.

Also applies to: 52-57, 24-29, 59-72

test_scripts/rust/test_crewai/src/main.rs (1)

16-21: CrewAI config usage and argument wiring match the new API

The migration to RunAgentClient::new(RunAgentClientConfig { ... }).await? and using run / run_stream with the expected topic argument slice looks correct and matches the updated client interface.

Also applies to: 24-26, 52-57, 59-74

test_scripts/rust/test_autogen/src/main.rs (1)

16-21: AutoGen non-streaming and streaming paths use the new API correctly

The client construction via RunAgentClientConfig and the run / run_stream calls with a single task argument slice are consistent with the updated RunAgentClient API and keep the examples aligned across non-streaming and streaming tests.

Also applies to: 24-26, 55-60, 62-77

runagent-rust/runagent/src/lib.rs (2)

18-32: Docs now consistently reflect the config-based client API

All the updated examples (basic, streaming, local, LangChain, LangGraph) now import RunAgentClient and RunAgentClientConfig from the crate root and construct clients via RunAgentClient::new(RunAgentClientConfig { ... }).await?, which matches the new public API and should help keep users on the correct pattern.

Also applies to: 48-60, 81-94, 110-120, 139-150


281-283: Re-exporting RunAgentClientConfig at the root and in the prelude is helpful

Including RunAgentClientConfig in both the top-level re-export set and the prelude module makes the new configuration-based API easy to access and keeps the high-level ergonomics intact.

Also applies to: 437-438

runagent-rust/runagent/README.md (1)

247-275: API reference and error-handling description look consistent with the new surface

The API reference tables for client creation, configuration builder, and client methods correctly mirror the current public surface (RunAgentClient::new(config), builder methods, run*, run_stream*, health_check, get_agent_architecture) and the RunAgentError::Execution { .. } variant description aligns with the overall error model introduced elsewhere.

Nice concise summary of the SDK surface.

runagent-rust/runagent/src/blocking.rs (2)

41-75: Blocking wrapper design is generally sound and mirrors async API

The blocking RunAgentClient wrapper cleanly delegates to the async client via Runtime::new() and block_on, exposing a synchronous surface (run, run_with_args, run_stream*, health_check, get_agent_architecture) that matches the async API. This is a reasonable approach for users who can’t or don’t want to adopt async in their apps.


220-226: Iterator implementation is straightforward and matches the blocking contract

The Iterator impl for BlockingStream that simply does self.receiver.recv().ok() is simple and correct for a blocking interface; it will yield items until the sender closes and then terminate cleanly.

Looks good.

runagent-rust/runagent/src/client/runagent_client.rs (4)

167-276: Client construction and local/remote resolution look correct

The new RunAgentClient::new(config):

  • Correctly derives local and enable_registry from the config.
  • Resolves host/port for local agents, using the DB when available and enable_registry is true, with clear validation errors when host/port are still missing.
  • Resolves API key and base URL with the expected precedence: config > env vars (RUNAGENT_API_KEY, RUNAGENT_BASE_URL) > DEFAULT_BASE_URL.
  • Logs useful information about remote connections and presence/absence of an API key.
  • Creates REST and socket clients with appropriate HTTP/WS URLs in both local and remote modes.

The db_service field being always initialized as None and marked #[allow(dead_code)] is fine for now given it’s reserved for future use.


340-476: Robust response handling and streaming‑generator detection in run_with_args

The new run_with_args logic is quite thorough:

  • It enforces non‑streaming usage for _stream entrypoints.
  • Handles multiple response shapes (data as string, data.result_data.data, object payloads, and legacy output_data), with generator detection at each level.
  • Uses the shared CoreSerializer for {type, payload} structures and applies a size cap.
  • Provides clear validation messages suggesting run_stream when a generator object is detected.

This should make the client resilient across backend evolutions and helps guide users toward the correct streaming API.

Looks solid.


493-507: Local guardrail for non‑stream entrypoints is consistent with README

The _stream suffix check in run_stream_with_args:

if !self.entrypoint_tag.ends_with("_stream") {
    return Err(RunAgentError::validation(
        "Use run() for non-stream entrypoints".to_string(),
    ));
}

correctly prevents accidental misuse of streaming APIs with non‑stream entrypoints and matches the guardrails described in the README.

Nice clear error path.


532-541: extra_params accessor is fine; ensure callers know it’s optional/opaque

Exposing extra_params(&self) -> Option<&HashMap<String, Value>> is straightforward and keeps this field flexible for future use. Just ensure callers treat it as opaque metadata for now (as suggested by the docs) to avoid tight coupling to unstable semantics.

No changes needed.

Comment on lines +1 to +27
//! Example showing direct struct construction (TypeScript-like interface)
//!
//! This matches the TypeScript SDK pattern where you pass a config object directly.

use runagent::RunAgentClient;
use serde_json::json;

#[tokio::main]
async fn main() -> runagent::RunAgentResult<()> {
// Direct struct construction - matches TypeScript interface
let client = RunAgentClient::new(runagent::RunAgentClientConfig {
agent_id: "a6977384-6c88-40dc-a629-e6bf077786ae".to_string(),
entrypoint_tag: "minimal".to_string(),
api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
base_url: Some("http://localhost:8333/".to_string()),
local: None,
host: None,
port: None,
extra_params: None,
enable_registry: None,
}).await?;

let response = client.run(&[("message", json!("Hello!"))]).await?;

println!("Response: {}", response);
Ok(())
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove hard-coded API key from the example to avoid secret exposure

This example currently embeds a full api_key literal:

api_key: Some("rau_...".to_string()),

Committing anything that looks like a real API key (even if test-only) is risky and will train users into copying the pattern. It’s safer to:

  • Read the key from an environment variable (e.g., std::env::var(ENV_RUNAGENT_API_KEY)) or
  • Use a placeholder like None / "YOUR_API_KEY_HERE".to_string() and explain in comments how to configure it.

I’d strongly recommend stripping or rotating any real key before merging.

🤖 Prompt for AI Agents
In runagent-rust/examples/direct_construction.rs around lines 1 to 27, remove
the hard-coded api_key literal and replace it with a non-secret pattern: read
the API key from an environment variable (e.g.,
std::env::var("RUNAGENT_API_KEY")) and pass that value as Some(key) if present,
or use None / a clear placeholder like "YOUR_API_KEY_HERE" when not set; ensure
you handle the Result from env::var (map to Option) or fall back safely so the
example compiles and does not expose secrets.

Comment on lines +14 to +15
api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
base_url: Some("http://localhost:8333/".to_string()),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove hardcoded credentials from examples.

Hardcoded API keys and base URLs in example code can be accidentally copied into production. Even if these are test credentials, examples should demonstrate secure practices.

Consider one of these approaches:

-        api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
-        base_url: Some("http://localhost:8333/".to_string()),
+        api_key: std::env::var("RUNAGENT_API_KEY").ok(),
+        base_url: std::env::var("RUNAGENT_BASE_URL").ok(),

Or use placeholder comments:

-        api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
-        base_url: Some("http://localhost:8333/".to_string()),
+        api_key: None, // Or std::env::var("RUNAGENT_API_KEY").ok()
+        base_url: None, // Or Some("http://localhost:8333/".to_string()) for local testing
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
base_url: Some("http://localhost:8333/".to_string()),
api_key: std::env::var("RUNAGENT_API_KEY").ok(),
base_url: std::env::var("RUNAGENT_BASE_URL").ok(),
🤖 Prompt for AI Agents
In runagent-rust/runagent/examples/direct_construction_omitted.rs around lines
14 to 15, the example contains hardcoded API key and base URL; remove those
literals and replace them with secure placeholders or runtime configuration
(e.g., read from environment variables like RAGENT_API_KEY and RAGENT_BASE_URL
with a clear placeholder fallback or unwrap_or_else that prompts the user),
update the example to show how to obtain values securely (document the env var
names in a comment) and ensure no secrets are committed in the example code.

Comment on lines +14 to +15
api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
base_url: Some("http://localhost:8333/".to_string()),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove hardcoded credentials from examples.

Same issue as in direct_construction_omitted.rs. Hardcoded API keys in examples can be accidentally copied into production code.

Use environment variables or placeholder comments instead:

-        api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
-        base_url: Some("http://localhost:8333/".to_string()),
+        api_key: std::env::var("RUNAGENT_API_KEY").ok(),
+        base_url: std::env::var("RUNAGENT_BASE_URL").ok(),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
api_key: Some("rau_b4dcebdef6386726b08971a1cc968d8a2b77c5834d30f3f5a43bddf065cd95cb".to_string()),
base_url: Some("http://localhost:8333/".to_string()),
api_key: std::env::var("RUNAGENT_API_KEY").ok(),
base_url: std::env::var("RUNAGENT_BASE_URL").ok(),
🤖 Prompt for AI Agents
In runagent-rust/runagent/examples/direct_construction.rs around lines 14 to 15,
remove the hardcoded API key and any production-like base_url from the example;
replace them with either environment variable reads (e.g., fetch from
std::env::var) or clear placeholder strings and a comment guiding users to set
REAL_API_KEY and REAL_BASE_URL in their environment/config before running.
Ensure the example compiles with placeholders (e.g., Option::None or placeholder
text) and add a brief comment above showing how to export the env vars so
credentials are not embedded in source.

Comment on lines +31 to 47
```rust
use runagent::RunAgentClientConfig;

**Important:** You must export your API key before running your application:
// Local agent with explicit address
let client = RunAgentClient::new(
RunAgentClientConfig::new("agent-id", "entrypoint")
.with_local(true)
.with_address("127.0.0.1", 8450)
.with_enable_registry(false)
).await?;

```bash
export RUNAGENT_API_KEY="your-api-key"
// Remote agent
let client = RunAgentClient::new(
RunAgentClientConfig::new("agent-id", "entrypoint")
.with_api_key(env::var("RUNAGENT_API_KEY").unwrap())
).await?;
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Config overview snippet is missing the RunAgentClient import

In the configuration overview example you use RunAgentClient::new(...) but only import RunAgentClientConfig:

use runagent::RunAgentClientConfig;
// ...
let client = RunAgentClient::new(/* ... */).await?;

Add RunAgentClient to the use line so the snippet compiles as shown:

use runagent::{RunAgentClient, RunAgentClientConfig};
🤖 Prompt for AI Agents
In runagent-rust/runagent/README.md around lines 31 to 47, the example uses
RunAgentClient::new but only imports RunAgentClientConfig; update the use
statement to import both types so the snippet compiles (i.e., add RunAgentClient
to the use line alongside RunAgentClientConfig).

Comment on lines +185 to +215
### Local Agents

For local development, you can configure cache and logging:
#### With explicit address

```bash
export RUNAGENT_CACHE_DIR="~/.runagent"
export RUNAGENT_LOGGING_LEVEL="info"
```rust
use runagent::{RunAgentClient, RunAgentClientConfig};

let client = RunAgentClient::new(RunAgentClientConfig {
agent_id: "local-agent-id".to_string(),
entrypoint_tag: "minimal".to_string(),
local: Some(true),
host: Some("127.0.0.1".to_string()),
port: Some(8452),
enable_registry: Some(false), // Skip DB lookup
..RunAgentClientConfig::default()
}).await?;
```

### Quick Reference

| Setting | RunAgent Cloud | Local Development |
|---------|---------------|-------------------|
| **API Key** | **Required** (`RUNAGENT_API_KEY`) | Not needed |
| **Base URL** | Optional (defaults to `https://api.runagent.ai`) | Not needed |
| **Client Parameter** | `local = false` | `local = true` |
| **Agent Location** | RunAgent infrastructure | Your local machine |

### Configuration Builder

You can also configure the SDK programmatically:
#### With auto-discovery (requires `db` feature)

```rust
use runagent::RunAgentConfig;

let config = RunAgentConfig::new()
.with_api_key("your-api-key")
.with_base_url("https://api.runagent.ai")
.with_logging()
.build();
let client = RunAgentClient::new(RunAgentClientConfig {
agent_id: "local-agent-id".to_string(),
entrypoint_tag: "minimal".to_string(),
local: Some(true),
// enable_registry defaults to true for local agents
..RunAgentClientConfig::default()
}).await?;
```

---

## Architecture

### Core Components

* **Client**: High-level client for agent interaction
* **REST Client**: HTTP-based client for non-streaming requests
* **Socket Client**: WebSocket-based client for streaming interactions
* **Database**: SQLite-based agent history store (optional)
* **Serialization**: Safe messaging via WebSocket
> **Guardrails**: tags ending with `_stream` can only be run via `run_stream*`. Non-stream tags must be run via `run*`. The client raises clear errors (`STREAM_ENTRYPOINT`, `NON_STREAM_ENTRYPOINT`) with suggestions.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Guardrails docs mention specific error codes not clearly surfaced by local validation

The guardrails note promises STREAM_ENTRYPOINT / NON_STREAM_ENTRYPOINT error codes, but the local checks in RunAgentClient::run / run_stream_with_args currently return RunAgentError::validation("Use run_stream for streaming entrypoints" / "Use run() for non-stream entrypoints") without codes.

If those symbolic codes are only produced by the backend (and not by these local guards), consider clarifying the docs, or updating the client-side validation errors to use the same structured Execution variant with codes so behavior matches the table.

🤖 Prompt for AI Agents
In runagent-rust/runagent/README.md around lines 185-215, the docs promise
STREAM_ENTRYPOINT / NON_STREAM_ENTRYPOINT error codes but the client-side local
guards currently return generic validation errors; update the client to return
the same structured Execution/with-code errors as the backend (i.e., have
RunAgentClient::run and run_stream_with_args produce RunAgentError::Execution
including the appropriate code string and helpful message) so behavior matches
the docs, or alternatively update the README text to state that those codes are
only produced by the backend if you prefer not to change code.

Comment thread sdk_checklist.md
Comment on lines +45 to +50
### Architecture Metadata Contract
- Treat `/api/v1/agents/{id}/architecture` as an envelope `{ success, data, message, error, timestamp, request_id }`. Handle both the new envelope and the legacy payload transparently.
- When `success === false`, raise the backend-provided `code/message` and surface any `suggestion`/`details` so users know how to recover (e.g. `AGENT_NOT_FOUND_REMOTE`, `AUTHENTICATION_ERROR`).
- When `success === true`, normalize `data` into a single `AgentArchitecture` structure that includes `agent_id`/`agentId` plus the full entrypoint metadata (`tag`, `file`, `module`, `extractor`, `description`, etc.).
- If `data` or `data.entrypoints` is missing, throw a clear `ARCHITECTURE_MISSING` error instructing users to redeploy or supply proper entrypoints.
- When an entrypoint lookup fails, log or expose the list of entrypoint tags returned by the server to simplify debugging typo/mismatch issues.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Consolidate duplicated architecture endpoint guidance.

Lines 45–50 and 145–150 both describe the architecture endpoint contract, error handling, and normalization. The Additional Consistency Requirements section largely repeats what's already specified here. Consider consolidating to avoid divergence as the document evolves, or designate one canonical section.

🤖 Prompt for AI Agents
In sdk_checklist.md around lines 45–50, there is duplicated guidance also
present at lines 145–150; consolidate by keeping one canonical "Architecture
Metadata Contract" section (preferably the earlier one at 45–50), remove the
duplicate block at 145–150, and replace it with a short cross-reference pointing
to the canonical section; ensure the canonical section contains the full
requirements (envelope handling, success/error semantics, normalization to
AgentArchitecture, ARCHITECTURE_MISSING error, and entrypoint-tag exposure) so
nothing is lost and update any internal links/TOC entries accordingly.

Comment thread sdk_checklist.md
Comment on lines +147 to +149
- **Run vs. runStream guardrails**: enforce that `_stream` tags only work with `runStream()` (`STREAM_ENTRYPOINT` error with a helpful suggestion) and non-stream tags only work with `run()` (`NON_STREAM_ENTRYPOINT` error). This mirrors the CLI and prevents silent misuse.
- **Structured error surfaces**: expose a canonical error type (`RunAgentError`/`RunAgentExecutionError`) that always carries `code`, `message`, `suggestion`, and optional `details`, and reuse the shared code taxonomy (`AUTHENTICATION_ERROR`, `PERMISSION_ERROR`, `VALIDATION_ERROR`, `CONNECTION_ERROR`, `SERVER_ERROR`, `AGENT_NOT_FOUND_LOCAL`, `AGENT_NOT_FOUND_REMOTE`, `STREAM_ENTRYPOINT`, `NON_STREAM_ENTRYPOINT`, `ARCHITECTURE_MISSING`, etc.).
- **Diagnostics for entrypoint mismatches**: when the requested entrypoint isn’t found, log or otherwise expose the set of tags returned by the backend so developers can quickly spot typos or missing deployments.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Integrate run vs. runStream guardrails and missing error codes into earlier sections.

The run/runStream entrypoint validation and new error codes (STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT) should be moved into the "HTTP run() Semantics" (line 57) and "WebSocket run_stream() Semantics" (line 84) sections, where endpoint-specific behavior is already documented. Additionally, these error codes are not mentioned in the error taxonomy (line 82), creating a gap where readers can't find the canonical list.

The phrase "_stream tags" (line 147) should also be defined the first time it appears—introduce it earlier (perhaps in line 4 when discussing entrypoint metadata) to clarify what distinguishes a stream-eligible tag.

Verify that STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT, and ARCHITECTURE_MISSING error codes are consistently defined in the canonical error taxonomy and are actually implemented (enforced) in the Rust SDK and other SDKs.


I need to gather information from the codebase to verify this review comment. Let me examine the file and search for the relevant error code implementations.


---

🏁 Script executed:

```shell
#!/bin/bash
# Examine sdk_checklist.md to see current structure and error taxonomy
cat sdk_checklist.md | head -150 | tail -100

Length of output: 6312


🏁 Script executed:

#!/bin/bash
# Search for error code definitions in the file, especially the taxonomy section around line 82
cat sdk_checklist.md | sed -n '70,120p'

Length of output: 2671


🏁 Script executed:

#!/bin/bash
# Look for STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT, ARCHITECTURE_MISSING in the codebase
rg -n 'STREAM_ENTRYPOINT|NON_STREAM_ENTRYPOINT|ARCHITECTURE_MISSING' -C2

Length of output: 6701


🏁 Script executed:

#!/bin/bash
# Search for _stream tags definition in sdk_checklist.md
rg -n '_stream' sdk_checklist.md -C2

Length of output: 2926


🏁 Script executed:

#!/bin/bash
# Look for Rust SDK error implementations
fd -e rs | xargs rg -l 'RunAgentError|error.*code' | head -20

Length of output: 439


Reorganize error taxonomy and define "_stream tags" to consolidate run/runStream guardrails.

The review comment is accurate: STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT, and ARCHITECTURE_MISSING error codes are currently documented only in the "Additional Consistency Requirements" section (line 148), not in the canonical error taxonomy at line 82. The codes are already implemented in Rust and TypeScript SDKs, but the documentation structure creates a gap where readers must cross-reference sections.

Additionally, "_stream tags" lacks a formal definition on first mention (line 147). The term should be introduced when entrypoint metadata is discussed (around line 4).

The suggested refactor is valid and necessary:

  • Add STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT, and ARCHITECTURE_MISSING to the error taxonomy at line 82.
  • Move the run/runStream guardrails content into the "HTTP run() Semantics" (line 57) and "WebSocket run_stream() Semantics" (line 84) sections to document endpoint-specific validation behavior where it belongs.
  • Define "_stream tags" early (line 4 context) as entrypoint tags ending with _stream that invoke streaming behavior.
🤖 Prompt for AI Agents
In sdk_checklist.md around lines 147-149, the review points out that
STREAM_ENTRYPOINT, NON_STREAM_ENTRYPOINT, and ARCHITECTURE_MISSING are only
documented in "Additional Consistency Requirements" instead of the canonical
error taxonomy; add these three error codes to the error taxonomy at ~line 82;
define “_stream tags” early near the entrypoint metadata discussion (~line 4) as
tags that end with “_stream” and invoke streaming behavior; move the
run/runStream guardrails text from the Additional Consistency section into the
HTTP `run()` Semantics (~line 57) and WebSocket `run_stream()` Semantics (~line
84) sections so endpoint-specific validation is documented in-place; finally,
include the diagnostics recommendation in the entrypoint-mismatch guidance to
log/expose the set of tags returned by the backend when an entrypoint isn’t
found.

Comment thread sdk_checklist.md
### Additional Consistency Requirements
- **Architecture endpoint contract**: every SDK must treat `/api/v1/agents/{id}/architecture` as an envelope `{ success, data, message, error, timestamp, request_id }`, propagate backend `error.code/message/suggestion/details`, normalize the `data` payload (including `agent_id`/`agentId`, `file`, `module`, `extractor`, etc.), and throw a clear `ARCHITECTURE_MISSING` error when `data.entrypoints` is absent.
- **Run vs. runStream guardrails**: enforce that `_stream` tags only work with `runStream()` (`STREAM_ENTRYPOINT` error with a helpful suggestion) and non-stream tags only work with `run()` (`NON_STREAM_ENTRYPOINT` error). This mirrors the CLI and prevents silent misuse.
- **Structured error surfaces**: expose a canonical error type (`RunAgentError`/`RunAgentExecutionError`) that always carries `code`, `message`, `suggestion`, and optional `details`, and reuse the shared code taxonomy (`AUTHENTICATION_ERROR`, `PERMISSION_ERROR`, `VALIDATION_ERROR`, `CONNECTION_ERROR`, `SERVER_ERROR`, `AGENT_NOT_FOUND_LOCAL`, `AGENT_NOT_FOUND_REMOTE`, `STREAM_ENTRYPOINT`, `NON_STREAM_ENTRYPOINT`, `ARCHITECTURE_MISSING`, etc.).
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Deduplicate structured error handling guidance.

Lines 148 and 110–113 both describe error types and structured surfaces. Consolidate into a single, authoritative "Error Handling Guidance" section to avoid maintenance drift.

🤖 Prompt for AI Agents
In sdk_checklist.md around line 148 (and duplicated content at lines 110–113),
there are two overlapping descriptions of structured error types; consolidate
them into a single authoritative "Error Handling Guidance" section: merge the
duplicated text into one canonical paragraph that defines the
RunAgentError/RunAgentExecutionError shape (code, message, suggestion, optional
details), include the shared code taxonomy (AUTHENTICATION_ERROR,
PERMISSION_ERROR, VALIDATION_ERROR, CONNECTION_ERROR, SERVER_ERROR,
AGENT_NOT_FOUND_LOCAL, AGENT_NOT_FOUND_REMOTE, STREAM_ENTRYPOINT,
NON_STREAM_ENTRYPOINT, ARCHITECTURE_MISSING, etc.), remove the duplicate block
at lines 110–113, and replace it with a short cross-reference to the unified
section to avoid drift.

Comment on lines +2 to 4
"agent_name": "Agno agent simple assistant",
"description": "My AI agent simple assistant",
"framework": "agno",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Verify agent_id consistency with clients using this template

The updated agent_name/description (“simple assistant”) look good.

However, this config’s agent_id (ae29bd73-b3d3-42c8-a98f-5d7aec7ee919) differs from the one used in test_scripts/python/client_test_agno.py (ad29...). If that script is intended to target this template’s agent, it would be good to make the IDs consistent.

Please confirm whether they should point at the same agent and adjust accordingly.

Also applies to: 28-31


🏁 Script executed:

#!/bin/bash
# Find and display agent_id from runagent.config.json
echo "=== runagent.config.json agent_id ==="
find . -name "runagent.config.json" -type f -exec grep -n "agent_id" {} + 2>/dev/null | head -20

echo -e "\n=== client_test_agno.py agent references ==="
find . -name "client_test_agno.py" -type f -exec grep -n "agent_id\|ad29\|ae29" {} + 2>/dev/null | head -20

Length of output: 2325


Confirm and align agent_id between template and test client

The agent_id in templates/agno/default/runagent.config.json:28 is ae29bd73-b3d3-42c8-a98f-5d7aec7ee919, but test_scripts/python/client_test_agno.py:20 uses ad29bd73-b3d3-42c8-a98f-5d7aec7ee919 (note the difference in the 3rd–4th characters: ae29 vs ad29). If this test client is meant to work with this template, align the IDs to match.

🤖 Prompt for AI Agents
In templates/agno/default/runagent.config.json around lines 2–28 the agent_id
value (currently ae29bd73-b3d3-42c8-a98f-5d7aec7ee919) does not match the
agent_id used in test_scripts/python/client_test_agno.py line 20
(ad29bd73-b3d3-42c8-a98f-5d7aec7ee919); update one of these files so both use
the exact same UUID (choose which is canonical for your tests and replace the
mismatched UUID accordingly) to ensure the test client targets the template
agent.

Comment on lines 19 to 23
ra = RunAgentClient(
agent_id="abc4f000-0000-0000-0000-000000000000",
agent_id="ad29bd73-b3d3-42c8-a98f-5d7aec7ee919",
entrypoint_tag="agno_print_response_stream",
local=False
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

Possible agent_id mismatch with template configuration

The agent_id here is ad29bd73-b3d3-42c8-a98f-5d7aec7ee919, while templates/agno/default/runagent.config.json uses ae29bd73-b3d3-42c8-a98f-5d7aec7ee919. The one-character difference (d vs e) looks unintentional.

Please double-check which ID is correct and align the script and template so they target the same agent.


🏁 Script executed:

#!/bin/bash
# Verify test script exists and check lines 19-23
echo "=== Checking test script ==="
if [ -f "test_scripts/python/client_test_agno.py" ]; then
  echo "File exists. Lines 19-23:"
  sed -n '19,23p' "test_scripts/python/client_test_agno.py"
else
  echo "File NOT found"
fi

# Verify template config exists and search for agent_id
echo -e "\n=== Checking template config ==="
if [ -f "templates/agno/default/runagent.config.json" ]; then
  echo "File exists. Full content:"
  cat "templates/agno/default/runagent.config.json"
else
  echo "File NOT found"
fi

# Search for all occurrences of both agent IDs in codebase
echo -e "\n=== Searching for agent ID: ad29bd73-b3d3-42c8-a98f-5d7aec7ee919 ==="
rg "ad29bd73-b3d3-42c8-a98f-5d7aec7ee919" -n

echo -e "\n=== Searching for agent ID: ae29bd73-b3d3-42c8-a98f-5d7aec7ee919 ==="
rg "ae29bd73-b3d3-42c8-a98f-5d7aec7ee919" -n

Length of output: 1909


Confirm agent_id mismatch and align test script with template

Verification confirms the mismatch: the Python test script uses ad29bd73-b3d3-42c8-a98f-5d7aec7ee919, while the template config uses ae29bd73-b3d3-42c8-a98f-5d7aec7ee919 (differ by one character: d vs e). The Rust test also indicates the ae29... version is the canonical agent ID (used in active code and template). Update test_scripts/python/client_test_agno.py line 20 to use ae29bd73-b3d3-42c8-a98f-5d7aec7ee919 to align with the configured agent.

🤖 Prompt for AI Agents
In test_scripts/python/client_test_agno.py around lines 19 to 23, the agent_id
value is incorrect (uses ad29bd73-... with 'd'); update the agent_id on line 20
to the canonical ae29bd73-b3d3-42c8-a98f-5d7aec7ee919 so the Python test matches
the template and Rust test; save and run tests to verify alignment.

@sawradip sawradip merged commit 0dc1771 into main Nov 17, 2025
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Nov 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants