Skip to main content

adk_gcp/
lib.rs

1//! Shared Google Cloud REST plumbing for ADK-Rust Vertex AI backends.
2//!
3//! Every Vertex integration in the workspace — sessions, memory, example
4//! store, artifact storage, deployment — needs the same three pieces:
5//!
6//! - **[`GcpHttpClient`]** — Application Default Credentials with cached
7//!   auth headers, a redirect-disabled HTTP client with connect/request
8//!   timeouts, HTTPS-or-loopback endpoint validation, and bounded JSON
9//!   response reads.
10//! - **[`LroPoller`]** — `google.longrunning.Operation` polling with capped
11//!   exponential backoff, operation identity pinning, and project/location
12//!   scope validation.
13//! - **[`VertexResourceName`]** — parsing and formatting of
14//!   `projects/*/locations/*/reasoningEngines/*` resource names.
15//!
16//! Errors cross the [`adk_core::AdkError`] boundary carrying each
17//! consumer's own identity: a [`GcpErrorContext`] bundles the
18//! [`ErrorComponent`](adk_core::ErrorComponent), a
19//! [`GcpErrorCodes`] table of `&'static str` codes, the human-readable
20//! subject, and the provider tag, so errors from the shared plumbing are
21//! indistinguishable from the ones each backend previously built for
22//! itself.
23//!
24//! # Example
25//!
26//! ```rust,no_run
27//! use adk_core::ErrorComponent;
28//! use adk_gcp::{GcpErrorCodes, GcpErrorContext, GcpHttpClient, LroPoller};
29//! use serde_json::json;
30//!
31//! const CODES: GcpErrorCodes = GcpErrorCodes {
32//!     invalid_input: "memory.vertex.invalid_input",
33//!     unauthorized: "memory.vertex.unauthorized",
34//!     forbidden: "memory.vertex.forbidden",
35//!     not_found: "memory.vertex.not_found",
36//!     rate_limited: "memory.vertex.rate_limited",
37//!     timeout: "memory.vertex.timeout",
38//!     unavailable: "memory.vertex.unavailable",
39//!     credentials_unavailable: "memory.vertex.credentials_unavailable",
40//!     invalid_response: "memory.vertex.invalid_response",
41//!     invalid_request: "memory.vertex.invalid_request",
42//!     upstream_error: "memory.vertex.upstream_error",
43//!     operation_failed: "memory.vertex.operation_failed",
44//! };
45//!
46//! # async fn generate() -> adk_core::Result<()> {
47//! let client = GcpHttpClient::builder(
48//!     GcpErrorContext::new(ErrorComponent::Memory, CODES, "vertex memory"),
49//!     "https://us-central1-aiplatform.googleapis.com",
50//! )
51//! .build()?;
52//!
53//! let parent = "projects/my-project/locations/us-central1/reasoningEngines/4242";
54//! let request = client
55//!     .request(reqwest::Method::POST, &format!("{parent}/memories:generate"))
56//!     .await?
57//!     .json(&json!({ "directContentsSource": { "events": [] } }));
58//! let operation = client.send_value(request).await?;
59//!
60//! LroPoller::new()
61//!     .wait_for_operation(&client, operation, "memories generate", false, "my-project", "us-central1")
62//!     .await?;
63//! # Ok(())
64//! # }
65//! ```
66
67#![warn(missing_docs)]
68
69mod client;
70mod error;
71mod lro;
72mod resource;
73
74pub use client::{GcpHttpClient, GcpHttpClientBuilder};
75pub use error::{GcpErrorCodes, GcpErrorContext, truncate_for_error};
76pub use lro::{LroPoller, Operation, OperationError};
77pub use resource::{VertexResourceName, is_canonical_reasoning_engine_id, is_scoped_resource_name};