Compare commits
3
Commits
9540345ec7
...
e606eb7c49
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e606eb7c49
|
||
|
|
a8fb32b6bd
|
||
|
|
1f7b8417fa
|
@@ -88,7 +88,6 @@ nodes:
|
||||
prompt: |
|
||||
Research prompt: {{initial_prompt}}
|
||||
tools: []
|
||||
temperature: 0.1
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
@@ -180,7 +179,6 @@ nodes:
|
||||
tools:
|
||||
- mcp:ddg-search
|
||||
max_iterations: 15
|
||||
temperature: 0.1
|
||||
state_updates:
|
||||
search_output: "{{output}}"
|
||||
fallback: synthesize
|
||||
@@ -251,7 +249,6 @@ nodes:
|
||||
tools:
|
||||
- mcp:personal-github
|
||||
max_iterations: 15
|
||||
temperature: 0.1
|
||||
state_updates:
|
||||
oss_output: "{{output}}"
|
||||
fallback: synthesize
|
||||
@@ -338,7 +335,6 @@ nodes:
|
||||
tools:
|
||||
- fetch_url_via_curl
|
||||
max_iterations: 20
|
||||
temperature: 0.1
|
||||
state_updates:
|
||||
findings: "{{output}}"
|
||||
fallback: final_format
|
||||
|
||||
+10
-3
@@ -1,3 +1,5 @@
|
||||
use std::mem;
|
||||
|
||||
use super::*;
|
||||
|
||||
use crate::utils::{base64_decode, encode_uri, hex_encode, hmac_sha256, sha256, strip_think_tag};
|
||||
@@ -275,10 +277,11 @@ async fn chat_completions_streaming(
|
||||
format!("Tool call '{function_name}' has non-JSON arguments '{function_arguments}'")
|
||||
})?;
|
||||
handler.tool_call(ToolCall::new(
|
||||
function_name.clone(),
|
||||
mem::take(&mut function_name),
|
||||
arguments,
|
||||
Some(function_id.clone()),
|
||||
Some(mem::take(&mut function_id)),
|
||||
))?;
|
||||
function_arguments.clear();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -529,7 +532,11 @@ fn extract_chat_completions(data: &Value) -> Result<ChatCompletionsOutput> {
|
||||
bail!("Invalid response data: {data}");
|
||||
}
|
||||
|
||||
let output = ChatCompletionsOutput { text, tool_calls, ..Default::default() };
|
||||
let output = ChatCompletionsOutput {
|
||||
text,
|
||||
tool_calls,
|
||||
..Default::default()
|
||||
};
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::mem;
|
||||
|
||||
use super::access_token::get_access_token;
|
||||
use super::claude_oauth::ClaudeOAuthProvider;
|
||||
use super::oauth::{self, OAuthProvider};
|
||||
@@ -232,8 +234,8 @@ pub async fn claude_chat_completions_streaming(
|
||||
handler.text("\n</think>\n\n")?;
|
||||
reasoning_state = 0;
|
||||
handler.thinking_block(ThinkingBlock::Thinking {
|
||||
thinking: std::mem::take(&mut thinking_text),
|
||||
signature: std::mem::take(&mut thinking_signature),
|
||||
thinking: mem::take(&mut thinking_text),
|
||||
signature: mem::take(&mut thinking_signature),
|
||||
});
|
||||
}
|
||||
if !function_name.is_empty() {
|
||||
@@ -245,10 +247,11 @@ pub async fn claude_chat_completions_streaming(
|
||||
})?
|
||||
};
|
||||
handler.tool_call(ToolCall::new(
|
||||
function_name.clone(),
|
||||
mem::take(&mut function_name),
|
||||
arguments,
|
||||
Some(function_id.clone()),
|
||||
Some(mem::take(&mut function_id)),
|
||||
))?;
|
||||
function_arguments.clear();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
||||
+44
-2
@@ -88,11 +88,21 @@ async fn run_one_shot(prompt: &str, ctx: &mut RequestContext) -> Result<String>
|
||||
}
|
||||
|
||||
fn try_parse_json(raw: &str) -> Option<Value> {
|
||||
let cleaned = strip_code_fences(raw.trim());
|
||||
|
||||
let cleaned = strip_code_fences(strip_thinking_blocks(raw.trim()));
|
||||
serde_json::from_str(cleaned).ok()
|
||||
}
|
||||
|
||||
fn strip_thinking_blocks(s: &str) -> &str {
|
||||
let mut s = s.trim_start();
|
||||
while s.starts_with("<think>") {
|
||||
match s.find("</think>") {
|
||||
Some(end) => s = s[end + "</think>".len()..].trim_start(),
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
fn strip_code_fences(s: &str) -> &str {
|
||||
let after_open = s
|
||||
.strip_prefix("```json")
|
||||
@@ -148,6 +158,38 @@ mod tests {
|
||||
assert_eq!(v, json!({"x": true}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_parse_json_strips_thinking_blocks() {
|
||||
let raw = "<think>\nsome reasoning\n</think>\n{\"a\": 1}";
|
||||
|
||||
let v = try_parse_json(raw).unwrap();
|
||||
|
||||
assert_eq!(v, json!({"a": 1}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_parse_json_strips_empty_thinking_block() {
|
||||
let raw = "<think>\n\n</think>\n{\"a\": 1}";
|
||||
|
||||
let v = try_parse_json(raw).unwrap();
|
||||
|
||||
assert_eq!(v, json!({"a": 1}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_parse_json_strips_multiple_thinking_blocks() {
|
||||
let raw = "<think>first</think>\n<think>second</think>\n{\"a\": 1}";
|
||||
|
||||
let v = try_parse_json(raw).unwrap();
|
||||
|
||||
assert_eq!(v, json!({"a": 1}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_parse_json_unclosed_think_tag_returns_none() {
|
||||
assert!(try_parse_json("<think>unclosed {\"a\": 1}").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_parse_json_returns_none_on_prose() {
|
||||
assert!(try_parse_json("Here is the result: it's good").is_none());
|
||||
|
||||
Reference in New Issue
Block a user