Skip to content

Commit 904e0c5

Browse files
author
zynx
committed
Merge remote-tracking branch 'origin/main' into feat/message-cursor-pagination
2 parents 08575ba + e0ce4f4 commit 904e0c5

32 files changed

Lines changed: 1930 additions & 657 deletions

File tree

Cargo.lock

Lines changed: 24 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ aionui-cron = { path = "crates/aionui-cron" }
5353
aionui-assistant = { path = "crates/aionui-assistant" }
5454
aionui-app = { path = "crates/aionui-app" }
5555

56-
aion-agent = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.32" }
57-
aion-providers = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.32" }
58-
aion-types = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.32" }
59-
aion-protocol = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.32" }
60-
aion-config = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.32" }
61-
aion-mcp = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.32" }
56+
aion-agent = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.33" }
57+
aion-providers = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.33" }
58+
aion-types = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.33" }
59+
aion-protocol = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.33" }
60+
aion-config = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.33" }
61+
aion-mcp = { git = "https://github.com/iOfficeAI/aionrs.git", tag = "v0.1.33" }
6262

6363
# Core framework
6464
tokio = { version = "1", features = ["full"] }
@@ -70,6 +70,7 @@ http = "1"
7070
# Serialization
7171
serde = { version = "1", features = ["derive"] }
7272
serde_json = "1"
73+
serde_yaml = "0.9"
7374

7475
# Async utilities
7576
futures-util = "0.3"

