1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Code generated by @uarp/codegen from spec/openapi.json. DO NOT EDIT.
//!
//! OpenAI-compatible ChatCompletion endpoint
#![allow(unused_imports, clippy::too_many_arguments)]
use reqwest::Method;
use serde::{Deserialize, Serialize};
use crate::client::{Client, Request, NO_BODY, NO_QUERY};
use crate::error::Result;
use crate::generated::models;
use crate::multipart::{field_text, FilePart};
use crate::util::encode_path;
/// OpenAI-compatible ChatCompletion endpoint
#[derive(Debug, Clone)]
pub struct OpenAiCompatApi {
pub(crate) client: Client,
}
impl Client {
/// OpenAI-compatible ChatCompletion endpoint
pub fn open_ai_compat(&self) -> OpenAiCompatApi {
OpenAiCompatApi { client: self.clone() }
}
}
impl OpenAiCompatApi {
/// OpenAI-compatible chat completion
///
/// Maps OpenAI ChatCompletion requests to UARP agent runs. The 'model' field maps to
/// 'agent/\<agent_id\>' or a plain agent_id.
///
/// `POST /v1/chat/completions`
///
/// Required scopes: `runs:create`.
pub async fn chat_completion(&self, body: &models::ChatCompletionRequest) -> Result<serde_json::Value> {
self.client
.request_json(Request {
method: Method::POST,
path: "/v1/chat/completions".to_string(),
query: NO_QUERY,
body: Some(body),
headers: Vec::new(),
idempotent: false,
})
.await
}
/// Create response (OpenAI Responses API)
///
/// OpenAI-compatible Responses API. `model` and `input` required; `previous_response_id` chains
/// to a prior response; `instructions` overrides the agent's system prompt for this call.
///
/// `POST /v1/responses`
///
/// Required scopes: `runs:create`.
pub async fn create_response(&self, body: &models::CreateResponseRequest) -> Result<models::CreateResponseResponse> {
self.client
.request_json(Request {
method: Method::POST,
path: "/v1/responses".to_string(),
query: NO_QUERY,
body: Some(body),
headers: Vec::new(),
idempotent: false,
})
.await
}
/// OpenAI-compatible embeddings
///
/// Generate embedding vectors for input text. Per Standats-Protocols ยง6.1. Uses
/// platform-configured model (text-embedding-3-small).
///
/// `POST /v1/embeddings`
///
/// Required scopes: `runs:create`.
pub async fn embeddings(&self, body: &models::EmbeddingsRequest) -> Result<models::EmbeddingsResponse> {
self.client
.request_json(Request {
method: Method::POST,
path: "/v1/embeddings".to_string(),
query: NO_QUERY,
body: Some(body),
headers: Vec::new(),
idempotent: false,
})
.await
}
/// Get response by ID (OpenAI Responses API)
///
/// `GET /v1/responses/{responseId}`
pub async fn get_response(&self, response_id: &str) -> Result<serde_json::Value> {
self.client
.request_json(Request {
method: Method::GET,
path: format!("/v1/responses/{}", encode_path(response_id)),
query: NO_QUERY,
body: NO_BODY,
headers: Vec::new(),
idempotent: false,
})
.await
}
/// List available models (OpenAI-compatible)
///
/// Returns agents as models in OpenAI model list format.
///
/// `GET /v1/models`
pub async fn list_models(&self) -> Result<models::ListModelsResponse> {
self.client
.request_json(Request {
method: Method::GET,
path: "/v1/models".to_string(),
query: NO_QUERY,
body: NO_BODY,
headers: Vec::new(),
idempotent: false,
})
.await
}
}