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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*!
ds-api — Rust client for DeepSeek
# Quickstart
## Simple non-streaming request
```no_run
use ds_api::{ApiClient, ApiRequest};
use ds_api::raw::request::message::Message;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Set DEEPSEEK_API_KEY in your environment before running this example.
let token = std::env::var("DEEPSEEK_API_KEY")?;
let client = ApiClient::new(token);
let req = ApiRequest::deepseek_chat(vec![
Message::new(ds_api::raw::request::message::Role::User, "Hello from Rust"),
])
.max_tokens(150)
.json();
let resp = client.send(req).await?;
// Print debug representation of the response; adapt to your needs.
println!("Response: {:?}", resp);
Ok(())
}
```
## Agent with a tool
```no_run
use ds_api::{AgentEvent, DeepseekAgent, tool};
use futures::StreamExt;
use serde_json::{Value, json};
struct EchoTool;
#[tool]
impl ds_api::Tool for EchoTool {
/// Echo the input back.
/// input: the string to echo
async fn echo(&self, input: String) -> Value {
json!({ "echo": input })
}
}
#[tokio::main]
async fn main() {
let token = std::env::var("DEEPSEEK_API_KEY").expect("DEEPSEEK_API_KEY must be set");
let mut stream = DeepseekAgent::new(token).add_tool(EchoTool).chat("Please echo: hello");
while let Some(event) = stream.next().await {
match event {
Err(e) => { eprintln!("Error: {e}"); break; }
Ok(AgentEvent::Token(text)) => println!("Assistant: {text}"),
Ok(AgentEvent::ToolCall(c)) => println!("calling {}({})", c.name, c.delta),
Ok(AgentEvent::ToolResult(r)) => println!("result: {} -> {}", r.name, r.result),
Ok(_) => {}
}
}
}
```
## Injecting messages mid-run
[`DeepseekAgent::with_interrupt_channel`] returns a sender you can use to push
messages into the agent while it's still running. Messages are picked up after
the current tool-execution round and added to the conversation before the next
API turn.
```no_run
use ds_api::{AgentEvent, DeepseekAgent, tool};
use futures::StreamExt;
use serde_json::{Value, json};
use tokio::time::{Duration, sleep};
struct SlowTool;
#[tool]
impl ds_api::Tool for SlowTool {
/// Do some slow work and return a result.
async fn slow_work(&self) -> Value {
sleep(Duration::from_secs(1)).await;
json!({ "status": "done" })
}
}
#[tokio::main]
async fn main() {
let token = std::env::var("DEEPSEEK_API_KEY").expect("DEEPSEEK_API_KEY must be set");
let agent = DeepseekAgent::new(token)
.with_streaming()
.add_tool(SlowTool);
let tx = agent.interrupt_sender();
// Inject a follow-up message from another task while tools are running.
tokio::spawn(async move {
sleep(Duration::from_millis(500)).await;
tx.send("Actually, please summarise the result in one sentence.".into()).unwrap();
});
let mut stream = agent.chat("Please run slow_work.");
while let Some(event) = stream.next().await {
match event {
Err(e) => { eprintln!("Error: {e}"); break; }
Ok(AgentEvent::Token(text)) => print!("{text}"),
Ok(AgentEvent::ToolCall(c)) => { if c.delta.is_empty() { println!("\n[calling {}]", c.name) } }
Ok(AgentEvent::ToolResult(r)) => println!("\n[result] {}", r.result),
Ok(_) => {}
}
}
}
```
See the crate README and the `interrupt` example for more details.
## Inspecting conversation history
After recovering the agent from a finished stream you can read the full
conversation history with [`DeepseekAgent::history`]:
```no_run
use ds_api::DeepseekAgent;
use futures::StreamExt;
# #[tokio::main] async fn main() {
let token = std::env::var("DEEPSEEK_API_KEY").expect("DEEPSEEK_API_KEY must be set");
let mut stream = DeepseekAgent::new(token).chat("Hello!");
while let Some(_) = stream.next().await {}
if let Some(agent) = stream.into_agent() {
for msg in agent.history() {
println!("{:?}: {:?}", msg.role, msg.content);
}
}
# }
```
See the crate README for more examples and migration notes.
*/
// raw types remain accessible via `ds_api::raw` but are not the primary public API
pub use ;
pub use ;
pub use ;
pub use ApiError;
pub use Tool;
pub use ToolBundle;
pub use tool;
pub use McpTool;
pub use ;