crates/aionui-ai-agent/src/agent_task.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,8 @@ mod aionrs_config_option_tests {
521521
system_prompt: None,
522522
max_tokens: 4096,
523523
max_turns: None,
524-
max_malformed_tool_call_turns: None,
524+
max_tool_call_malformed_turns: None,
525+
max_tool_call_failure_turns: None,
525526
compat_overrides: Default::default(),
526527
session_directory: std::env::temp_dir().join("aionrs-agent-task-test-sessions"),
527528
session_mode: None,

crates/aionui-ai-agent/src/factory/aionrs.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ pub(super) async fn build(
189189
system_prompt: overrides.system_prompt,
190190
max_tokens: overrides.max_tokens,
191191
max_turns: overrides.max_turns,
192-
max_malformed_tool_call_turns: overrides.max_malformed_tool_call_turns,
192+
max_tool_call_malformed_turns: overrides.max_tool_call_malformed_turns,
193+
max_tool_call_failure_turns: overrides.max_tool_call_failure_turns,
193194
compat_overrides,
194195
session_directory,
195196
session_mode: overrides.session_mode,

crates/aionui-ai-agent/src/manager/aionrs/agent.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ impl AionrsAgentManager {
7878
model: Some(config_extra.model.clone()),
7979
max_tokens: Some(config_extra.max_tokens),
8080
max_turns: config_extra.max_turns,
81-
max_malformed_tool_call_turns: config_extra.max_malformed_tool_call_turns,
81+
max_tool_call_malformed_turns: config_extra.max_tool_call_malformed_turns,
82+
max_tool_call_failure_turns: config_extra.max_tool_call_failure_turns,
8283
system_prompt: config_extra.system_prompt.clone(),
8384
profile: None,
8485
auto_approve: config_extra.session_mode.as_deref() == Some("yolo"),
@@ -485,7 +486,8 @@ mod tests {
485486
system_prompt: None,
486487
max_tokens: 4096,
487488
max_turns: None,
488-
max_malformed_tool_call_turns: None,
489+
max_tool_call_malformed_turns: None,
490+
max_tool_call_failure_turns: None,
489491
compat_overrides: Default::default(),
490492
session_directory: std::env::temp_dir().join("aionrs-test-sessions"),
491493
session_mode: None,

crates/aionui-ai-agent/src/manager/aionrs/error.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ pub(super) fn aionrs_engine_error_to_send_error(error: &AionrsAgentError) -> Age
1010
let detail = format!("Aionrs agent error: {error}");
1111
match error {
1212
AionrsAgentError::Provider(provider_error) => aionrs_provider_error_to_send_error(provider_error, detail),
13-
AionrsAgentError::RepeatedMalformedToolCall { .. } => provider_send_error(
13+
AionrsAgentError::ToolCallMalformed { .. } => provider_send_error(
1414
"The model provider repeatedly returned malformed tool calls",
1515
AgentErrorCode::UserLlmProviderInvalidRequest,
1616
detail,
1717
false,
1818
AgentErrorResolutionKind::ChangeModel,
1919
Some(AgentErrorResolutionTarget::ProviderSettings),
2020
),
21+
AionrsAgentError::ToolCallFailures { .. } => tool_call_failure_send_error(detail),
2122
AionrsAgentError::ContextTooLong { .. } => provider_send_error(
2223
"The request is too large for the configured model context window",
2324
AgentErrorCode::UserLlmProviderContextTooLarge,
@@ -180,13 +181,25 @@ fn unknown_upstream_send_error(detail: String) -> AgentSendError {
180181
)
181182
}
182183

184+
fn tool_call_failure_send_error(detail: String) -> AgentSendError {
185+
AgentSendError::new(
186+
"The upstream Agent repeatedly failed while executing tool calls",
187+
AgentErrorCode::UnknownUpstreamError,
188+
AgentErrorOwnership::UnknownUpstream,
189+
Some(detail),
190+
true,
191+
true,
192+
Some(AgentErrorResolution::new(AgentErrorResolutionKind::Retry, None)),
193+
)
194+
}
195+
183196
#[cfg(test)]
184197
mod tests {
185198
use super::*;
186199

187200
#[test]
188201
fn aionrs_structured_malformed_tool_call_error_is_provider_error() {
189-
let error = AionrsAgentError::RepeatedMalformedToolCall { count: 3, limit: 3 };
202+
let error = AionrsAgentError::ToolCallMalformed { count: 3, limit: 3 };
190203
let send_error = aionrs_engine_error_to_send_error(&error);
191204

192205
assert_eq!(
@@ -274,7 +287,7 @@ mod tests {
274287

275288
#[test]
276289
fn aionrs_repeated_malformed_tool_call_is_user_llm_provider_error() {
277-
let error = AionrsAgentError::RepeatedMalformedToolCall { count: 3, limit: 3 };
290+
let error = AionrsAgentError::ToolCallMalformed { count: 3, limit: 3 };
278291
let send_error = aionrs_engine_error_to_send_error(&error);
279292

280293
assert_eq!(
@@ -287,4 +300,20 @@ mod tests {
287300
);
288301
assert_eq!(send_error.stream_error().retryable, Some(false));
289302
}
303+
304+
#[test]
305+
fn aionrs_tool_call_failures_are_unknown_upstream_error() {
306+
let error = AionrsAgentError::ToolCallFailures { count: 3, limit: 3 };
307+
let send_error = aionrs_engine_error_to_send_error(&error);
308+
309+
assert_eq!(
310+
send_error.code(),
311+
Some(aionui_api_types::AgentErrorCode::UnknownUpstreamError)
312+
);
313+
assert_eq!(
314+
send_error.ownership(),
315+
Some(aionui_api_types::AgentErrorOwnership::UnknownUpstream)
316+
);
317+
assert_eq!(send_error.stream_error().retryable, Some(true));
318+
}
290319
}

crates/aionui-ai-agent/src/protocol/send_error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ impl AgentSendError {
217217
self.stream_error
218218
}
219219

220+
pub fn from_stream_error_data(stream_error: AgentStreamErrorData) -> Self {
221+
Self { stream_error }
222+
}
223+
220224
pub fn code(&self) -> Option<AgentErrorCode> {
221225
self.stream_error.code
222226
}

crates/aionui-ai-agent/src/services/provider_health.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ impl ProviderHealthCheckService {
8282
system_prompt: Some("You are a provider health probe. Reply with exactly OK and do not use tools.".into()),
8383
max_tokens: 16,
8484
max_turns: Some(1),
85-
max_malformed_tool_call_turns: Some(1),
85+
max_tool_call_malformed_turns: Some(1),
86+
max_tool_call_failure_turns: Some(1),
8687
compat_overrides,
8788
session_directory: self.data_dir.join("aionrs-health-check-sessions"),
8889
session_mode: None,
@@ -195,7 +196,8 @@ async fn build_probe_engine(config_extra: AionrsResolvedConfig) -> Result<AgentE
195196
model: Some(config_extra.model),
196197
max_tokens: Some(config_extra.max_tokens),
197198
max_turns: config_extra.max_turns,
198-
max_malformed_tool_call_turns: config_extra.max_malformed_tool_call_turns,
199+
max_tool_call_malformed_turns: config_extra.max_tool_call_malformed_turns,
200+
max_tool_call_failure_turns: config_extra.max_tool_call_failure_turns,
199201
system_prompt: config_extra.system_prompt,
200202
profile: None,
201203
auto_approve: false,

crates/aionui-ai-agent/src/types.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ pub struct AionrsResolvedConfig {
6464
/// Max agentic turns.
6565
pub max_turns: Option<usize>,
6666
/// Max repeated malformed tool-call turns before stopping.
67-
pub max_malformed_tool_call_turns: Option<usize>,
67+
pub max_tool_call_malformed_turns: Option<usize>,
68+
/// Max repeated tool-call failure turns before stopping.
69+
pub max_tool_call_failure_turns: Option<usize>,
6870
/// Provider-specific compat overrides.
6971
pub compat_overrides: AionrsCompatOverrides,
7072
/// Directory for aionrs session persistence files.
@@ -195,7 +197,8 @@ mod tests {
195197
assert!(extra.preset_rules.is_none());
196198
assert_eq!(extra.max_tokens, 8192);
197199
assert!(extra.max_turns.is_none());
198-
assert!(extra.max_malformed_tool_call_turns.is_none());
200+
assert!(extra.max_tool_call_malformed_turns.is_none());
201+
assert!(extra.max_tool_call_failure_turns.is_none());
199202
}
200203

201204
#[test]
@@ -204,13 +207,15 @@ mod tests {
204207
"system_prompt": "You are a helpful assistant.",
205208
"max_tokens": 4096,
206209
"max_turns": 10,
207-
"max_malformed_tool_call_turns": 2
210+
"max_tool_call_malformed_turns": 2,
211+
"max_tool_call_failure_turns": 3
208212
});
209213
let extra: AionrsBuildExtra = serde_json::from_value(json).unwrap();
210214
assert_eq!(extra.system_prompt.unwrap(), "You are a helpful assistant.");
211215
assert_eq!(extra.max_tokens, 4096);
212216
assert_eq!(extra.max_turns.unwrap(), 10);
213-
assert_eq!(extra.max_malformed_tool_call_turns.unwrap(), 2);
217+
assert_eq!(extra.max_tool_call_malformed_turns.unwrap(), 2);
218+
assert_eq!(extra.max_tool_call_failure_turns.unwrap(), 3);
214219
}
215220

216221
#[test]

crates/aionui-ai-agent/tests/agent_types_integration.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ fn make_aionrs_config() -> AionrsResolvedConfig {
9797
system_prompt: None,
9898
max_tokens: 4096,
9999
max_turns: None,
100-
max_malformed_tool_call_turns: None,
100+
max_tool_call_malformed_turns: None,
101+
max_tool_call_failure_turns: None,
101102
compat_overrides: Default::default(),
102103
session_directory: std::env::temp_dir().join("aionrs-test-sessions"),
103104
session_mode: None,

0 commit comments

Comments
 (0)