diff --git a/.jp/mcp/tools/rust/crate_readme.toml b/.jp/mcp/tools/rust/crate_readme.toml index 6cf707425..b9f916d91 100644 --- a/.jp/mcp/tools/rust/crate_readme.toml +++ b/.jp/mcp/tools/rust/crate_readme.toml @@ -27,11 +27,7 @@ inline_results = "off" parameters = "function_call" [conversation.tools.rust_crate_readme.parameters.crate_name] -type = "string" -required = true summary = "Exact name of the crate." [conversation.tools.rust_crate_readme.parameters.crate_version] -type = "string" -default = "latest" summary = "Semver-compatible version, or `latest` for the most recent release." diff --git a/.jp/mcp/tools/rust/crate_resource.toml b/.jp/mcp/tools/rust/crate_resource.toml index 5368b5074..ecdf3dfe2 100644 --- a/.jp/mcp/tools/rust/crate_resource.toml +++ b/.jp/mcp/tools/rust/crate_resource.toml @@ -41,6 +41,4 @@ inline_results = "off" parameters = "function_call" [conversation.tools.rust_crate_resource.parameters.uri] -type = "string" -required = true summary = "Crate resource URI." diff --git a/.jp/mcp/tools/rust/crate_search_items.toml b/.jp/mcp/tools/rust/crate_search_items.toml index 07b4390b9..73df68618 100644 --- a/.jp/mcp/tools/rust/crate_search_items.toml +++ b/.jp/mcp/tools/rust/crate_search_items.toml @@ -37,25 +37,13 @@ inline_results = "off" parameters = "function_call" [conversation.tools.rust_crate_search_items.parameters.crate_name] -type = "string" -required = true summary = "Exact name of the crate." [conversation.tools.rust_crate_search_items.parameters.crate_version] -type = "string" -default = "latest" summary = "Semver-compatible version, or `latest` for the most recent release." [conversation.tools.rust_crate_search_items.parameters.query] -type = "string" -required = true summary = "Partial-match query against item names and paths." [conversation.tools.rust_crate_search_items.parameters.kinds] -type = "array" -summary = """\ -Filter by item kind. Allowed values: Constant, Derive, Enum, Function, Macro, \ -Method, Module, Struct, Trait, Type, Variant, Attribute. Omit for all kinds.\ -""" -[conversation.tools.rust_crate_search_items.parameters.kinds.items] -type = "string" +summary = "Filter by item kind. Omit for all kinds." diff --git a/.jp/mcp/tools/rust/crate_versions.toml b/.jp/mcp/tools/rust/crate_versions.toml index 2f252913b..8c64d0ef3 100644 --- a/.jp/mcp/tools/rust/crate_versions.toml +++ b/.jp/mcp/tools/rust/crate_versions.toml @@ -22,6 +22,4 @@ inline_results = "off" parameters = "function_call" [conversation.tools.rust_crate_versions.parameters.crate_name] -type = "string" -required = true summary = "Exact name of the crate." diff --git a/.jp/mcp/tools/rust/crates_search.toml b/.jp/mcp/tools/rust/crates_search.toml index 07d2f25f4..27b541f85 100644 --- a/.jp/mcp/tools/rust/crates_search.toml +++ b/.jp/mcp/tools/rust/crates_search.toml @@ -31,6 +31,4 @@ inline_results = "off" parameters = "function_call" [conversation.tools.rust_crates_search.parameters.query] -type = "string" -required = true summary = "Search query." diff --git a/Cargo.lock b/Cargo.lock index 264ca733d..740855979 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-anthropic" version = "0.6.0" -source = "git+https://github.com/JeanMertz/async-anthropic#669cc30e75b0dd0f2069cff5bfd9b61c6aa3b7f9" +source = "git+https://github.com/JeanMertz/async-anthropic#2a9e19d3fe368258275f46ecfab759cce5c582d6" dependencies = [ "backon", "derive_builder", @@ -1013,7 +1013,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -1147,7 +1147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.0", ] [[package]] @@ -1230,7 +1230,7 @@ checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3753,7 +3753,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.0", ] [[package]] @@ -4482,7 +4482,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.0", ] [[package]] @@ -5320,7 +5320,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.0", ] [[package]] diff --git a/crates/jp_cli/src/cmd/query/tool/builtins.rs b/crates/jp_cli/src/cmd/query/tool/builtins.rs index 13fb17a6c..413395e32 100644 --- a/crates/jp_cli/src/cmd/query/tool/builtins.rs +++ b/crates/jp_cli/src/cmd/query/tool/builtins.rs @@ -22,11 +22,11 @@ pub fn describe_tools() -> PartialToolConfig { "Get detailed descriptions and usage examples for one or more tools.".to_owned(), ), parameters: IndexMap::from([("tools".to_owned(), PartialToolParameterConfig { - kind: PartialOneOrManyTypes::One("array".to_owned()), + kind: Some(PartialOneOrManyTypes::One("array".to_owned())), required: Some(true), description: Some("Array of tool names to describe".to_owned()), items: Some(Box::new(PartialToolParameterConfig { - kind: PartialOneOrManyTypes::One("string".to_owned()), + kind: Some(PartialOneOrManyTypes::One("string".to_owned())), ..Default::default() })), ..Default::default() diff --git a/crates/jp_cli/src/cmd/query/tool/inquiry.rs b/crates/jp_cli/src/cmd/query/tool/inquiry.rs index 724813a1d..cbeed5fb2 100644 --- a/crates/jp_cli/src/cmd/query/tool/inquiry.rs +++ b/crates/jp_cli/src/cmd/query/tool/inquiry.rs @@ -491,7 +491,7 @@ fn estimate_fixed_overhead_chars( chars += desc.len(); } // Parameter schemas are serialized as JSON by providers. - chars += serde_json::to_string(&tool.to_parameters_schema()).map_or(0, |s| s.len()); + chars += serde_json::to_string(&tool.parameters).map_or(0, |s| s.len()); } chars diff --git a/crates/jp_cli/src/cmd/query/tool/inquiry_tests.rs b/crates/jp_cli/src/cmd/query/tool/inquiry_tests.rs index ff8c3533a..39102cf6e 100644 --- a/crates/jp_cli/src/cmd/query/tool/inquiry_tests.rs +++ b/crates/jp_cli/src/cmd/query/tool/inquiry_tests.rs @@ -456,7 +456,7 @@ fn overhead_tool_definitions() { summary: Some("Search files.".to_string()), ..Default::default() }, - parameters: IndexMap::new(), + parameters: serde_json::json!({ "type": "object", "properties": {} }), }; let result = estimate_fixed_overhead_chars(None, &[], &[], &[tool]); // name + description + serialized schema @@ -472,7 +472,7 @@ fn overhead_combines_all_sources() { let tool = ToolDefinition { name: "t".to_string(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: serde_json::json!({ "type": "object", "properties": {} }), }; let combined = estimate_fixed_overhead_chars( diff --git a/crates/jp_config/src/conversation/tool.rs b/crates/jp_config/src/conversation/tool.rs index 4dba4caa8..0c065c78e 100644 --- a/crates/jp_config/src/conversation/tool.rs +++ b/crates/jp_config/src/conversation/tool.rs @@ -5,8 +5,7 @@ use std::{fmt, str::FromStr}; use indexmap::IndexMap; use schematic::{Config, ConfigEnum, ConfigError, HandlerError, PartialConfig as _}; use serde::{Deserialize, Serialize}; -use serde_json::{Map, Value}; -use tracing::warn; +use serde_json::Value; pub use crate::types::command::{ CommandConfig, CommandConfigOrString, PartialCommandConfig, PartialCommandConfigOrString, @@ -595,34 +594,41 @@ impl ToPartial for ToolConfig { } } -/// Tool parameter configuration. +/// Overrides for one tool parameter. /// -/// This type doubles as a recursive JSON Schema node: `items` points to the -/// schema for array elements, `properties` describes the fields of object -/// elements. +/// MCP parameters inherit unset fields from the server's schema. +/// Local and built-in parameters must set `type` and define complete array and +/// object shapes. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Config)] #[config(rename_all = "snake_case")] pub struct ToolParameterConfig { /// The type of the parameter. + /// + /// MCP tools inherit this from the server. + /// Local and built-in tools must set it explicitly. #[setting(nested)] - #[serde(rename = "type")] - pub kind: OneOrManyTypes, + #[serde(default, rename = "type", skip_serializing_if = "Option::is_none")] + pub kind: Option, - /// The default value of the parameter. + /// The value used when the argument is omitted. + /// + /// MCP tools inherit the server's default when unset. + /// Local and built-in tools have no default when unset. #[serde(default, skip_serializing_if = "Option::is_none")] pub default: Option, /// Whether the parameter is required. - #[setting(default)] - #[serde(default, skip_serializing_if = "std::ops::Not::not")] - pub required: bool, + /// + /// MCP parameters inherit the server's requirement when unset. + /// Local and built-in parameters default to optional. + /// A requirement declared by an MCP server cannot be removed. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub required: Option, /// A short summary of the parameter. /// - /// This is included in the JSON schema sent to the LLM. - /// If not set, falls back to [`description`]. - /// - /// [`description`]: Self::description + /// This is included in the schema sent to the LLM. + /// When unset, `description` is used. #[serde(default, skip_serializing_if = "Option::is_none")] pub summary: Option, @@ -638,17 +644,32 @@ pub struct ToolParameterConfig { #[serde(default, skip_serializing_if = "Option::is_none")] pub examples: Option, - /// A list of possible values for the parameter. - #[serde(default, rename = "enum", skip_serializing_if = "Vec::is_empty")] - pub enumeration: Vec, + /// Values accepted by the parameter. + /// + /// MCP tools inherit the server's enum when unset. + /// Local and built-in tools accept any value matching `type` when unset. + /// Set this to an empty array to remove an inherited enum. + /// + /// For array elements, set `items.enum`. + /// An enum on the array itself must contain complete arrays, for example + /// `enum = [["one"], ["two", "three"]]`. + #[serde(default, rename = "enum", skip_serializing_if = "Option::is_none")] + pub enumeration: Option>, - /// Schema for array items (recursive). + /// Constraints applied to every array element. + /// + /// MCP tools inherit `items` when unset. + /// Local and built-in array parameters must define it. #[setting(nested)] #[serde(default, skip_serializing_if = "Option::is_none")] #[expect(clippy::use_self, reason = "macro can't resolve `Self`")] pub items: Option>, - /// Sub-properties for object-typed parameters (recursive). + /// Constraints for fields of an object parameter. + /// + /// MCP properties are merged by name. + /// Entries here may narrow nested fields or add fields to local and + /// built-in object parameters. #[setting(nested, merge = merge_nested_indexmap)] #[serde(default, skip_serializing_if = "IndexMap::is_empty")] #[expect(clippy::use_self, reason = "macro can't resolve `Self`")] @@ -658,7 +679,7 @@ pub struct ToolParameterConfig { impl PartialConfigDelta for PartialToolParameterConfig { fn delta(&self, next: Self) -> Self { Self { - kind: self.kind.delta(next.kind), + kind: delta_opt_partial(self.kind.as_ref(), next.kind), default: delta_opt(self.default.as_ref(), next.default), required: delta_opt(self.required.as_ref(), next.required), summary: delta_opt(self.summary.as_ref(), next.summary), @@ -690,17 +711,13 @@ impl ToPartial for ToolParameterConfig { let defaults = Self::Partial::default(); Self::Partial { - kind: self.kind.to_partial(), + kind: self.kind.as_ref().map(ToPartial::to_partial), default: partial_opts(self.default.as_ref(), defaults.default), - required: partial_opt(&self.required, defaults.required), + required: partial_opts(self.required.as_ref(), defaults.required), summary: partial_opts(self.summary.as_ref(), defaults.summary), description: partial_opts(self.description.as_ref(), defaults.description), examples: partial_opts(self.examples.as_ref(), defaults.examples), - enumeration: if self.enumeration.is_empty() { - None - } else { - Some(self.enumeration.clone()) - }, + enumeration: self.enumeration.clone(), items: self.items.as_ref().map(|v| Box::new(v.to_partial())), properties: self .properties @@ -762,72 +779,6 @@ impl OneOrManyTypes { Self::Many(v) => v.iter().any(|v| v == type_), } } - - /// Return whether the type is exactly the given type. - #[must_use] - pub fn is_type(&self, type_: &str) -> bool { - match self { - Self::One(v) => v.as_str() == type_, - Self::Many(v) => v.len() == 1 && v[0] == type_, - } - } -} - -impl ToolParameterConfig { - /// Return whether the parameter is required. - #[must_use] - pub const fn is_required(&self) -> bool { - self.required - } - - /// Convert the parameter to a JSON schema. - pub fn to_json_schema(&self) -> Value { - let mut map = Map::new(); - map.insert("type".to_owned(), match &self.kind { - OneOrManyTypes::One(v) => v.clone().into(), - OneOrManyTypes::Many(v) => v.clone().into(), - }); - - if let Some(desc) = self.summary.as_deref().or(self.description.as_deref()) { - map.insert("description".to_owned(), desc.into()); - } - - if let Some(default) = self.default.clone() { - map.insert("default".to_owned(), default); - } - - if !self.enumeration.is_empty() { - map.insert("enum".to_owned(), self.enumeration.as_slice().into()); - } - - if let Some(items) = self.items.as_ref() { - if !self.kind.is_type("array") { - warn!("Unexpected `items` property for non-array type"); - } - map.insert("items".to_owned(), items.to_json_schema()); - } - - if !self.properties.is_empty() { - let props: Map<_, _> = self - .properties - .iter() - .map(|(k, v)| (k.clone(), v.to_json_schema())) - .collect(); - map.insert("properties".to_owned(), Value::Object(props)); - - let required: Vec<_> = self - .properties - .iter() - .filter(|(_, v)| v.required) - .map(|(k, _)| Value::String(k.clone())) - .collect(); - if !required.is_empty() { - map.insert("required".to_owned(), Value::Array(required)); - } - } - - Value::Object(map) - } } /// The source of a tool. diff --git a/crates/jp_config/src/conversation/tool_tests.rs b/crates/jp_config/src/conversation/tool_tests.rs index 607e796c1..d38c402c8 100644 --- a/crates/jp_config/src/conversation/tool_tests.rs +++ b/crates/jp_config/src/conversation/tool_tests.rs @@ -351,6 +351,30 @@ fn test_tools_config() { ); } +#[test] +fn mcp_parameter_override_preserves_unset_shape_fields() { + let partial: PartialToolConfig = toml::from_str( + r#" +source = "mcp.grizzly" + +[parameters.tags.items] +enum = ["projects/jp", "task", "idea"] +"#, + ) + .unwrap(); + + let config = ToolConfig::from_partial(partial, vec![]).unwrap(); + let tags = config.parameters.get("tags").unwrap(); + let items = tags.items.as_deref().unwrap(); + + assert_eq!(tags.kind, None); + assert_eq!(items.kind, None); + assert_eq!( + items.enumeration, + Some(vec![json!("projects/jp"), json!("task"), json!("idea")]) + ); +} + #[test] fn test_tool_config_command() { let mut p = PartialToolConfig::default_values(&()).unwrap().unwrap(); diff --git a/crates/jp_llm/src/error.rs b/crates/jp_llm/src/error.rs index 63dbe6b92..8b141ad10 100644 --- a/crates/jp_llm/src/error.rs +++ b/crates/jp_llm/src/error.rs @@ -460,12 +460,8 @@ pub enum ToolError { error: minijinja::Error, }, - #[error("Invalid `type` property for {key}, got {value:?}, expected one of {need:?}")] - InvalidType { - key: String, - value: Value, - need: Vec<&'static str>, - }, + #[error("Invalid schema at `{path}`: {message}")] + InvalidSchema { path: String, message: String }, #[error("Needs input: {question:?}")] NeedsInput { question: jp_tool::Question }, diff --git a/crates/jp_llm/src/provider/anthropic.rs b/crates/jp_llm/src/provider/anthropic.rs index 791ad3b15..5654f7c5e 100644 --- a/crates/jp_llm/src/provider/anthropic.rs +++ b/crates/jp_llm/src/provider/anthropic.rs @@ -2064,24 +2064,15 @@ fn convert_tools( description: tool.docs.schema_description().map(str::to_owned), strict: strict.then_some(true), input_schema: { - let required = tool - .parameters - .iter() - .filter(|(_, cfg)| cfg.required) - .map(|(key, _)| key.clone()) - .collect(); - - let properties = tool - .parameters - .into_iter() - .map(|(key, cfg)| (key, cfg.to_json_schema())) - .collect(); - - types::ToolInputSchema { - kind: types::ToolInputSchemaKind::Object, - properties, - required, - additional_properties: strict.then_some(false), + // The document arrives as its source declared it. `$ref` + // and `$defs` are supported, so they pass through; strict + // mode additionally requires the closed-object subset, + // which `transform_schema` produces. + let document = tool.parameters.as_object().cloned().unwrap_or_default(); + if strict { + transform_schema(document).into() + } else { + document.into() } }, cache_control: None, diff --git a/crates/jp_llm/src/provider/anthropic_tests.rs b/crates/jp_llm/src/provider/anthropic_tests.rs index 9923c41ba..085a7745f 100644 --- a/crates/jp_llm/src/provider/anthropic_tests.rs +++ b/crates/jp_llm/src/provider/anthropic_tests.rs @@ -1,12 +1,9 @@ use std::time::Duration; use indexmap::IndexMap; -use jp_config::{ - conversation::tool::{OneOrManyTypes, ToolParameterConfig}, - model::{ - id::ModelIdConfig, - parameters::{PartialCustomReasoningConfig, PartialReasoningConfig, ReasoningEffort}, - }, +use jp_config::model::{ + id::ModelIdConfig, + parameters::{PartialCustomReasoningConfig, PartialReasoningConfig, ReasoningEffort}, }; use jp_conversation::{event::ChatRequest, thread::Thread}; use jp_test::{ @@ -197,17 +194,14 @@ async fn test_fable_5_forced_tool_soft_forces() -> Result { .model(id) .model_details(details) .enable_reasoning() - .tool("run_me", vec![("foo", ToolParameterConfig { - kind: OneOrManyTypes::One("string".into()), - default: Some("foo".into()), - required: false, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - })]) + .tool( + "run_me", + json!({ + "type": "object", + "properties": { "foo": { "type": "string", "default": "foo" } }, + "required": [] + }), + ) .tool_choice_fn("run_me") .chat_request("Please run the tool, providing whatever arguments you want."); @@ -1233,7 +1227,7 @@ fn test_forced_tool_with_reasoning_returns_fallback() { tools: vec![ToolDefinition { name: "my_tool".into(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: json!({ "type": "object", "properties": {} }), }], tool_choice: ToolChoice::Function("my_tool".into()), }; @@ -1305,7 +1299,7 @@ fn test_forced_tool_thinking_always_on_uses_escalating_nudge() { tools: vec![ToolDefinition { name: "my_tool".into(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: json!({ "type": "object", "properties": {} }), }], tool_choice: ToolChoice::Function("my_tool".into()), }; @@ -1389,7 +1383,7 @@ fn test_forced_tool_thinking_always_on_reasoning_off_still_soft_forces() { tools: vec![ToolDefinition { name: "my_tool".into(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: json!({ "type": "object", "properties": {} }), }], tool_choice: ToolChoice::Function("my_tool".into()), }; @@ -1448,12 +1442,12 @@ fn test_forced_tool_function_multi_tool_preserves_name() { ToolDefinition { name: "read_file".into(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: json!({ "type": "object", "properties": {} }), }, ToolDefinition { name: "commit".into(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: json!({ "type": "object", "properties": {} }), }, ], tool_choice: ToolChoice::Function("commit".into()), @@ -1521,7 +1515,7 @@ fn test_forced_tool_without_reasoning_no_fallback() { tools: vec![ToolDefinition { name: "my_tool".into(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: json!({ "type": "object", "properties": {} }), }], tool_choice: ToolChoice::Required, }; diff --git a/crates/jp_llm/src/provider/cerebras.rs b/crates/jp_llm/src/provider/cerebras.rs index ce631cd4d..519eaacbb 100644 --- a/crates/jp_llm/src/provider/cerebras.rs +++ b/crates/jp_llm/src/provider/cerebras.rs @@ -727,7 +727,7 @@ fn convert_tools(tools: Vec) -> Vec { "function": { "name": tool.name, "description": tool.docs.schema_description().unwrap_or_default(), - "parameters": parameters_with_strict_mode(tool.parameters, false), + "parameters": parameters_with_strict_mode(&tool.parameters, false), }, }) }) diff --git a/crates/jp_llm/src/provider/google.rs b/crates/jp_llm/src/provider/google.rs index 19ba8fd5e..9235736fd 100644 --- a/crates/jp_llm/src/provider/google.rs +++ b/crates/jp_llm/src/provider/google.rs @@ -1011,6 +1011,25 @@ fn convert_tool_choice(choice: ToolChoice) -> types::ToolConfig { } } +/// Close the root object of a tool's parameters schema. +/// +/// Gemini accepts JSON Schema as declared, references included, so the document +/// passes through. +/// Only `additionalProperties` is added, to state that the argument object +/// takes no keys beyond the ones it declares. +fn closed_object_schema(parameters: Value) -> Value { + let mut document = match parameters { + Value::Object(document) => document, + other => return other, + }; + + document + .entry("additionalProperties") + .or_insert(Value::Bool(false)); + + Value::Object(document) +} + fn convert_tools(tools: Vec) -> Vec { tools .into_iter() @@ -1018,7 +1037,7 @@ fn convert_tools(tools: Vec) -> Vec { types::Tool::FunctionDeclaration(types::ToolConfigFunctionDeclaration { function_declarations: vec![types::FunctionDeclaration { parameters: None, - parameters_json_schema: Some(tool.to_parameters_schema()), + parameters_json_schema: Some(closed_object_schema(tool.parameters)), name: tool.name, description: tool .docs diff --git a/crates/jp_llm/src/provider/llamacpp.rs b/crates/jp_llm/src/provider/llamacpp.rs index 27a6604de..32f41502a 100644 --- a/crates/jp_llm/src/provider/llamacpp.rs +++ b/crates/jp_llm/src/provider/llamacpp.rs @@ -659,7 +659,7 @@ fn convert_tools(tools: Vec, tool_choice: &ToolChoice) -> Vec for Ollama { } } +/// Convert tool definitions to Ollama's tool format. +/// +/// Ollama decodes tool parameters into a fixed structure rather than accepting +/// JSON Schema: a property may carry `type`, `description`, `enum`, `items`, +/// `anyOf`, `properties` and `required`, and every other keyword is dropped as +/// the request is read. +/// `$ref` is among the dropped keys, so a property that kept its reference +/// would reach the model with no type at all. +/// References are expanded here instead. fn convert_tools(tools: Vec) -> Result> { tools .into_iter() .map(|tool| { + let parameters = json_schema::inline(&tool.parameters) + .as_object() + .cloned() + .unwrap_or_default(); + Ok(ToolInfo { tool_type: ToolType::Function, function: ToolFunctionInfo { - parameters: tool.to_parameters_map().into(), + parameters: parameters.into(), name: tool.name, description: tool .docs diff --git a/crates/jp_llm/src/provider/ollama_tests.rs b/crates/jp_llm/src/provider/ollama_tests.rs index 3c9aa1788..55f0cc375 100644 --- a/crates/jp_llm/src/provider/ollama_tests.rs +++ b/crates/jp_llm/src/provider/ollama_tests.rs @@ -1,4 +1,63 @@ +use serde_json::json; + use super::*; +use crate::tool::ToolDocs; + +/// Ollama drops `$ref` while decoding a tool's parameters, so a referenced type +/// has to arrive expanded or the model sees a property with no type. +#[test] +fn tool_references_are_expanded() { + let tools = vec![ToolDefinition { + name: "crate_search_items".to_owned(), + docs: ToolDocs::default(), + parameters: json!({ + "type": "object", + "properties": { + "kinds": { "type": "array", "items": { "$ref": "#/$defs/EntryType" } } + }, + "required": ["kinds"], + "$defs": { "EntryType": { "type": "string", "enum": ["Enum", "Method"] } } + }), + }]; + + let converted = convert_tools(tools).expect("tools convert"); + let parameters = serde_json::to_value(&converted[0].function.parameters).expect("serializes"); + + assert_eq!( + parameters, + json!({ + "type": "object", + "properties": { + "kinds": { + "type": "array", + "items": { "type": "string", "enum": ["Enum", "Method"] } + } + }, + "required": ["kinds"] + }) + ); +} + +/// The whole document is sent, not just its properties: Ollama reads `type` and +/// `required` from the same object. +#[test] +fn tool_parameters_keep_the_schema_document() { + let tools = vec![ToolDefinition { + name: "read_file".to_owned(), + docs: ToolDocs::default(), + parameters: json!({ + "type": "object", + "properties": { "path": { "type": "string" } }, + "required": ["path"] + }), + }]; + + let converted = convert_tools(tools).expect("tools convert"); + let parameters = serde_json::to_value(&converted[0].function.parameters).expect("serializes"); + + assert_eq!(parameters["type"], json!("object")); + assert_eq!(parameters["required"], json!(["path"])); +} /// Build a query whose only config is an explicit reasoning setting. fn reasoning_query( diff --git a/crates/jp_llm/src/provider/openai.rs b/crates/jp_llm/src/provider/openai.rs index ffacf3e6c..b26d38793 100644 --- a/crates/jp_llm/src/provider/openai.rs +++ b/crates/jp_llm/src/provider/openai.rs @@ -4,11 +4,9 @@ use async_trait::async_trait; use base64::Engine as _; use chrono::NaiveDate; use futures::{StreamExt as _, TryStreamExt as _, stream}; -use indexmap::{IndexMap, IndexSet}; use jp_attachment::AttachmentContent; use jp_config::{ assistant::tool_choice::ToolChoice, - conversation::tool::{OneOrManyTypes, ToolParameterConfig}, model::{ id::{Name, ProviderId}, parameters::{CustomReasoningConfig, ReasoningConfig, ReasoningEffort}, @@ -1639,8 +1637,8 @@ impl TryFrom<&OpenaiConfig> for Openai { /// otherwise refuse. /// 2. The Python SDK doesn't inject nullability — Pydantic emits the `anyOf: /// [..., null]` form upstream. -/// Our function-calling pipeline goes through `ToolParameterConfig` which -/// encodes optionality as `required: bool`, so we have to bridge that here. +/// A tool schema states optionality through its `required` list, so the +/// nullable form has to be produced here. /// /// See: fn ensure_strict_schema(schema: &mut Value) { @@ -1785,48 +1783,34 @@ fn convert_tool_choice(choice: ToolChoice) -> types::ToolChoice { } } -pub(crate) fn parameters_with_strict_mode( - parameters: IndexMap, - strict: bool, -) -> Map { - let required = parameters - .iter() - .filter(|(_, cfg)| strict || cfg.required) - .map(|(k, _)| k.clone()) - .collect::>(); - - let properties = parameters - .into_iter() - .map(|(k, mut cfg)| { - sanitize_parameter(&mut cfg); - let needs_null = strict && !cfg.required; - - let mut schema = cfg.to_json_schema(); - - if needs_null { - make_schema_nullable(&mut schema); - } - - // If `strict` mode is enabled, the schema for each parameter - // must satisfy: `additionalProperties: false` on every - // object, all fields in `required`, and optional fields - // emulated via nullability. - // - // See: - if strict { - ensure_strict_schema(&mut schema); - } +/// Adapt a tool's parameters schema to what the API accepts. +/// +/// The document arrives as its source declared it, `$defs` and references +/// included, both of which OpenAI supports natively. +/// In strict mode [`ensure_strict_schema`] then applies the subset's +/// requirements across the whole document: every object closed, every property +/// required, and the ones that were optional emulated with a nullable union. +/// +/// See: +pub(crate) fn parameters_with_strict_mode(parameters: &Value, strict: bool) -> Map { + let mut document = parameters.as_object().cloned().unwrap_or_default(); + + document.insert("type".to_owned(), "object".into()); + document + .entry("properties") + .or_insert_with(|| Value::Object(Map::new())); + document + .entry("required") + .or_insert_with(|| Value::Array(vec![])); + document.insert("additionalProperties".to_owned(), (!strict).into()); + + if !strict { + return document; + } - (k, schema) - }) - .collect::>(); - - Map::from_iter([ - ("type".to_owned(), "object".into()), - ("properties".to_owned(), properties.into()), - ("additionalProperties".to_owned(), (!strict).into()), - ("required".to_owned(), required.into()), - ]) + let mut document = Value::Object(document); + ensure_strict_schema(&mut document); + document.as_object().cloned().unwrap_or_default() } /// Check whether a JSON schema `type` value includes `"object"`. @@ -1928,77 +1912,6 @@ fn make_schema_nullable(schema: &mut Value) { ); } -/// Sanitizes the parameter shape to fit Openai's limitations. specifically -/// moving array-based enums into the 'items' configuration. -fn sanitize_parameter(config: &mut ToolParameterConfig) { - if let Some(items) = &mut config.items { - sanitize_parameter(items); - } - - let allows_array = match &config.kind { - OneOrManyTypes::One(t) => t == "array", - OneOrManyTypes::Many(types) => types.iter().any(|t| t == "array"), - }; - - if !allows_array || !config.enumeration.iter().any(Value::is_array) { - return; - } - - let (arrays, other): (Vec, Vec) = - config.enumeration.drain(..).partition(Value::is_array); - - config.enumeration = other; - - // Flatten [["foo", "bar"], ["baz"]] -> ["foo", "bar", "baz"] - let items: Vec = arrays - .into_iter() - .flat_map(|v| match v { - Value::Array(v) => v, - _ => vec![], - }) - .collect(); - - let items_config = config.items.get_or_insert_with(|| { - let mut inferred_types: IndexSet<_> = items - .iter() - .map(|v| match v { - Value::String(_) => "string", - Value::Number(n) if n.is_i64() || n.is_u64() => "integer", - Value::Number(_) => "number", - Value::Bool(_) => "boolean", - Value::Null => "null", - Value::Object(_) => "object", - Value::Array(_) => "array", - }) - .map(str::to_owned) - .collect(); - - // Construct the correct kind - let kind = if inferred_types.len() == 1 - && let Some(first) = inferred_types.pop() - { - OneOrManyTypes::One(first) - } else { - OneOrManyTypes::Many(inferred_types.into_iter().collect()) - }; - - Box::new(ToolParameterConfig { - kind, - default: None, - required: false, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - }) - }); - - // Append the flattened values to the items enum - items_config.enumeration.extend(items); -} - fn convert_tools(tools: Vec) -> Vec { tools .into_iter() @@ -2006,7 +1919,7 @@ fn convert_tools(tools: Vec) -> Vec { name: tool.name, strict: true, description: tool.docs.schema_description().map(str::to_owned), - parameters: parameters_with_strict_mode(tool.parameters, true).into(), + parameters: parameters_with_strict_mode(&tool.parameters, true).into(), }) .collect() } diff --git a/crates/jp_llm/src/provider/openai_tests.rs b/crates/jp_llm/src/provider/openai_tests.rs index 9358f9491..e48b26f79 100644 --- a/crates/jp_llm/src/provider/openai_tests.rs +++ b/crates/jp_llm/src/provider/openai_tests.rs @@ -125,42 +125,26 @@ mod make_schema_nullable { } mod parameters_with_strict_mode { - use indexmap::IndexMap; - use jp_config::conversation::tool::{OneOrManyTypes, ToolParameterConfig}; use serde_json::json; use super::super::parameters_with_strict_mode; - fn cfg(kind: &str) -> ToolParameterConfig { - ToolParameterConfig { - kind: OneOrManyTypes::One(kind.to_owned()), - default: None, - required: false, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - } - } - /// Regression for the `crate_search_items.kinds` schema rejected by /// OpenAI's strict validator with "array schema missing items" when the /// parameter is encoded as `{type: ["array", "null"], items: ...}`. #[test] fn nullable_array_parameter_renders_as_anyof() { - let mut params = IndexMap::new(); - params.insert("crate_name".to_owned(), ToolParameterConfig { - required: true, - ..cfg("string") - }); - params.insert("kinds".to_owned(), ToolParameterConfig { - items: Some(Box::new(cfg("string"))), - ..cfg("array") - }); - - let schema = parameters_with_strict_mode(params, true); + let schema = parameters_with_strict_mode( + &json!({ + "type": "object", + "properties": { + "crate_name": { "type": "string" }, + "kinds": { "type": "array", "items": { "type": "string" } } + }, + "required": ["crate_name"] + }), + true, + ); let kinds = &schema["properties"]["kinds"]; assert!( @@ -180,10 +164,14 @@ mod parameters_with_strict_mode { #[test] fn nullable_primitive_parameter_keeps_type_array_form() { - let mut params = IndexMap::new(); - params.insert("label".to_owned(), cfg("string")); - - let schema = parameters_with_strict_mode(params, true); + let schema = parameters_with_strict_mode( + &json!({ + "type": "object", + "properties": { "label": { "type": "string" } }, + "required": [] + }), + true, + ); assert_eq!( schema["properties"]["label"]["type"], @@ -193,20 +181,78 @@ mod parameters_with_strict_mode { #[test] fn required_array_parameter_is_not_wrapped() { - let mut params = IndexMap::new(); - params.insert("paths".to_owned(), ToolParameterConfig { - required: true, - items: Some(Box::new(cfg("string"))), - ..cfg("array") - }); - - let schema = parameters_with_strict_mode(params, true); + let schema = parameters_with_strict_mode( + &json!({ + "type": "object", + "properties": { + "paths": { "type": "array", "items": { "type": "string" } } + }, + "required": ["paths"] + }), + true, + ); let paths = &schema["properties"]["paths"]; assert_eq!(paths["type"], json!("array")); assert_eq!(paths["items"], json!({ "type": "string" })); assert!(paths.get("anyOf").is_none()); } + + #[test] + fn array_enum_keeps_complete_array_values() { + let schema = parameters_with_strict_mode( + &json!({ + "type": "object", + "properties": { + "tags": { + "type": "array", + "enum": [["projects/jp"], ["task", "idea"]], + "items": { "type": "string" } + } + }, + "required": ["tags"] + }), + true, + ); + + assert_eq!( + schema["properties"]["tags"], + json!({ + "type": "array", + "enum": [["projects/jp"], ["task", "idea"]], + "items": { "type": "string" } + }) + ); + } + + /// References and their definitions are supported natively, so they reach + /// the API intact. + #[test] + fn references_and_definitions_are_preserved() { + let schema = parameters_with_strict_mode( + &json!({ + "type": "object", + "properties": { "kinds": { + "type": "array", + "items": { "$ref": "#/$defs/EntryType" } + } }, + "required": ["kinds"], + "$defs": { + "EntryType": { "type": "string", "enum": ["Enum", "Method"] } + } + }), + true, + ); + + assert_eq!( + schema["properties"]["kinds"]["items"], + json!({ "$ref": "#/$defs/EntryType" }) + ); + assert_eq!( + schema["$defs"]["EntryType"], + json!({ "type": "string", "enum": ["Enum", "Method"] }) + ); + } } mod ensure_strict_schema { diff --git a/crates/jp_llm/src/provider/openrouter.rs b/crates/jp_llm/src/provider/openrouter.rs index 3b816fc84..f10238859 100644 --- a/crates/jp_llm/src/provider/openrouter.rs +++ b/crates/jp_llm/src/provider/openrouter.rs @@ -765,7 +765,7 @@ fn create_request( .into_iter() .map(|tool| Tool::Function { function: ToolFunction { - parameters: parameters_with_strict_mode(tool.parameters, true), + parameters: parameters_with_strict_mode(&tool.parameters, true), name: tool.name, description: tool.docs.schema_description().map(str::to_owned), strict: true, diff --git a/crates/jp_llm/src/provider/openrouter_tests.rs b/crates/jp_llm/src/provider/openrouter_tests.rs index 20d89ac37..8a5d86bda 100644 --- a/crates/jp_llm/src/provider/openrouter_tests.rs +++ b/crates/jp_llm/src/provider/openrouter_tests.rs @@ -1,9 +1,7 @@ -use std::iter; - -use indexmap::IndexMap; -use jp_config::{conversation::tool::ToolParameterConfig, providers::llm::LlmProviderConfig}; +use jp_config::providers::llm::LlmProviderConfig; use jp_conversation::event::{ToolCallRequest, ToolCallResponse}; use jp_test::{Result, function_name}; +use serde_json::json; use super::*; use crate::{model::ReasoningDetails, test::TestRequest}; @@ -64,14 +62,8 @@ async fn test_anthropic_opus_5_parallel_tool_round_trip() -> Result { .model(model_id) .model_details(model) .enable_reasoning() - .tool( - "list_items", - iter::empty::<(&'static str, ToolParameterConfig)>(), - ) - .tool( - "search_items", - iter::empty::<(&'static str, ToolParameterConfig)>(), - ) + .tool_without_parameters("list_items") + .tool_without_parameters("search_items") .chat_request( "Call both list_items and search_items in parallel. Do not answer with text \ before calling both tools.", @@ -106,17 +98,14 @@ async fn test_anthropic_opus_5_parallel_tool_round_trip() -> Result { #[test] fn request_preserves_integer_tool_parameter_type() -> Result { let request = TestRequest::chat(ProviderId::Openrouter) - .tool("fs_read_file", [("start_line", ToolParameterConfig { - kind: "integer".to_owned().into(), - required: false, - default: None, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::new(), - })]) + .tool( + "fs_read_file", + json!({ + "type": "object", + "properties": { "start_line": { "type": "integer" } }, + "required": [] + }), + ) .chat_request("Read README.md"); let TestRequest::Chat { model, query, .. } = request else { unreachable!(); @@ -202,10 +191,7 @@ fn forced_tool_request( ) -> (request::ChatCompletion, Option) { let request = TestRequest::chat(ProviderId::Openrouter) .tool_choice_fn("edit_file") - .tool( - "edit_file", - iter::empty::<(&'static str, ToolParameterConfig)>(), - ) + .tool_without_parameters("edit_file") .chat_request("Edit the file"); let request = if enable_reasoning { request.enable_reasoning() diff --git a/crates/jp_llm/src/provider_tests.rs b/crates/jp_llm/src/provider_tests.rs index e83b5b8d5..c1532fa82 100644 --- a/crates/jp_llm/src/provider_tests.rs +++ b/crates/jp_llm/src/provider_tests.rs @@ -1,12 +1,9 @@ use std::sync::Arc; -use indexmap::IndexMap; -use jp_config::{ - assistant::tool_choice::ToolChoice, - conversation::tool::{OneOrManyTypes, ToolParameterConfig}, -}; +use jp_config::assistant::tool_choice::ToolChoice; use jp_conversation::event::ChatRequest; use jp_test::{Result, function_name}; +use serde_json::json; use super::*; use crate::test::{TestRequest, fixture_attachment, run_test, test_model_details}; @@ -44,40 +41,21 @@ fn tool_call_base(provider: ProviderId) -> TestRequest { .event(ChatRequest::from( "Please run the tool, providing whatever arguments you want.", )) - .tool("run_me", vec![ - ("foo", ToolParameterConfig { - kind: OneOrManyTypes::One("string".into()), - default: Some("foo".into()), - required: false, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - }), - ("bar", ToolParameterConfig { - kind: OneOrManyTypes::Many(vec!["string".into(), "array".into()]), - default: None, - required: true, - summary: None, - description: None, - examples: None, - enumeration: vec!["foo".into(), vec!["foo", "bar"].into()], - items: Some(Box::new(ToolParameterConfig { - kind: OneOrManyTypes::One("string".into()), - default: None, - required: false, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - })), - properties: IndexMap::default(), + .tool( + "run_me", + json!({ + "type": "object", + "properties": { + "foo": { "type": "string", "default": "foo" }, + "bar": { + "type": ["string", "array"], + "enum": ["foo"], + "items": { "type": "string", "enum": ["foo", "bar"] } + } + }, + "required": ["bar"] }), - ]) + ) } async fn tool_call_stream(provider: ProviderId, test_name: &str) -> Result { diff --git a/crates/jp_llm/src/test.rs b/crates/jp_llm/src/test.rs index 8b5337bd6..6e1a59ac0 100644 --- a/crates/jp_llm/src/test.rs +++ b/crates/jp_llm/src/test.rs @@ -6,7 +6,6 @@ use jp_attachment::Attachment; use jp_config::{ AppConfig, Config as _, PartialAppConfig, ToPartial as _, assistant::tool_choice::ToolChoice, - conversation::tool::ToolParameterConfig, model::{ id::{ModelIdConfig, ModelIdOrAliasConfig, Name, PartialModelIdOrAliasConfig, ProviderId}, parameters::{ @@ -17,7 +16,7 @@ use jp_config::{ }; use jp_conversation::{ ConversationEvent, ConversationStream, - event::{ChatRequest, ToolCallResponse}, + event::{ChatRequest, EventKind, ToolCallResponse}, stream::ConversationEventWithConfig, thread::{Thread, ThreadBuilder}, }; @@ -32,6 +31,105 @@ use crate::{ tool::{ToolDefinition, ToolDocs}, }; +/// Fail when a model calls a tool with arguments its schema does not declare. +/// +/// A provider that drops or mangles the parameter schema on the way out still +/// produces a plausible-looking tool call: with nothing to go on, the model +/// invents argument names from the tool's name, and the snapshot records them +/// as though they were a real choice. +/// Checking each recorded call against the schema is what separates "the model +/// picked these arguments" from "the model never saw the schema". +/// +/// Only checked while recording. +/// On playback the response is fixed and may predate the schema it is being +/// judged against, so the check would report on the past rather than on current +/// behavior. +/// What playback verifies instead is the request: a cassette matches on its +/// recorded body, so a change to what JP sends fails the test on its own. +fn assert_tool_calls_match_schema(tools: &[ToolDefinition], events: &[TestEvent]) { + for event in events { + let TestEvent::Flushed(event) = event else { + continue; + }; + let EventKind::ToolCallRequest(call) = &event.kind else { + continue; + }; + + let Some(tool) = tools.iter().find(|tool| tool.name == call.name) else { + panic!( + "model called `{}`, which was never declared; declared tools: {:?}", + call.name, + tools.iter().map(|tool| &tool.name).collect::>() + ); + }; + + let declared = tool + .parameters + .get("properties") + .and_then(serde_json::Value::as_object); + + for name in call.arguments.keys() { + assert!( + declared.is_some_and(|declared| declared.contains_key(name)), + "model called `{}` with undeclared argument `{name}`, so the schema it was sent \ + does not describe this tool; sent: {}", + call.name, + tool.parameters + ); + } + } +} + +// This module is the test harness itself, so its own tests live here rather +// than in the sibling `_tests.rs` file the crate uses for production modules. +#[cfg(test)] +mod harness_tests { + use jp_conversation::event::ToolCallRequest; + use serde_json::{Map, json}; + + use super::*; + + fn tool_call(arguments: Map) -> TestEvent { + TestEvent::Flushed(ConversationEvent::new( + EventKind::ToolCallRequest(ToolCallRequest::new( + "call_1".to_owned(), + "run_me".to_owned(), + arguments, + )), + Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap(), + )) + } + + fn run_me() -> Vec { + vec![ToolDefinition { + name: "run_me".to_owned(), + docs: ToolDocs::default(), + parameters: json!({ + "type": "object", + "properties": { "foo": { "type": "string" } }, + "required": [] + }), + }] + } + + #[test] + fn a_declared_argument_passes() { + let arguments = json!({ "foo": "x" }).as_object().cloned().unwrap(); + + assert_tool_calls_match_schema(&run_me(), &[tool_call(arguments)]); + } + + /// The shape a provider produces when the schema never reached the model: a + /// well-formed call naming an argument the tool does not have. + #[test] + #[should_panic(expected = "undeclared argument")] + fn an_invented_argument_fails() { + let arguments = json!({ "command": "ls" }).as_object().cloned().unwrap(); + + assert_tool_calls_match_schema(&run_me(), &[tool_call(arguments)]); + } +} + /// An entry in the per-request event log used for snapshot testing. /// /// Captures the output of the streaming pipeline (flushed `ConversationEvent`s) @@ -216,25 +314,27 @@ impl TestRequest { self.tool_choice(ToolChoice::Function(name.into())) } - pub fn tool, I: IntoIterator>( - mut self, - name: S, - definitions: I, - ) -> Self { + /// Declare a tool with the given JSON Schema for its arguments. + pub fn tool>(mut self, name: S, parameters: serde_json::Value) -> Self { if let Self::Chat { query, .. } = &mut self { query.tools.push(ToolDefinition { name: name.into(), docs: ToolDocs::default(), - parameters: definitions - .into_iter() - .map(|(k, v)| (k.to_owned(), v)) - .collect(), + parameters, }); } self } + /// Declare a tool that takes no arguments. + pub fn tool_without_parameters>(self, name: S) -> Self { + self.tool( + name, + serde_json::json!({ "type": "object", "properties": {} }), + ) + } + #[expect(dead_code)] pub fn assert_chat(mut self, assert: impl Fn(&[Vec]) + 'static) -> Self { if let Self::Chat { assert: a, .. } = &mut self { @@ -508,6 +608,7 @@ pub async fn run_chat_completion( assert, assert_history, } => { + let tools = query.tools.clone(); let events: Vec = provider .chat_completion_stream(&model, query) .await @@ -576,6 +677,9 @@ pub async fn run_chat_completion( } } + if recording { + assert_tool_calls_match_schema(&tools, &all_events[index]); + } assert(&all_events); assert_history(&history); } diff --git a/crates/jp_llm/src/tool.rs b/crates/jp_llm/src/tool.rs index e69e88bcb..1a7732f31 100644 --- a/crates/jp_llm/src/tool.rs +++ b/crates/jp_llm/src/tool.rs @@ -2,6 +2,7 @@ pub mod builtin; pub mod executor; +pub mod json_schema; use std::{ffi::OsStr, process::Stdio, sync::Arc}; @@ -9,9 +10,7 @@ pub use builtin::BuiltinTool; use camino::Utf8Path; use indexmap::IndexMap; use jp_config::{ - conversation::tool::{ - CommandConfig, OneOrManyTypes, ToolConfigWithDefaults, ToolParameterConfig, ToolSource, - }, + conversation::tool::{CommandConfig, ToolConfigWithDefaults, ToolSource}, types::command::shell_command_line, }; use jp_conversation::event::ToolCallResponse; @@ -20,6 +19,7 @@ use jp_mcp::{ id::{McpServerId, McpToolId}, }; use jp_tool::{Action, Outcome, Question}; +use json_schema::{Node, merge_description}; use minijinja::{Environment, ErrorKind as MinijinjaErrorKind, value::ValueKind}; use serde_json::{Map, Value, json}; use tokio::{ @@ -602,7 +602,12 @@ pub struct InvocationContext { pub struct ToolDefinition { pub name: String, pub docs: ToolDocs, - pub parameters: IndexMap, + + /// JSON Schema for the tool's arguments, as its source declared it, with + /// configuration overrides applied. + /// + /// Adapting this to what a given API accepts belongs to that provider. + pub parameters: Value, } impl ToolDefinition { @@ -611,7 +616,7 @@ impl ToolDefinition { /// Strings stay unchanged when the schema accepts strings or their contents /// do not parse to a declared type. pub fn coerce_arguments(&self, arguments: &mut Map) { - coerce_parameter_types(arguments, &self.parameters); + coerce_arguments_to_schema(arguments, &self.parameters); } /// Execute the tool without any interactive prompts. @@ -744,9 +749,9 @@ impl ToolDefinition { // Apply configured defaults for missing parameters, then validate. if let Some(args) = arguments.as_object_mut() { - apply_parameter_defaults(args, config.parameters()); + apply_parameter_defaults(args, &self.parameters); - if let Err(error) = validate_tool_arguments(args, config.parameters()) { + if let Err(error) = validate_tool_arguments(args, &self.parameters) { return Ok(ExecutionOutcome::Completed { id, result: Err(format!( @@ -889,32 +894,10 @@ impl ToolDefinition { }) } - /// Return a map of parameter names to JSON schemas. - #[must_use] - pub fn to_parameters_map(&self) -> Map { - self.parameters - .clone() - .into_iter() - .map(|(k, v)| (k, v.to_json_schema())) - .collect() - } - - /// Return a JSON schema for the parameters of the tool. + /// Return the JSON Schema for the tool's parameters. #[must_use] pub fn to_parameters_schema(&self) -> Value { - let required = self - .parameters - .iter() - .filter(|(_, cfg)| cfg.required) - .map(|(k, _)| k.clone()) - .collect::>(); - - json!({ - "type": "object", - "properties": self.to_parameters_map(), - "additionalProperties": false, - "required": required, - }) + self.parameters.clone() } } @@ -986,58 +969,42 @@ pub(crate) fn split_description(text: &str) -> (String, Option) { (text.to_owned(), None) } -fn coerce_parameter_types( - arguments: &mut Map, - parameters: &IndexMap, -) { - for (name, config) in parameters { - let Some(value) = arguments.get_mut(name) else { - continue; - }; +/// Coerce JSON-encoded argument strings to the types the schema declares. +fn coerce_arguments_to_schema(arguments: &mut Map, schema: &Value) { + coerce_object(arguments, &Node::root(schema)); +} - coerce_parameter_value(value, config); +fn coerce_object(arguments: &mut Map, node: &Node<'_>) { + for (name, property) in node.properties() { + if let Some(value) = arguments.get_mut(&name) { + coerce_value(value, &property); + } } } -fn coerce_parameter_value(value: &mut Value, config: &ToolParameterConfig) { +fn coerce_value(value: &mut Value, node: &Node<'_>) { if let Value::String(raw) = value - && !config.kind.has_type("string") - && let Ok(parsed) = serde_json::from_str(raw) - && parameter_accepts_value(&parsed, &config.kind) + && !node.types().iter().any(|type_| type_ == "string") + && let Ok(parsed) = serde_json::from_str::(raw) + && node.accepts(&parsed) { *value = parsed; } match value { - Value::Object(arguments) if !config.properties.is_empty() => { - coerce_parameter_types(arguments, &config.properties); - } + Value::Object(arguments) => coerce_object(arguments, node), Value::Array(values) => { - let Some(items) = config.items.as_deref() else { + let Some(items) = node.items() else { return; }; for value in values { - coerce_parameter_value(value, items); + coerce_value(value, &items); } } _ => {} } } -fn parameter_accepts_value(value: &Value, types: &OneOrManyTypes) -> bool { - match value { - Value::Null => types.has_type("null"), - Value::Bool(_) => types.has_type("boolean"), - Value::Number(number) => { - types.has_type("number") - || (types.has_type("integer") && (number.is_i64() || number.is_u64())) - } - Value::String(_) => types.has_type("string"), - Value::Array(_) => types.has_type("array"), - Value::Object(_) => types.has_type("object"), - } -} - /// Fill in configured default values for missing parameters. /// /// LLMs commonly omit parameters that have a `default` in the JSON schema, even @@ -1045,33 +1012,35 @@ fn parameter_accepts_value(value: &Value, types: &OneOrManyTypes) -> bool { /// This function patches the arguments map before validation so that such /// omissions don't cause spurious "missing argument" errors and unnecessary LLM /// retries. -fn apply_parameter_defaults( - arguments: &mut Map, - parameters: &IndexMap, -) { - for (name, cfg) in parameters { - if !arguments.contains_key(name) { - if let Some(default) = &cfg.default { - arguments.insert(name.clone(), default.clone()); +fn apply_parameter_defaults(arguments: &mut Map, schema: &Value) { + apply_defaults_to(arguments, &Node::root(schema)); +} + +fn apply_defaults_to(arguments: &mut Map, node: &Node<'_>) { + for (name, property) in node.properties() { + if !arguments.contains_key(&name) { + if let Some(default) = property.default() { + let default = default.clone(); + arguments.insert(name, default); } continue; } // Recurse into object fields. - if let Some(obj) = arguments.get_mut(name).and_then(Value::as_object_mut) - && !cfg.properties.is_empty() + if property.has_properties() + && let Some(object) = arguments.get_mut(&name).and_then(Value::as_object_mut) { - apply_parameter_defaults(obj, &cfg.properties); + apply_defaults_to(object, &property); } // Recurse into array elements. - if let Some(items) = &cfg.items - && !items.properties.is_empty() - && let Some(arr) = arguments.get_mut(name).and_then(Value::as_array_mut) + if let Some(items) = property.items() + && items.has_properties() + && let Some(values) = arguments.get_mut(&name).and_then(Value::as_array_mut) { - for elem in arr.iter_mut() { - if let Some(obj) = elem.as_object_mut() { - apply_parameter_defaults(obj, &items.properties); + for value in values.iter_mut() { + if let Some(object) = value.as_object_mut() { + apply_defaults_to(object, &items); } } } @@ -1080,47 +1049,52 @@ fn apply_parameter_defaults( fn validate_tool_arguments( arguments: &Map, - parameters: &IndexMap, + schema: &Value, ) -> Result<(), ToolError> { + validate_arguments_against(arguments, &Node::root(schema)) +} + +fn validate_arguments_against( + arguments: &Map, + node: &Node<'_>, +) -> Result<(), ToolError> { + let properties = node.properties(); + let unknown = arguments .keys() - .filter(|k| !parameters.contains_key(*k)) + .filter(|name| !properties.iter().any(|(known, _)| known == *name)) .cloned() .collect::>(); - let mut missing = vec![]; - for (name, cfg) in parameters { - if cfg.required && !arguments.contains_key(name) { - missing.push(name.to_owned()); - } - } + let missing = properties + .iter() + .filter(|(name, _)| node.is_required(name) && !arguments.contains_key(name)) + .map(|(name, _)| name.clone()) + .collect::>(); if !missing.is_empty() || !unknown.is_empty() { return Err(ToolError::Arguments { missing, unknown }); } // Recurse into nested structures. - for (name, cfg) in parameters { - let Some(value) = arguments.get(name) else { + for (name, property) in properties { + let Some(value) = arguments.get(&name) else { continue; }; - // Object parameters with properties: validate the object fields. - if let Some(obj) = value.as_object() - && !cfg.properties.is_empty() + if let Some(object) = value.as_object() + && property.has_properties() { - validate_tool_arguments(obj, &cfg.properties)?; + validate_arguments_against(object, &property)?; } - // Array parameters with items that have properties: validate each - // element. - if let Some(items) = &cfg.items - && !items.properties.is_empty() - && let Some(arr) = value.as_array() + if let Some(items) = property.items() + && items.has_properties() + && let Some(values) = value.as_array() { - for element in arr { - if let Some(obj) = element.as_object() { - validate_tool_arguments(obj, &items.properties)?; + for value in values { + if let Some(object) = value.as_object() { + validate_arguments_against(object, &items)?; } } } @@ -1168,7 +1142,22 @@ pub async fn tool_definitions( } } - let definition = resolve_tool(name, &config, mcp_client).await?; + // A tool JP cannot describe to the provider is dropped rather than + // failing the query, matching the unavailable-server case above. A tool + // the caller named explicitly is the exception: silently omitting it + // would leave `tool_choice` pointing at a tool the provider never saw. + let definition = match resolve_tool(name, &config, mcp_client).await { + Ok(definition) => definition, + Err(error) if !forced => { + warn!( + tool = name, + %error, + "Skipping tool: its parameter schema could not be resolved." + ); + continue; + } + Err(error) => return Err(error), + }; definitions.push(definition); } @@ -1181,19 +1170,21 @@ async fn resolve_tool( config: &ToolConfigWithDefaults, mcp_client: &jp_mcp::Client, ) -> Result { - match config.source() { - ToolSource::Local { .. } | ToolSource::Builtin { .. } => { - let docs = ToolDocs::from_config(config); - Ok(ToolDefinition { - name: name.to_owned(), - docs, - parameters: config.parameters().clone(), - }) - } + let path = format!("conversation.tools.{name}.parameters"); + let definition = match config.source() { + ToolSource::Local { .. } | ToolSource::Builtin { .. } => ToolDefinition { + name: name.to_owned(), + docs: ToolDocs::from_config(config), + parameters: json_schema::from_config(&path, config.parameters())?, + }, ToolSource::Mcp { server, tool } => { - resolve_mcp_tool(server, name, tool.as_deref(), config, mcp_client).await + resolve_mcp_tool(server, name, tool.as_deref(), config, mcp_client).await? } - } + }; + + json_schema::validate(&path, &definition.parameters)?; + + Ok(definition) } /// Resolve an MCP tool: fetch from server, merge config overrides, auto-split @@ -1223,28 +1214,14 @@ async fn resolve_mcp_tool( mcp_tool.description.as_deref(), ); - // Build parameters from MCP schema + user overrides. - let schema = mcp_tool.input_schema.as_ref().clone(); - let required_properties: Vec<&str> = schema - .get("required") - .and_then(|v| v.as_array()) - .into_iter() - .flatten() - .filter_map(|v| v.as_str()) - .collect(); - - let mut params = IndexMap::new(); - for (param_name, opts) in schema - .get("properties") - .and_then(|v| v.as_object()) - .into_iter() - .flatten() - { - let override_cfg = user_overrides.get(param_name.as_str()); - let required_in_mcp = required_properties.iter().any(|p| *p == param_name); - let param = merge_mcp_param(param_name, opts, override_cfg, required_in_mcp)?; - params.insert(param_name.to_owned(), param); - } + // The server's document is the source of truth; configuration may narrow + // it, and nothing else touches it. + let source = Value::Object(mcp_tool.input_schema.as_ref().clone()); + let parameters = json_schema::with_overrides( + &format!("conversation.tools.{name}.parameters"), + &source, + user_overrides, + )?; // Build docs with auto-split heuristic. let has_user_summary = config.summary().is_some(); @@ -1265,10 +1242,11 @@ async fn resolve_mcp_tool( let examples = config.examples().map(str::to_owned); // Per-parameter docs: auto-split MCP descriptions when user didn't override. - let param_docs = params - .iter() - .filter_map(|(pname, pcfg)| { - let user_override = user_overrides.get(pname); + let param_docs = Node::root(¶meters) + .properties() + .into_iter() + .filter_map(|(pname, pnode)| { + let user_override = user_overrides.get(&pname); let has_user_param_summary = user_override.and_then(|o| o.summary.as_ref()).is_some(); let (summary, desc) = if has_user_param_summary { @@ -1280,7 +1258,7 @@ async fn resolve_mcp_tool( .and_then(|o| o.description.as_deref()) .map(str::to_owned); (summary, desc) - } else if let Some(resolved) = &pcfg.description { + } else if let Some(resolved) = pnode.description() { let (s, d) = split_description(resolved); (Some(s), d) } else { @@ -1295,7 +1273,7 @@ async fn resolve_mcp_tool( return None; } - Some((pname.to_owned(), ParameterDocs { + Some((pname, ParameterDocs { summary, description: desc, examples: ex, @@ -1313,174 +1291,10 @@ async fn resolve_mcp_tool( Ok(ToolDefinition { name: name.to_owned(), docs, - parameters: params, + parameters, }) } -/// Merge an MCP server's schema for a single parameter with the user's TOML -/// override, producing the resolved [`ToolParameterConfig`] used by the rest of -/// the pipeline. -/// -/// User overrides win wholesale for fields that affect the parameter's shape -/// (`kind`, `items`, `properties`, `enumeration`) and value constraints -/// (`default`, `description`). -/// The only field that's *not* freely replaceable is `required`: the MCP -/// server's contract allows tightening (`false → true`) but not loosening, -/// since loosening could produce LLM calls that drop arguments the server -/// expects. -/// -/// Item-level (`items`) and nested-object (`properties`) overrides are handled -/// here even when the MCP schema doesn't declare them (e.g. the MCP server -/// emits `items: {"$ref": ...}` which our parser can't inline today). -/// This keeps the override surface symmetric with `kind`, `default`, and -/// `enumeration`. -fn merge_mcp_param( - name: &str, - opts: &Value, - override_cfg: Option<&ToolParameterConfig>, - required_in_mcp: bool, -) -> Result { - let kind = match override_cfg.map(|v| v.kind.clone()) { - Some(kind) => kind, - None => match opts.get("type").unwrap_or(&Value::Null) { - Value::String(v) => OneOrManyTypes::One(v.to_owned()), - Value::Array(v) => OneOrManyTypes::Many( - v.iter() - .filter_map(Value::as_str) - .map(str::to_owned) - .collect(), - ), - value => { - if value.is_null() - && let Some(any) = opts - .get("anyOf") - .and_then(Value::as_array) - .map(|v| { - v.iter() - .filter_map(|v| { - v.get("type").and_then(Value::as_str).map(str::to_owned) - }) - .collect::>() - }) - .filter(|v| !v.is_empty()) - { - OneOrManyTypes::Many(any) - } else { - return Err(ToolError::InvalidType { - key: name.to_owned(), - value: value.to_owned(), - need: vec!["string", "array"], - }); - } - } - }, - }; - - let default = override_cfg - .and_then(|v| v.default.clone()) - .or_else(|| opts.get("default").cloned()); - - let description = merge_description( - override_cfg.and_then(|v| v.description.clone()), - opts.get("description").and_then(Value::as_str), - ); - - let mut enumeration: Vec = override_cfg - .map(|v| v.enumeration.clone()) - .into_iter() - .flatten() - .collect(); - - if enumeration.is_empty() { - enumeration = opts - .get("enum") - .and_then(|v| v.as_array()) - .into_iter() - .flatten() - .cloned() - .collect(); - } - - // An MCP tool's parameter `requiredness` can be switched from `false` - // to `true`, but not the other way around. This is because allowing - // this could break the contract with the external tool's expectations. - let required = match (required_in_mcp, override_cfg.map(|v| v.required)) { - (v, None) => v, - (true, _) => true, - (false, Some(cfg)) => cfg, - }; - - // Items: user override wins wholesale (same policy as `kind`). - // Otherwise fall back to the MCP schema, which we can only parse - // when its `items` declares a plain `type` — schemas that use - // `$ref` for items resolve to `None` here, in which case the - // user's TOML is the only path to a usable `items` config. - let items = override_cfg.and_then(|v| v.items.clone()).or_else(|| { - opts.get("items").and_then(|v| v.as_object()).and_then(|v| { - Some(Box::new(ToolParameterConfig { - kind: match v.get("type")? { - Value::String(v) => OneOrManyTypes::One(v.to_owned()), - Value::Array(v) => OneOrManyTypes::Many( - v.iter() - .filter_map(Value::as_str) - .map(str::to_owned) - .collect(), - ), - _ => return None, - }, - default: None, - required: false, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - })) - }) - }); - - // Properties: user override wins when non-empty. We don't currently - // parse nested `properties` from the MCP schema into - // `ToolParameterConfig`, so without an override this stays empty - // — same situation as `items` with a `$ref`. A future change can - // add MCP-side nested-property resolution; that's symmetric with - // the `$ref`-resolution follow-up for `items`. - let properties = override_cfg - .map(|v| v.properties.clone()) - .filter(|p| !p.is_empty()) - .unwrap_or_default(); - - Ok(ToolParameterConfig { - kind, - default, - required, - summary: None, - description, - examples: None, - enumeration, - items, - properties, - }) -} - -/// Merge a user-provided description with an MCP server description. -/// -/// If the user provided a description containing `{{description}}`, the MCP -/// description is substituted in. -/// If the user provided a description without the template, it takes -/// precedence. -/// If no user description exists, the MCP description is used as-is. -fn merge_description(user: Option, mcp: Option<&str>) -> Option { - match (user, mcp) { - (None, Some(mcp)) => Some(mcp.to_owned()), - // TODO: should use `minijinja` instead of raw string replacement. - (Some(desc), Some(mcp)) => Some(desc.replace("{{description}}", mcp)), - (Some(desc), None) => Some(desc), - (None, None) => None, - } -} - #[cfg(test)] #[path = "tool_tests.rs"] mod tests; diff --git a/crates/jp_llm/src/tool/executor.rs b/crates/jp_llm/src/tool/executor.rs index ae2a5bf44..5eae8e37b 100644 --- a/crates/jp_llm/src/tool/executor.rs +++ b/crates/jp_llm/src/tool/executor.rs @@ -308,7 +308,7 @@ impl TestExecutorSource { .map(|name| ToolDefinition { name: name.clone(), docs: super::ToolDocs::default(), - parameters: indexmap::IndexMap::new(), + parameters: serde_json::json!({ "type": "object", "properties": {} }), }) .collect() } diff --git a/crates/jp_llm/src/tool/json_schema.rs b/crates/jp_llm/src/tool/json_schema.rs new file mode 100644 index 000000000..44acc67f9 --- /dev/null +++ b/crates/jp_llm/src/tool/json_schema.rs @@ -0,0 +1,757 @@ +//! JSON Schema for tool parameters: construction, validation, and reading. +//! +//! A tool's parameters are one JSON Schema object, held exactly as its source +//! declared it. +//! For an MCP tool that is the server's `inputSchema` with the user's +//! configured overrides applied; for a local or built-in tool it is generated +//! from configuration. +//! Nothing else rewrites it: adapting a schema to what a given API accepts is +//! the responsibility of that provider. +//! +//! [`Node`] is the read-only view used by argument handling and validation. +//! It follows same-document `$ref` pointers while reading, so a referenced enum +//! or nested object answers questions the same way an inline one does. + +use std::borrow::Cow; + +use indexmap::IndexMap; +use jp_config::conversation::tool::{OneOrManyTypes, ToolParameterConfig}; +use serde_json::{Map, Value, json}; + +use crate::error::ToolError; + +/// JSON types a tool parameter may declare. +const SUPPORTED_TYPES: &[&str] = &[ + "array", "boolean", "integer", "null", "number", "object", "string", +]; + +/// Bound on `$ref` expansion while reading, so a self-referential schema +/// terminates. +const MAX_REF_HOPS: usize = 32; + +/// Build the parameters schema for a tool whose shape is defined entirely in +/// configuration. +/// +/// Local and built-in tools have no upstream schema, so every parameter must +/// declare a type. +pub fn from_config( + path: &str, + parameters: &IndexMap, +) -> Result { + let mut properties = Map::new(); + let mut required = vec![]; + + for (name, parameter) in parameters { + let node = node_from_config(&format!("{path}.{name}"), parameter)?; + if parameter.required.unwrap_or(false) { + required.push(Value::String(name.clone())); + } + properties.insert(name.clone(), node); + } + + Ok(object_schema(properties, required)) +} + +/// Apply configured overrides to a schema declared by an MCP server. +/// +/// The server's document is preserved, including any `$defs` block. +/// An override may narrow a parameter, but may not contradict the type the +/// server declared. +pub fn with_overrides( + path: &str, + source: &Value, + overrides: &IndexMap, +) -> Result { + let mut schema = source.as_object().cloned().unwrap_or_default(); + let source_required = required_names(source); + + let mut properties = source + .get("properties") + .and_then(Value::as_object) + .cloned() + .unwrap_or_default(); + let mut required = source_required + .iter() + .map(|name| Value::String((*name).to_owned())) + .collect::>(); + + for (name, override_config) in overrides { + let path = format!("{path}.{name}"); + let node = match properties.get(name) { + Some(node) => node_with_override(&path, node, source, override_config)?, + None => node_from_config(&path, override_config)?, + }; + properties.insert(name.clone(), node); + + // A server's requirement cannot be relaxed, only added to: dropping it + // would produce calls that omit an argument the server expects. + let named = Value::String(name.clone()); + if override_config.required == Some(true) && !required.contains(&named) { + required.push(named); + } + } + + schema.insert("properties".to_owned(), Value::Object(properties)); + schema.insert("required".to_owned(), Value::Array(required)); + schema.insert("type".to_owned(), Value::String("object".to_owned())); + + Ok(Value::Object(schema)) +} + +/// Validate a tool's parameters schema. +/// +/// Rejects the shapes that no provider can act on, and the ones that contradict +/// themselves: unusable types, arrays with no item schema, `items` or +/// `properties` on a type that cannot carry them, duplicate or ill-typed enum +/// values, and defaults the schema itself forbids. +pub fn validate(path: &str, schema: &Value) -> Result<(), ToolError> { + let root = Node::root(schema); + for (name, property) in root.properties() { + validate_node(&format!("{path}.{name}"), &property, &mut vec![])?; + } + + Ok(()) +} + +/// Validate one node, tracking which definitions the walk is already inside. +/// +/// A recursive schema is legal, and providers that reject it say so themselves. +/// Re-entering a definition already on the path adds nothing, so the walk stops +/// there instead of expanding forever. +fn validate_node(path: &str, node: &Node<'_>, visiting: &mut Vec) -> Result<(), ToolError> { + if let Some(origin) = node.origin() { + if visiting.iter().any(|seen| seen == origin) { + return Ok(()); + } + visiting.push(origin.to_owned()); + } + + let result = validate_node_inner(path, node, visiting); + + if node.origin().is_some() { + visiting.pop(); + } + + result +} + +fn validate_node_inner( + path: &str, + node: &Node<'_>, + visiting: &mut Vec, +) -> Result<(), ToolError> { + let types = node.types(); + validate_types(path, &types)?; + + let items = node.items(); + if types.iter().any(|type_| type_ == "array") && items.is_none() { + return Err(ToolError::InvalidSchema { + path: format!("{path}.items"), + message: "array schemas must declare an item schema".to_owned(), + }); + } + + if let Some(items) = &items { + if !types.iter().any(|type_| type_ == "array") { + return Err(ToolError::InvalidSchema { + path: format!("{path}.items"), + message: format!( + "`items` requires an array type, but the schema requires {}", + format_types(&types) + ), + }); + } + validate_node(&format!("{path}.items"), items, visiting)?; + } + + let properties = node.properties(); + if !properties.is_empty() && !types.iter().any(|type_| type_ == "object") { + return Err(ToolError::InvalidSchema { + path: format!("{path}.properties"), + message: format!( + "`properties` requires an object type, but the schema requires {}", + format_types(&types) + ), + }); + } + for (name, property) in properties { + validate_node(&format!("{path}.properties.{name}"), &property, visiting)?; + } + + let enumeration = node.enumeration(); + for (index, value) in enumeration.iter().enumerate() { + if enumeration[..index].contains(value) { + return Err(ToolError::InvalidSchema { + path: format!("{path}.enum"), + message: format!("enum values must be unique; duplicate value {value}"), + }); + } + + if node.accepts(value) { + validate_value(&format!("{path}.enum[{index}]"), value, node, "enum value")?; + continue; + } + + let hint = if types.iter().any(|type_| type_ == "array") && !value.is_array() { + format!("; use `{path}.items.enum` to constrain array elements") + } else { + String::new() + }; + return Err(ToolError::InvalidSchema { + path: format!("{path}.enum"), + message: format!( + "enum value {value} has type {}, but the schema requires {}{hint}", + value_type(value), + format_types(&types), + ), + }); + } + + if let Some(default) = node.default() { + validate_value(&format!("{path}.default"), default, node, "default value")?; + } + + Ok(()) +} + +/// Validate a schema-declared value against the node it appears in. +/// +/// Applies the node's type and `enum`, then recurses into array elements and +/// object properties so nested constraints are enforced at every depth. +/// `subject` names what is being checked (`default value`, `enum value`) for +/// the error message. +fn validate_value( + path: &str, + value: &Value, + node: &Node<'_>, + subject: &str, +) -> Result<(), ToolError> { + if !node.accepts(value) { + return Err(ToolError::InvalidSchema { + path: path.to_owned(), + message: format!( + "{subject} {value} has type {}, but the schema requires {}", + value_type(value), + format_types(&node.types()) + ), + }); + } + + let enumeration = node.enumeration(); + if !enumeration.is_empty() && !enumeration.contains(value) { + return Err(ToolError::InvalidSchema { + path: path.to_owned(), + message: format!("{subject} {value} is not allowed by the enum"), + }); + } + + if let (Value::Array(values), Some(items)) = (value, node.items()) { + for (index, value) in values.iter().enumerate() { + validate_value(&format!("{path}[{index}]"), value, &items, subject)?; + } + } + + if let Value::Object(values) = value { + for (name, property) in node.properties() { + let Some(value) = values.get(&name) else { + if node.is_required(&name) { + return Err(ToolError::InvalidSchema { + path: format!("{path}.{name}"), + message: format!("{subject} is missing required property `{name}`"), + }); + } + continue; + }; + validate_value(&format!("{path}.{name}"), value, &property, subject)?; + } + } + + Ok(()) +} + +fn validate_types(path: &str, types: &[String]) -> Result<(), ToolError> { + if types.is_empty() { + return Err(ToolError::InvalidSchema { + path: format!("{path}.type"), + message: "schema does not declare a supported type".to_owned(), + }); + } + + for (index, type_) in types.iter().enumerate() { + if !SUPPORTED_TYPES.contains(&type_.as_str()) { + return Err(ToolError::InvalidSchema { + path: format!("{path}.type"), + message: format!("unsupported JSON type `{type_}`"), + }); + } + if types[..index].contains(type_) { + return Err(ToolError::InvalidSchema { + path: format!("{path}.type"), + message: format!("type values must be unique; duplicate type `{type_}`"), + }); + } + } + + Ok(()) +} + +/// Expand every same-document `$ref` and drop the definitions block. +/// +/// For providers that cannot follow references. +/// A reference that cannot be resolved, or one that revisits a definition +/// already being expanded, is left in place: a recursive type has no finite +/// expansion, and dropping the node would be worse than forwarding something +/// the API can reject. +#[must_use] +pub fn inline(schema: &Value) -> Value { + let mut inlined = inline_node(schema, schema, &mut vec![]); + if let Some(object) = inlined.as_object_mut() { + object.remove("$defs"); + object.remove("definitions"); + } + + inlined +} + +fn inline_node(node: &Value, root: &Value, expanding: &mut Vec) -> Value { + let pointer = pointer_of(node); + if let Some(pointer) = &pointer { + if expanding.contains(pointer) { + return node.clone(); + } + expanding.push(pointer.clone()); + } + + let resolved = resolve(node, root); + let expanded = match resolved.as_object() { + Some(object) => Value::Object( + object + .iter() + .map(|(key, value)| { + let value = match value { + Value::Object(_) => inline_node(value, root, expanding), + Value::Array(values) => Value::Array( + values + .iter() + .map(|value| inline_node(value, root, expanding)) + .collect(), + ), + other => other.clone(), + }; + (key.clone(), value) + }) + .collect(), + ), + None => resolved.into_owned(), + }; + + if pointer.is_some() { + expanding.pop(); + } + + expanded +} + +/// A read-only view of one schema node, resolving `$ref` as it reads. +#[derive(Debug, Clone)] +pub struct Node<'a> { + root: &'a Value, + node: Cow<'a, Value>, + origin: Option, +} + +impl<'a> Node<'a> { + /// View a whole parameters schema, where `$ref` pointers resolve against + /// the same document. + #[must_use] + pub fn root(schema: &'a Value) -> Self { + Self { + root: schema, + node: resolve(schema, schema), + origin: pointer_of(schema), + } + } + + /// The `$ref` pointer this node was reached through, when it was one. + #[must_use] + pub fn origin(&self) -> Option<&str> { + self.origin.as_deref() + } + + /// View a nested node, resolving it against the same document. + /// + /// The node is cloned because resolving a `$ref` produces a new value that + /// cannot borrow from the parent. + fn child(&self, node: &Value) -> Node<'a> { + Node { + root: self.root, + node: Cow::Owned(resolve(node, self.root).into_owned()), + origin: pointer_of(node), + } + } + + /// JSON types this node accepts. + #[must_use] + pub fn types(&self) -> Vec { + match self.node.get("type") { + Some(Value::String(type_)) => vec![type_.clone()], + Some(Value::Array(types)) => types + .iter() + .filter_map(Value::as_str) + .map(str::to_owned) + .collect(), + _ => vec![], + } + } + + /// Whether a value satisfies this node's declared types. + #[must_use] + pub fn accepts(&self, value: &Value) -> bool { + let types = self.types(); + let has = |type_: &str| types.iter().any(|candidate| candidate == type_); + + match value { + Value::Null => has("null"), + Value::Bool(_) => has("boolean"), + Value::Number(number) => { + has("number") || (has("integer") && (number.is_i64() || number.is_u64())) + } + Value::String(_) => has("string"), + Value::Array(_) => has("array"), + Value::Object(_) => has("object"), + } + } + + /// The value inserted when the argument is omitted. + #[must_use] + pub fn default(&self) -> Option<&Value> { + // The borrow has to come from the node itself, which `Cow` owns when a + // `$ref` was inlined, so match rather than returning through the Cow. + match &self.node { + Cow::Borrowed(node) => node.get("default"), + Cow::Owned(node) => node.get("default"), + } + } + + /// Values this node accepts, empty when unconstrained. + #[must_use] + pub fn enumeration(&self) -> Vec { + self.node + .get("enum") + .and_then(Value::as_array) + .cloned() + .unwrap_or_default() + } + + /// The schema applied to each array element. + #[must_use] + pub fn items(&self) -> Option> { + self.node.get("items").map(|items| self.child(items)) + } + + /// The schemas for this node's object properties, in declaration order. + #[must_use] + pub fn properties(&self) -> Vec<(String, Node<'a>)> { + self.node + .get("properties") + .and_then(Value::as_object) + .map(|properties| { + properties + .iter() + .map(|(name, node)| (name.clone(), self.child(node))) + .collect() + }) + .unwrap_or_default() + } + + /// Whether this node lists `name` among its required properties. + #[must_use] + pub fn is_required(&self, name: &str) -> bool { + required_names(&self.node).contains(&name) + } + + /// The description sent to the model for this node. + #[must_use] + pub fn description(&self) -> Option<&str> { + match &self.node { + Cow::Borrowed(node) => node.get("description"), + Cow::Owned(node) => node.get("description"), + } + .and_then(Value::as_str) + } + + /// Whether this node declares any property. + #[must_use] + pub fn has_properties(&self) -> bool { + self.node + .get("properties") + .and_then(Value::as_object) + .is_some_and(|properties| !properties.is_empty()) + } +} + +impl PartialEq for Node<'_> { + fn eq(&self, other: &Self) -> bool { + self.node == other.node + } +} + +/// Follow same-document `$ref` pointers, merging sibling keys over the target. +/// +/// Sibling keys win, per JSON Schema 2020-12. +/// A pointer that leaves the document or revisits one already followed is left +/// in place, so reading degrades to "this node declares nothing" rather than +/// looping. +fn resolve<'a>(node: &'a Value, root: &Value) -> Cow<'a, Value> { + let mut current = Cow::Borrowed(node); + let mut seen: Vec = vec![]; + + while let Some(pointer) = current.get("$ref").and_then(Value::as_str) { + let pointer = pointer.to_owned(); + if seen.len() >= MAX_REF_HOPS || seen.contains(&pointer) { + break; + } + + let Some(target) = follow_pointer(&pointer, root) else { + break; + }; + + let mut merged = target; + for (key, value) in current.as_object().into_iter().flatten() { + if key != "$ref" { + merged.insert(key.clone(), value.clone()); + } + } + + seen.push(pointer); + current = Cow::Owned(Value::Object(merged)); + } + + current +} + +fn pointer_of(node: &Value) -> Option { + node.get("$ref").and_then(Value::as_str).map(str::to_owned) +} + +/// Look up a same-document JSON pointer, such as `#/$defs/EntryType`. +fn follow_pointer(pointer: &str, root: &Value) -> Option> { + if pointer == "#" { + return root.as_object().cloned(); + } + + let mut current = root; + for segment in pointer.strip_prefix("#/")?.split('/') { + current = current.get(segment.replace("~1", "/").replace("~0", "~"))?; + } + + current.as_object().cloned() +} + +fn required_names(schema: &Value) -> Vec<&str> { + schema + .get("required") + .and_then(Value::as_array) + .into_iter() + .flatten() + .filter_map(Value::as_str) + .collect() +} + +fn object_schema(properties: Map, required: Vec) -> Value { + json!({ + "type": "object", + "properties": Value::Object(properties), + "required": Value::Array(required), + }) +} + +/// Build one schema node from configuration alone. +fn node_from_config(path: &str, config: &ToolParameterConfig) -> Result { + let kind = config + .kind + .as_ref() + .ok_or_else(|| ToolError::InvalidSchema { + path: format!("{path}.type"), + message: "local and built-in tool parameters must declare a type".to_owned(), + })?; + + let mut node = Map::new(); + node.insert("type".to_owned(), types_to_json(kind)); + apply_config_fields(path, &mut node, &Value::Null, config)?; + + Ok(Value::Object(node)) +} + +/// Overlay configuration onto a node the source already declared. +fn node_with_override( + path: &str, + source: &Value, + root: &Value, + config: &ToolParameterConfig, +) -> Result { + let mut node = source.as_object().cloned().unwrap_or_default(); + + if let Some(kind) = &config.kind { + // The source keeps its own declaration; an override may restate it but + // not contradict it, since the source owns the contract. Resolving + // against the document is what lets a referenced type be compared. + let declared = Node::root(root).child(source).types(); + if !declared.is_empty() && !types_match(&declared, kind) { + return Err(ToolError::InvalidSchema { + path: format!("{path}.type"), + message: format!( + "MCP declares {}, but the configuration declares {}", + format_types(&declared), + format_types(&type_names(kind)) + ), + }); + } + validate_types(path, &type_names(kind))?; + if declared.is_empty() { + node.insert("type".to_owned(), types_to_json(kind)); + } + } + + apply_config_fields(path, &mut node, root, config)?; + + Ok(Value::Object(node)) +} + +/// Apply the override fields shared by both construction paths. +/// +/// `root` is the document nested nodes resolve against; it is [`Value::Null`] +/// when the schema is built from configuration alone. +fn apply_config_fields( + path: &str, + node: &mut Map, + root: &Value, + config: &ToolParameterConfig, +) -> Result<(), ToolError> { + if let Some(default) = &config.default { + node.insert("default".to_owned(), default.clone()); + } + if let Some(enumeration) = &config.enumeration { + if enumeration.is_empty() { + node.remove("enum"); + } else { + node.insert("enum".to_owned(), Value::Array(enumeration.clone())); + } + } + if let Some(description) = config.summary.as_ref().or(config.description.as_ref()) { + let source = node.get("description").and_then(Value::as_str); + if let Some(merged) = merge_description(Some(description.clone()), source) { + node.insert("description".to_owned(), Value::String(merged)); + } + } + + if let Some(items) = config.items.as_deref() { + let path = format!("{path}.items"); + let merged = match node.get("items") { + Some(source) => node_with_override(&path, source, root, items)?, + None => node_from_config(&path, items)?, + }; + node.insert("items".to_owned(), merged); + } + + if !config.properties.is_empty() { + let mut properties = node + .get("properties") + .and_then(Value::as_object) + .cloned() + .unwrap_or_default(); + let mut required = node + .get("required") + .and_then(Value::as_array) + .cloned() + .unwrap_or_default(); + + for (name, property) in &config.properties { + let path = format!("{path}.properties.{name}"); + let merged = match properties.get(name) { + Some(source) => node_with_override(&path, source, root, property)?, + None => node_from_config(&path, property)?, + }; + properties.insert(name.clone(), merged); + + let named = Value::String(name.clone()); + if property.required == Some(true) && !required.contains(&named) { + required.push(named); + } + } + + node.insert("properties".to_owned(), Value::Object(properties)); + if !required.is_empty() { + node.insert("required".to_owned(), Value::Array(required)); + } + } + + Ok(()) +} + +fn type_names(types: &OneOrManyTypes) -> Vec { + match types { + OneOrManyTypes::One(type_) => vec![type_.clone()], + OneOrManyTypes::Many(types) => types.clone(), + } +} + +fn types_to_json(types: &OneOrManyTypes) -> Value { + match types { + OneOrManyTypes::One(type_) => Value::String(type_.clone()), + OneOrManyTypes::Many(types) => { + Value::Array(types.iter().cloned().map(Value::String).collect()) + } + } +} + +/// Whether two type declarations describe the same set of JSON types. +/// +/// JSON Schema type arrays are unordered, and a single-element array means the +/// same thing as a bare string, so `["null", "string"]`, `["string", "null"]` +/// and `"string"` all compare equal. +fn types_match(left: &[String], right: &OneOrManyTypes) -> bool { + let normalize = |mut types: Vec| { + types.sort_unstable(); + types.dedup(); + types + }; + + normalize(left.to_vec()) == normalize(type_names(right)) +} + +/// Merge a user-provided description with the one the source declared. +/// +/// A user description containing `{{description}}` has the source's text +/// substituted in; otherwise the user's text wins outright. +/// With no user description the source's is kept as-is. +#[must_use] +pub fn merge_description(user: Option, source: Option<&str>) -> Option { + match (user, source) { + (None, Some(source)) => Some(source.to_owned()), + // TODO: should use `minijinja` instead of raw string replacement. + (Some(user), Some(source)) => Some(user.replace("{{description}}", source)), + (Some(user), None) => Some(user), + (None, None) => None, + } +} + +fn value_type(value: &Value) -> &'static str { + match value { + Value::Null => "null", + Value::Bool(_) => "boolean", + Value::Number(number) if number.is_i64() || number.is_u64() => "integer", + Value::Number(_) => "number", + Value::String(_) => "string", + Value::Array(_) => "array", + Value::Object(_) => "object", + } +} + +fn format_types(types: &[String]) -> String { + types.join(" or ") +} + +#[cfg(test)] +#[path = "json_schema_tests.rs"] +mod tests; diff --git a/crates/jp_llm/src/tool/json_schema_tests.rs b/crates/jp_llm/src/tool/json_schema_tests.rs new file mode 100644 index 000000000..d5516292d --- /dev/null +++ b/crates/jp_llm/src/tool/json_schema_tests.rs @@ -0,0 +1,629 @@ +use indexmap::IndexMap; +use jp_config::conversation::tool::ToolParameterConfig; +use serde_json::json; + +use super::*; + +/// Parse a parameter override the way a configuration file would produce it. +fn config(value: serde_json::Value) -> ToolParameterConfig { + serde_json::from_value(value).expect("valid parameter config") +} + +fn configs(values: &[(&str, serde_json::Value)]) -> IndexMap { + values + .iter() + .map(|(name, value)| ((*name).to_owned(), config(value.clone()))) + .collect() +} + +fn error_of(result: Result) -> String { + result.unwrap_err().to_string() +} + +mod from_config { + use super::*; + + #[test] + fn builds_an_object_schema() { + let parameters = configs(&[ + ("path", json!({ "type": "string", "required": true })), + ( + "limit", + json!({ "type": "integer", "default": 10, "summary": "How many." }), + ), + ]); + + let schema = from_config("tools.demo.parameters", ¶meters).unwrap(); + + assert_eq!( + schema, + json!({ + "type": "object", + "properties": { + "path": { "type": "string" }, + "limit": { "type": "integer", "default": 10, "description": "How many." } + }, + "required": ["path"] + }) + ); + } + + #[test] + fn builds_nested_arrays_and_objects() { + let parameters = configs(&[ + ( + "tags", + json!({ "type": "array", "items": { "type": "string", "enum": ["a", "b"] } }), + ), + ( + "target", + json!({ + "type": "object", + "properties": { "path": { "type": "string", "required": true } } + }), + ), + ]); + + let schema = from_config("tools.demo.parameters", ¶meters).unwrap(); + + assert_eq!( + schema, + json!({ + "type": "object", + "properties": { + "tags": { + "type": "array", + "items": { "type": "string", "enum": ["a", "b"] } + }, + "target": { + "type": "object", + "properties": { "path": { "type": "string" } }, + "required": ["path"] + } + }, + "required": [] + }) + ); + } + + #[test] + fn a_parameter_without_a_type_is_rejected() { + let parameters = configs(&[("path", json!({ "summary": "Where." }))]); + + assert_eq!( + error_of(from_config("tools.demo.parameters", ¶meters)), + "Invalid schema at `tools.demo.parameters.path.type`: local and built-in tool \ + parameters must declare a type" + ); + } +} + +mod with_overrides { + use super::*; + + /// The server's document is the source of truth: anything the override does + /// not speak to survives untouched, `$defs` included. + #[test] + fn preserves_the_server_document() { + let source = json!({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "CreateNote", + "properties": { + "title": { "type": "string" }, + "tags": { "type": "array", "items": { "$ref": "#/$defs/Tag" } } + }, + "required": ["title"], + "$defs": { + "Tag": { "type": "string" } + } + }); + let overrides = configs(&[("tags", json!({ "items": { "enum": ["task", "idea"] } }))]); + + let schema = with_overrides("tools.notes.parameters", &source, &overrides).unwrap(); + + assert_eq!( + schema, + json!({ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "title": "CreateNote", + "properties": { + "title": { "type": "string" }, + "tags": { + "type": "array", + "items": { "$ref": "#/$defs/Tag", "enum": ["task", "idea"] } + } + }, + "required": ["title"], + "$defs": { + "Tag": { "type": "string" } + } + }) + ); + } + + /// The reference stays a reference. + /// Narrowing it adds a sibling keyword rather than expanding the definition + /// into the document. + #[test] + fn a_referenced_item_keeps_its_reference() { + let source = json!({ + "type": "object", + "properties": { + "kinds": { "type": "array", "items": { "$ref": "#/$defs/EntryType" } } + }, + "$defs": { "EntryType": { "type": "string", "enum": ["Enum", "Method"] } } + }); + let overrides = configs(&[("kinds", json!({ "items": { "type": "string" } }))]); + + let schema = with_overrides("tools.docs.parameters", &source, &overrides).unwrap(); + + assert_eq!( + schema["properties"]["kinds"]["items"], + json!({ "$ref": "#/$defs/EntryType" }) + ); + } + + #[test] + fn an_empty_enum_clears_an_inherited_one() { + let source = json!({ + "type": "object", + "properties": { "state": { "type": "string", "enum": ["open", "closed"] } } + }); + let overrides = configs(&[("state", json!({ "enum": [] }))]); + + let schema = with_overrides("tools.demo.parameters", &source, &overrides).unwrap(); + + assert_eq!(schema["properties"]["state"], json!({ "type": "string" })); + } + + #[test] + fn a_contradicting_type_is_rejected() { + let source = json!({ + "type": "object", + "properties": { "count": { "type": "integer" } } + }); + let overrides = configs(&[("count", json!({ "type": "string" }))]); + + assert_eq!( + error_of(with_overrides("tools.demo.parameters", &source, &overrides)), + "Invalid schema at `tools.demo.parameters.count.type`: MCP declares integer, but the \ + configuration declares string" + ); + } + + /// A referenced type is compared through the document, so restating it + /// correctly is accepted and restating it wrongly is not. + #[test] + fn a_contradicting_type_is_rejected_through_a_reference() { + let source = json!({ + "type": "object", + "properties": { "kind": { "$ref": "#/$defs/Kind" } }, + "$defs": { "Kind": { "type": "string" } } + }); + let overrides = configs(&[("kind", json!({ "type": "integer" }))]); + + assert_eq!( + error_of(with_overrides("tools.demo.parameters", &source, &overrides)), + "Invalid schema at `tools.demo.parameters.kind.type`: MCP declares string, but the \ + configuration declares integer" + ); + } + + /// JSON Schema type arrays are unordered, and a single-element array means + /// the same as the bare string. + #[test] + fn a_matching_type_may_be_restated_in_any_form() { + let source = json!({ + "type": "object", + "properties": { + "content": { "type": ["string", "null"] }, + "name": { "type": "string" } + } + }); + let overrides = configs(&[ + ("content", json!({ "type": ["null", "string"] })), + ("name", json!({ "type": ["string"] })), + ]); + + let schema = with_overrides("tools.demo.parameters", &source, &overrides).unwrap(); + + assert_eq!( + schema["properties"]["content"]["type"], + json!(["string", "null"]) + ); + assert_eq!(schema["properties"]["name"]["type"], json!("string")); + } + + #[test] + fn required_can_be_tightened_but_not_loosened() { + let source = json!({ + "type": "object", + "properties": { "a": { "type": "string" }, "b": { "type": "string" } }, + "required": ["b"] + }); + let overrides = configs(&[ + ("a", json!({ "required": true })), + ("b", json!({ "required": false })), + ]); + + let schema = with_overrides("tools.demo.parameters", &source, &overrides).unwrap(); + + assert_eq!(schema["required"], json!(["b", "a"])); + } + + #[test] + fn a_property_the_server_omits_is_added() { + let source = json!({ "type": "object", "properties": {} }); + let overrides = configs(&[("extra", json!({ "type": "string", "summary": "Added." }))]); + + let schema = with_overrides("tools.demo.parameters", &source, &overrides).unwrap(); + + assert_eq!( + schema["properties"]["extra"], + json!({ "type": "string", "description": "Added." }) + ); + } +} + +mod validate { + use super::*; + + fn validated(schema: &serde_json::Value) -> Result<(), ToolError> { + validate("tools.demo.parameters", schema) + } + + fn message_of(schema: &serde_json::Value) -> String { + validated(schema).unwrap_err().to_string() + } + + #[test] + fn an_array_must_declare_items() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { "tags": { "type": "array" } } + })), + "Invalid schema at `tools.demo.parameters.tags.items`: array schemas must declare an \ + item schema" + ); + } + + #[test] + fn items_require_an_array_type() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { "tags": { "type": "string", "items": { "type": "string" } } } + })), + "Invalid schema at `tools.demo.parameters.tags.items`: `items` requires an array \ + type, but the schema requires string" + ); + } + + #[test] + fn properties_require_an_object_type() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { + "target": { "type": "string", "properties": { "a": { "type": "string" } } } + } + })), + "Invalid schema at `tools.demo.parameters.target.properties`: `properties` requires \ + an object type, but the schema requires string" + ); + } + + #[test] + fn a_scalar_enum_on_an_array_points_at_items() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { + "tags": { + "type": "array", + "items": { "type": "string" }, + "enum": ["projects/jp"] + } + } + })), + "Invalid schema at `tools.demo.parameters.tags.enum`: enum value \"projects/jp\" has \ + type string, but the schema requires array; use \ + `tools.demo.parameters.tags.items.enum` to constrain array elements" + ); + } + + #[test] + fn enum_values_must_be_unique() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { "kind": { "type": "string", "enum": ["task", "task"] } } + })), + "Invalid schema at `tools.demo.parameters.kind.enum`: enum values must be unique; \ + duplicate value \"task\"" + ); + } + + #[test] + fn a_default_outside_the_enum_is_rejected() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { + "state": { "type": "string", "enum": ["open"], "default": "all" } + } + })), + "Invalid schema at `tools.demo.parameters.state.default`: default value \"all\" is \ + not allowed by the enum" + ); + } + + #[test] + fn a_default_must_match_the_item_schema() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { + "tags": { + "type": "array", + "items": { "type": "string" }, + "default": ["task", 1] + } + } + })), + "Invalid schema at `tools.demo.parameters.tags.default[1]`: default value 1 has type \ + integer, but the schema requires string" + ); + } + + #[test] + fn a_default_must_match_a_property_enum() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { + "target": { + "type": "object", + "properties": { "mode": { "type": "string", "enum": ["safe"] } }, + "default": { "mode": "fast" } + } + } + })), + "Invalid schema at `tools.demo.parameters.target.default.mode`: default value \ + \"fast\" is not allowed by the enum" + ); + } + + #[test] + fn an_unsupported_type_is_rejected() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { "name": { "type": "strng" } } + })), + "Invalid schema at `tools.demo.parameters.name.type`: unsupported JSON type `strng`" + ); + } + + #[test] + fn duplicate_types_are_rejected() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { "name": { "type": ["string", "string"] } } + })), + "Invalid schema at `tools.demo.parameters.name.type`: type values must be unique; \ + duplicate type `string`" + ); + } + + #[test] + fn a_node_without_a_usable_type_is_rejected() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { "thing": { "$ref": "https://example.com/schema.json#/Thing" } } + })), + "Invalid schema at `tools.demo.parameters.thing.type`: schema does not declare a \ + supported type" + ); + } + + /// Validation reads through references, so a constraint behind a `$ref` is + /// enforced exactly as an inline one would be. + #[test] + fn constraints_behind_a_reference_are_enforced() { + assert_eq!( + message_of(&json!({ + "type": "object", + "properties": { + "kind": { "$ref": "#/$defs/Kind", "default": "fast" } + }, + "$defs": { "Kind": { "type": "string", "enum": ["safe"] } } + })), + "Invalid schema at `tools.demo.parameters.kind.default`: default value \"fast\" is \ + not allowed by the enum" + ); + } + + /// A self-referential type is legal. + /// Providers that reject recursion say so themselves; validation must + /// terminate rather than expand forever. + #[test] + fn a_recursive_schema_is_accepted() { + assert!( + validated(&json!({ + "type": "object", + "properties": { "node": { "$ref": "#/$defs/Node" } }, + "$defs": { + "Node": { + "type": "object", + "properties": { + "value": { "type": "string" }, + "child": { "$ref": "#/$defs/Node" } + } + } + } + })) + .is_ok() + ); + } + + /// Mutually recursive definitions close the same loop through two pointers. + #[test] + fn mutually_recursive_definitions_are_accepted() { + assert!( + validated(&json!({ + "type": "object", + "properties": { "a": { "$ref": "#/$defs/A" } }, + "$defs": { + "A": { "type": "object", "properties": { "b": { "$ref": "#/$defs/B" } } }, + "B": { "type": "object", "properties": { "a": { "$ref": "#/$defs/A" } } } + } + })) + .is_ok() + ); + } +} + +mod inline { + use super::*; + + #[test] + fn expands_references_and_drops_definitions() { + let expanded = inline(&json!({ + "type": "object", + "properties": { + "kinds": { "type": "array", "items": { "$ref": "#/$defs/EntryType" } } + }, + "$defs": { "EntryType": { "type": "string", "enum": ["Enum"] } } + })); + + assert_eq!( + expanded, + json!({ + "type": "object", + "properties": { + "kinds": { + "type": "array", + "items": { "type": "string", "enum": ["Enum"] } + } + } + }) + ); + } + + #[test] + fn sibling_keys_win_over_the_definition() { + let expanded = inline(&json!({ + "type": "object", + "properties": { + "mode": { "$ref": "#/$defs/Mode", "description": "from the parameter" } + }, + "$defs": { "Mode": { "type": "string", "description": "from defs" } } + })); + + assert_eq!( + expanded["properties"]["mode"], + json!({ "type": "string", "description": "from the parameter" }) + ); + } + + /// A recursive type has no finite expansion, so the innermost reference is + /// left as written rather than looping. + #[test] + fn a_recursive_reference_terminates() { + let expanded = inline(&json!({ + "type": "object", + "properties": { "node": { "$ref": "#/$defs/Node" } }, + "$defs": { + "Node": { + "type": "object", + "properties": { "child": { "$ref": "#/$defs/Node" } } + } + } + })); + + assert_eq!( + expanded["properties"]["node"], + json!({ + "type": "object", + "properties": { "child": { "$ref": "#/$defs/Node" } } + }) + ); + } + + #[test] + fn an_unresolvable_reference_is_left_in_place() { + let expanded = inline(&json!({ + "type": "object", + "properties": { "thing": { "$ref": "https://example.com/s.json#/Thing" } } + })); + + assert_eq!( + expanded["properties"]["thing"], + json!({ "$ref": "https://example.com/s.json#/Thing" }) + ); + } +} + +mod node { + use super::*; + + #[test] + fn reads_through_a_reference() { + let schema = json!({ + "type": "object", + "properties": { "kind": { "$ref": "#/$defs/Kind" } }, + "$defs": { "Kind": { "type": "string", "enum": ["a", "b"] } } + }); + + let root = Node::root(&schema); + let (_, kind) = root + .properties() + .into_iter() + .find(|(name, _)| name == "kind") + .expect("property"); + + assert_eq!(kind.types(), vec!["string".to_owned()]); + assert_eq!(kind.enumeration(), vec![json!("a"), json!("b")]); + assert!(kind.accepts(&json!("a"))); + assert!(!kind.accepts(&json!(1))); + } + + /// Sibling keys win over the referenced definition, per JSON Schema + /// 2020-12. + #[test] + fn sibling_keys_win_over_the_definition() { + let schema = json!({ + "type": "object", + "properties": { + "kind": { "$ref": "#/$defs/Kind", "description": "from the parameter" } + }, + "$defs": { "Kind": { "type": "string", "description": "from defs" } } + }); + + let root = Node::root(&schema); + let (_, kind) = root.properties().into_iter().next().expect("property"); + + assert_eq!(kind.origin(), Some("#/$defs/Kind")); + assert_eq!(kind.types(), vec!["string".to_owned()]); + } + + #[test] + fn reports_required_properties() { + let schema = json!({ + "type": "object", + "properties": { "a": { "type": "string" }, "b": { "type": "string" } }, + "required": ["a"] + }); + + let root = Node::root(&schema); + + assert!(root.is_required("a")); + assert!(!root.is_required("b")); + } +} diff --git a/crates/jp_llm/src/tool_tests.rs b/crates/jp_llm/src/tool_tests.rs index 324996c64..510dddb75 100644 --- a/crates/jp_llm/src/tool_tests.rs +++ b/crates/jp_llm/src/tool_tests.rs @@ -3,6 +3,7 @@ use jp_config::{ AppConfig, Config as _, conversation::tool::{PartialToolConfig, ToolConfig}, }; +use jp_mcp::Client; use jp_tool::Outcome; use super::*; @@ -128,40 +129,82 @@ fn test_execution_outcome_helper_methods() { assert!(cancelled.is_cancelled()); } -/// Build a minimal `ToolParameterConfig` for use in validation tests. -fn param(kind: &str, required: bool) -> ToolParameterConfig { - ToolParameterConfig { - kind: kind.to_owned().into(), - required, - default: None, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - } +/// Build a parameters schema from `(name, node, required)` triples. +fn schema(properties: [(&str, Value, bool); N]) -> Value { + let required = properties + .iter() + .filter(|(_, _, required)| *required) + .map(|(name, _, _)| Value::String((*name).to_owned())) + .collect::>(); + let properties = properties + .into_iter() + .map(|(name, node, _)| (name.to_owned(), node)) + .collect::>(); + + json!({ "type": "object", "properties": properties, "required": required }) +} + +/// A schema node of the given type. +fn param(kind: &str) -> Value { + json!({ "type": kind }) +} + +#[tokio::test] +async fn local_tool_rejects_scalar_enum_on_array_parameter() { + let partial: PartialToolConfig = serde_json::from_value(json!({ + "source": "local", + "parameters": { + "tags": { + "type": "array", + "enum": ["projects/jp", "task", "idea"], + "items": { "type": "string" } + } + } + })) + .unwrap(); + let tool = ToolConfig::from_partial(partial, vec![]).unwrap(); + let mut app = AppConfig::new_test(); + app.conversation + .tools + .insert("bear_note_create".to_owned(), tool); + let config = app.conversation.tools.get("bear_note_create").unwrap(); + + let error = resolve_tool("bear_note_create", &config, &Client::new(IndexMap::new())) + .await + .unwrap_err(); + + assert_eq!( + error.to_string(), + "Invalid schema at `conversation.tools.bear_note_create.parameters.tags.enum`: enum value \ + \"projects/jp\" has type string, but the schema requires array; use \ + `conversation.tools.bear_note_create.parameters.tags.items.enum` to constrain array \ + elements" + ); } #[test] fn coerces_json_strings_to_declared_parameter_types() { - let parameters = IndexMap::from_iter([ - ("path".to_owned(), param("string", true)), - ("start_line".to_owned(), param("integer", false)), - ("enabled".to_owned(), param("boolean", false)), - ("string_or_integer".to_owned(), ToolParameterConfig { - kind: vec!["string".to_owned(), "integer".to_owned()].into(), - ..param("string", false) - }), - ("patterns".to_owned(), ToolParameterConfig { - kind: "array".to_owned().into(), - items: Some(Box::new(ToolParameterConfig { - kind: "object".to_owned().into(), - properties: IndexMap::from_iter([("count".to_owned(), param("integer", true))]), - ..param("object", false) - })), - ..param("array", false) - }), + let parameters = schema([ + ("path", param("string"), true), + ("start_line", param("integer"), false), + ("enabled", param("boolean"), false), + ( + "string_or_integer", + json!({ "type": ["string", "integer"] }), + false, + ), + ( + "patterns", + json!({ + "type": "array", + "items": { + "type": "object", + "properties": { "count": { "type": "integer" } }, + "required": ["count"] + } + }), + false, + ), ]); let mut arguments = json!({ "path": "README.md", @@ -208,7 +251,7 @@ async fn execute_coerces_json_strings_before_calling_tool() { let definition = ToolDefinition { name: "echo_arguments".to_owned(), docs: ToolDocs::default(), - parameters: IndexMap::from_iter([("start_line".to_owned(), param("integer", false))]), + parameters: schema([("start_line", param("integer"), false)]), }; let builtins = builtin::BuiltinExecutors::new().register("echo_arguments", EchoArguments); @@ -218,7 +261,7 @@ async fn execute_coerces_json_strings_before_calling_tool() { json!({"start_line": "1"}), &IndexMap::new(), &config, - &jp_mcp::Client::new(IndexMap::new()), + &Client::new(IndexMap::new()), Utf8Path::new("/tmp"), CancellationToken::new(), &builtins, @@ -239,27 +282,27 @@ async fn execute_coerces_json_strings_before_calling_tool() { fn test_validate_tool_arguments() { struct TestCase { arguments: Map, - parameters: IndexMap, + parameters: Value, want: Result<(), ToolError>, } let cases = vec![ ("empty", TestCase { arguments: Map::new(), - parameters: IndexMap::new(), + parameters: schema([]), want: Ok(()), }), ("correct", TestCase { arguments: Map::from_iter([("foo".to_owned(), json!("bar"))]), - parameters: IndexMap::from_iter([ - ("foo".to_owned(), param("string", true)), - ("bar".to_owned(), param("string", false)), + parameters: schema([ + ("foo", param("string"), true), + ("bar", param("string"), false), ]), want: Ok(()), }), ("missing", TestCase { arguments: Map::new(), - parameters: IndexMap::from_iter([("foo".to_owned(), param("string", true))]), + parameters: schema([("foo", param("string"), true)]), want: Err(ToolError::Arguments { missing: vec!["foo".to_owned()], unknown: vec![], @@ -267,7 +310,7 @@ fn test_validate_tool_arguments() { }), ("unknown", TestCase { arguments: Map::from_iter([("foo".to_owned(), json!("bar"))]), - parameters: IndexMap::from_iter([("bar".to_owned(), param("string", false))]), + parameters: schema([("bar", param("string"), false)]), want: Err(ToolError::Arguments { missing: vec![], unknown: vec!["foo".to_owned()], @@ -275,7 +318,7 @@ fn test_validate_tool_arguments() { }), ("both", TestCase { arguments: Map::from_iter([("foo".to_owned(), json!("bar"))]), - parameters: IndexMap::from_iter([("bar".to_owned(), param("string", true))]), + parameters: schema([("bar", param("string"), true)]), want: Err(ToolError::Arguments { missing: vec!["bar".to_owned()], unknown: vec!["foo".to_owned()], @@ -293,22 +336,23 @@ fn test_validate_tool_arguments() { fn test_validate_nested_array_item_properties() { // Mirrors the fs_modify_file schema: // patterns: array of { old: string (required), new: string (required) } - let parameters = IndexMap::from_iter([ - ("path".to_owned(), param("string", true)), - ("patterns".to_owned(), ToolParameterConfig { - kind: "array".to_owned().into(), - required: true, - items: Some(Box::new(ToolParameterConfig { - kind: "object".to_owned().into(), - required: false, - properties: IndexMap::from_iter([ - ("old".to_owned(), param("string", true)), - ("new".to_owned(), param("string", true)), - ]), - ..param("object", false) - })), - ..param("array", true) - }), + let parameters = schema([ + ("path", param("string"), true), + ( + "patterns", + json!({ + "type": "array", + "items": { + "type": "object", + "properties": { + "old": { "type": "string" }, + "new": { "type": "string" } + }, + "required": ["old", "new"] + } + }), + true, + ), ]); // Valid: correct inner fields. @@ -400,17 +444,20 @@ fn test_validate_nested_array_item_properties() { #[test] fn test_validate_nested_object_properties() { - let parameters = IndexMap::from_iter([ - ("name".to_owned(), param("string", true)), - ("config".to_owned(), ToolParameterConfig { - kind: "object".to_owned().into(), - required: false, - properties: IndexMap::from_iter([ - ("verbose".to_owned(), param("boolean", false)), - ("output".to_owned(), param("string", true)), - ]), - ..param("object", false) - }), + let parameters = schema([ + ("name", param("string"), true), + ( + "config", + json!({ + "type": "object", + "properties": { + "verbose": { "type": "boolean" }, + "output": { "type": "string" } + }, + "required": ["output"] + }), + false, + ), ]); // Valid. @@ -448,21 +495,19 @@ fn test_validate_nested_object_properties() { ); } -/// Build a parameter with a default value. -fn param_with_default(kind: &str, required: bool, default: Value) -> ToolParameterConfig { - ToolParameterConfig { - default: Some(default), - ..param(kind, required) - } +/// A schema node of the given type, carrying a default value. +fn param_with_default(kind: &str, default: &Value) -> Value { + json!({ "type": kind, "default": default }) } #[test] fn test_apply_defaults_fills_missing_required_with_default() { - let parameters = IndexMap::from_iter([ - ("path".to_owned(), param("string", true)), + let parameters = schema([ + ("path", param("string"), true), ( - "use_regex".to_owned(), - param_with_default("boolean", true, json!(false)), + "use_regex", + param_with_default("boolean", &json!(false)), + true, ), ]); @@ -476,9 +521,10 @@ fn test_apply_defaults_fills_missing_required_with_default() { #[test] fn test_apply_defaults_does_not_overwrite_provided_values() { - let parameters = IndexMap::from_iter([( - "use_regex".to_owned(), - param_with_default("boolean", true, json!(false)), + let parameters = schema([( + "use_regex", + param_with_default("boolean", &json!(false)), + true, )]); let mut args: Map = Map::from_iter([("use_regex".to_owned(), json!(true))]); @@ -490,9 +536,10 @@ fn test_apply_defaults_does_not_overwrite_provided_values() { #[test] fn test_apply_defaults_fills_optional_param_with_default() { - let parameters = IndexMap::from_iter([( - "verbose".to_owned(), - param_with_default("boolean", false, json!(false)), + let parameters = schema([( + "verbose", + param_with_default("boolean", &json!(false)), + false, )]); let mut args: Map = Map::new(); @@ -503,7 +550,7 @@ fn test_apply_defaults_fills_optional_param_with_default() { #[test] fn test_apply_defaults_skips_params_without_default() { - let parameters = IndexMap::from_iter([("path".to_owned(), param("string", true))]); + let parameters = schema([("path", param("string"), true)]); let mut args: Map = Map::new(); apply_parameter_defaults(&mut args, ¶meters); @@ -513,15 +560,14 @@ fn test_apply_defaults_skips_params_without_default() { #[test] fn test_apply_defaults_recurses_into_objects() { - let parameters = IndexMap::from_iter([("config".to_owned(), ToolParameterConfig { - kind: "object".to_owned().into(), - required: false, - properties: IndexMap::from_iter([( - "verbose".to_owned(), - param_with_default("boolean", false, json!(true)), - )]), - ..param("object", false) - })]); + let parameters = schema([( + "config", + json!({ + "type": "object", + "properties": { "verbose": { "type": "boolean", "default": true } } + }), + false, + )]); let mut args: Map = Map::from_iter([("config".to_owned(), json!({}))]); @@ -532,20 +578,17 @@ fn test_apply_defaults_recurses_into_objects() { #[test] fn test_apply_defaults_recurses_into_array_items() { - let parameters = IndexMap::from_iter([("items".to_owned(), ToolParameterConfig { - kind: "array".to_owned().into(), - required: true, - items: Some(Box::new(ToolParameterConfig { - kind: "object".to_owned().into(), - required: false, - properties: IndexMap::from_iter([( - "enabled".to_owned(), - param_with_default("boolean", false, json!(true)), - )]), - ..param("object", false) - })), - ..param("array", true) - })]); + let parameters = schema([( + "items", + json!({ + "type": "array", + "items": { + "type": "object", + "properties": { "enabled": { "type": "boolean", "default": true } } + } + }), + true, + )]); let mut args: Map = Map::from_iter([( "items".to_owned(), @@ -564,11 +607,12 @@ fn test_apply_defaults_recurses_into_array_items() { fn test_apply_defaults_then_validate_passes() { // Mirrors the fs_modify_file scenario: replace_using_regex is required // with a default, and the LLM omits it. - let parameters = IndexMap::from_iter([ - ("path".to_owned(), param("string", true)), + let parameters = schema([ + ("path", param("string"), true), ( - "replace_using_regex".to_owned(), - param_with_default("boolean", true, json!(false)), + "replace_using_regex", + param_with_default("boolean", &json!(false)), + true, ), ]); @@ -883,13 +927,13 @@ async fn test_execute_local_exposes_invocation_ids_in_context() { let definition = ToolDefinition { name: "echo_ids".to_owned(), docs: ToolDocs::default(), - parameters: IndexMap::new(), + parameters: schema([]), }; let invocation = InvocationContext { workspace_id: "ws-abc".to_owned(), conversation_id: "conv-xyz".to_owned(), }; - let mcp_client = jp_mcp::Client::new(IndexMap::new()); + let mcp_client = Client::new(IndexMap::new()); let builtins = builtin::BuiltinExecutors::new(); let outcome = definition @@ -952,7 +996,7 @@ async fn test_tool_definitions_forced_tool_drops_locked_off() { ToolConfig::from_partial(locked_off, vec![]).expect("resolved tool config"), ); - let mcp_client = jp_mcp::Client::new(IndexMap::new()); + let mcp_client = Client::new(IndexMap::new()); // Forcing the toggleable OFF tool keeps it in the definitions. let defs = tool_definitions(cfg.conversation.tools.iter(), &mcp_client, Some("off_tool")) @@ -977,195 +1021,74 @@ async fn test_tool_definitions_forced_tool_drops_locked_off() { ); } -mod merge_mcp_param { - use indexmap::IndexMap; - use jp_config::conversation::tool::{OneOrManyTypes, ToolParameterConfig}; - use serde_json::{Value, json}; - - use super::super::merge_mcp_param; - - fn cfg(kind: &str) -> ToolParameterConfig { - ToolParameterConfig { - kind: OneOrManyTypes::One(kind.to_owned()), - default: None, - required: false, - summary: None, - description: None, - examples: None, - enumeration: vec![], - items: None, - properties: IndexMap::default(), - } - } - - /// Regression for the `crate_search_items.kinds` case. - /// The MCP schema declares `items: {"$ref": ...}` (no plain `type`), which - /// our parser can't inline. - /// The user's TOML override provides a usable `items` config and must win. - #[test] - fn user_items_override_used_when_mcp_items_lacks_type() { - let opts = json!({ - "type": "array", - "items": { "$ref": "#/$defs/EntryType" } - }); - let override_cfg = ToolParameterConfig { - items: Some(Box::new(cfg("string"))), - ..cfg("array") - }; - - let merged = merge_mcp_param("kinds", &opts, Some(&override_cfg), false).unwrap(); - - let items = merged.items.expect("items should be set from override"); - assert!(matches!( - items.kind, - OneOrManyTypes::One(ref s) if s == "string" - )); - } - - /// When the user override declares `items`, it wins even if the MCP schema - /// also has a usable `items`. - /// Mirrors the existing `kind` / `default` / `enumeration` override - /// semantics. - #[test] - fn user_items_override_replaces_mcp_items() { - let opts = json!({ - "type": "array", - "items": { "type": "integer" } - }); - let override_cfg = ToolParameterConfig { - items: Some(Box::new(cfg("string"))), - ..cfg("array") - }; - - let merged = merge_mcp_param("xs", &opts, Some(&override_cfg), false).unwrap(); - - let items = merged.items.expect("items present"); - assert!(matches!( - items.kind, - OneOrManyTypes::One(ref s) if s == "string" - )); - } - - /// When the user provides no override, fall back to the MCP schema's - /// `items` (existing behavior, preserved by the refactor). - #[test] - fn mcp_items_used_when_no_user_override() { - let opts = json!({ - "type": "array", - "items": { "type": "integer" } - }); - - let merged = merge_mcp_param("xs", &opts, None, false).unwrap(); - - let items = merged.items.expect("items from MCP"); - assert!(matches!( - items.kind, - OneOrManyTypes::One(ref s) if s == "integer" - )); - } - - /// MCP `items` without a parsable `type` (e.g. `$ref`) and no user override - /// results in `items: None`. - /// This is the exact pre-fix state that produced the `array schema missing - /// items` error from OpenAI — documented here so a future change that adds - /// `$ref` resolution will surface as a test update. - #[test] - fn no_items_when_mcp_uses_ref_and_no_user_override() { - let opts = json!({ - "type": "array", - "items": { "$ref": "#/$defs/EntryType" } - }); - - let merged = merge_mcp_param("kinds", &opts, None, false).unwrap(); - - assert!(merged.items.is_none()); - } - - /// User `properties` override is honored, mirroring `items`. - #[test] - fn user_properties_override_is_used() { - let opts = json!({ "type": "object" }); - let mut props = IndexMap::new(); - props.insert("name".to_owned(), cfg("string")); - let override_cfg = ToolParameterConfig { - properties: props, - ..cfg("object") - }; - - let merged = merge_mcp_param("target", &opts, Some(&override_cfg), false).unwrap(); - - assert_eq!(merged.properties.len(), 1); - assert!(merged.properties.contains_key("name")); - } - - /// Empty user properties don't override — falls back to default (currently - /// empty, since MCP-side nested property resolution isn't implemented). - #[test] - fn empty_user_properties_falls_back_to_default() { - let opts = json!({ "type": "object" }); - - let merged = merge_mcp_param("target", &opts, None, false).unwrap(); - - assert!(merged.properties.is_empty()); - } - - /// `required: false → true` allowed by override (tightening). - #[test] - fn override_can_tighten_required() { - let opts = json!({ "type": "string" }); - let override_cfg = ToolParameterConfig { - required: true, - ..cfg("string") - }; - - let merged = merge_mcp_param("x", &opts, Some(&override_cfg), false).unwrap(); - - assert!(merged.required); - } +/// A tool whose schema cannot be resolved is dropped from the request rather +/// than failing the whole query, mirroring how an unavailable MCP server is +/// handled. +#[tokio::test] +async fn tool_with_an_unresolvable_schema_is_skipped() { + let broken: PartialToolConfig = serde_json::from_value(json!({ + "source": "local", + "command": "echo broken", + "parameters": { "tags": { "type": "array" } }, + })) + .expect("valid partial tool config"); + let healthy: PartialToolConfig = serde_json::from_value(json!({ + "source": "local", + "command": "echo fine", + "parameters": { "path": { "type": "string" } }, + })) + .expect("valid partial tool config"); - /// `required: true → false` ignored — the server's contract wins. - #[test] - fn override_cannot_loosen_required() { - let opts = json!({ "type": "string" }); - let override_cfg = ToolParameterConfig { - required: false, - ..cfg("string") - }; + let mut cfg = AppConfig::new_test(); + cfg.conversation.tools.insert( + "broken_tool".to_owned(), + ToolConfig::from_partial(broken, vec![]).expect("resolved tool config"), + ); + cfg.conversation.tools.insert( + "healthy_tool".to_owned(), + ToolConfig::from_partial(healthy, vec![]).expect("resolved tool config"), + ); - let merged = merge_mcp_param("x", &opts, Some(&override_cfg), true).unwrap(); + let defs = tool_definitions( + cfg.conversation.tools.iter(), + &Client::new(IndexMap::new()), + None, + ) + .await + .expect("a broken tool must not fail the query"); - assert!(merged.required, "MCP-required field cannot be loosened"); - } + let names = defs.iter().map(|d| d.name.as_str()).collect::>(); + assert_eq!(names, vec!["healthy_tool"]); +} - /// `kind` override wins (existing behavior, exercised here for completeness - /// alongside the new `items` / `properties` tests). - #[test] - fn user_kind_override_replaces_mcp_kind() { - let opts = json!({ "type": "integer" }); - let override_cfg = cfg("string"); +/// Naming a tool with `--tool` is an explicit request for it, so its schema +/// error surfaces instead of the tool silently disappearing. +#[tokio::test] +async fn forced_tool_with_an_unresolvable_schema_still_errors() { + let broken: PartialToolConfig = serde_json::from_value(json!({ + "source": "local", + "command": "echo broken", + "parameters": { "tags": { "type": "array" } }, + })) + .expect("valid partial tool config"); - let merged = merge_mcp_param("x", &opts, Some(&override_cfg), false).unwrap(); + let mut cfg = AppConfig::new_test(); + cfg.conversation.tools.insert( + "broken_tool".to_owned(), + ToolConfig::from_partial(broken, vec![]).expect("resolved tool config"), + ); - assert!(matches!( - merged.kind, - OneOrManyTypes::One(ref s) if s == "string" - )); - } + let error = tool_definitions( + cfg.conversation.tools.iter(), + &Client::new(IndexMap::new()), + Some("broken_tool"), + ) + .await + .unwrap_err(); - /// `enum` from MCP carries through when no user override. - #[test] - fn mcp_enum_used_when_no_user_enumeration() { - let opts = json!({ - "type": "string", - "enum": ["a", "b", "c"] - }); - - let merged = merge_mcp_param("x", &opts, None, false).unwrap(); - - assert_eq!(merged.enumeration, vec![ - Value::from("a"), - Value::from("b"), - Value::from("c") - ]); - } + assert_eq!( + error.to_string(), + "Invalid schema at `conversation.tools.broken_tool.parameters.tags.items`: array schemas \ + must declare an item schema" + ); } diff --git a/crates/jp_llm/tests/fixtures/anthropic/test_multi_turn_conversation.yml b/crates/jp_llm/tests/fixtures/anthropic/test_multi_turn_conversation.yml index 248fd7f69..a8fae06da 100644 --- a/crates/jp_llm/tests/fixtures/anthropic/test_multi_turn_conversation.yml +++ b/crates/jp_llm/tests/fixtures/anthropic/test_multi_turn_conversation.yml @@ -278,14 +278,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_auto.yml b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_auto.yml index a89ebafb9..8428f71a4 100644 --- a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_auto.yml +++ b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_auto.yml @@ -41,14 +41,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_function.yml b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_function.yml index be0716e47..713075454 100644 --- a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_function.yml +++ b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_function.yml @@ -41,14 +41,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_reasoning.yml b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_reasoning.yml index 2d33148c0..f8b7a08fa 100644 --- a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_reasoning.yml @@ -43,14 +43,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_no_reasoning.yml b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_no_reasoning.yml index c48dc2daf..1b86c1c66 100644 --- a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_no_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_no_reasoning.yml @@ -41,14 +41,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_reasoning.yml b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_reasoning.yml index d35935ccf..71c916c84 100644 --- a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_required_reasoning.yml @@ -43,14 +43,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_stream.yml b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_stream.yml index 63d015fe0..321fa78c9 100644 --- a/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_stream.yml +++ b/crates/jp_llm/tests/fixtures/anthropic/test_tool_call_stream.yml @@ -41,14 +41,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/google/test_multi_turn_conversation.yml b/crates/jp_llm/tests/fixtures/google/test_multi_turn_conversation.yml index f99276b13..d248ba941 100644 --- a/crates/jp_llm/tests/fixtures/google/test_multi_turn_conversation.yml +++ b/crates/jp_llm/tests/fixtures/google/test_multi_turn_conversation.yml @@ -176,14 +176,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/google/test_tool_call_auto.yml b/crates/jp_llm/tests/fixtures/google/test_tool_call_auto.yml index dc5b3b94e..8fc0fa44f 100644 --- a/crates/jp_llm/tests/fixtures/google/test_tool_call_auto.yml +++ b/crates/jp_llm/tests/fixtures/google/test_tool_call_auto.yml @@ -36,14 +36,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/google/test_tool_call_function.yml b/crates/jp_llm/tests/fixtures/google/test_tool_call_function.yml index 138eb10b2..5f4f1d0a5 100644 --- a/crates/jp_llm/tests/fixtures/google/test_tool_call_function.yml +++ b/crates/jp_llm/tests/fixtures/google/test_tool_call_function.yml @@ -36,14 +36,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/google/test_tool_call_reasoning.yml b/crates/jp_llm/tests/fixtures/google/test_tool_call_reasoning.yml index a206b33f8..ee3f1a678 100644 --- a/crates/jp_llm/tests/fixtures/google/test_tool_call_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/google/test_tool_call_reasoning.yml @@ -36,14 +36,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/google/test_tool_call_required_no_reasoning.yml b/crates/jp_llm/tests/fixtures/google/test_tool_call_required_no_reasoning.yml index 8d5bffa95..b41fadd04 100644 --- a/crates/jp_llm/tests/fixtures/google/test_tool_call_required_no_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/google/test_tool_call_required_no_reasoning.yml @@ -36,14 +36,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/google/test_tool_call_required_reasoning.yml b/crates/jp_llm/tests/fixtures/google/test_tool_call_required_reasoning.yml index 420f06b2a..2ec36e777 100644 --- a/crates/jp_llm/tests/fixtures/google/test_tool_call_required_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/google/test_tool_call_required_reasoning.yml @@ -36,14 +36,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/google/test_tool_call_stream.yml b/crates/jp_llm/tests/fixtures/google/test_tool_call_stream.yml index ac99e175e..8ce396e0d 100644 --- a/crates/jp_llm/tests/fixtures/google/test_tool_call_stream.yml +++ b/crates/jp_llm/tests/fixtures/google/test_tool_call_stream.yml @@ -36,14 +36,14 @@ when: "array" ], "enum": [ - "foo", - [ + "foo" + ], + "items": { + "type": "string", + "enum": [ "foo", "bar" ] - ], - "items": { - "type": "string" } } }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.snap index d540ebef7..8e79a70aa 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.snap @@ -9,7 +9,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Reasoning { - reasoning: "Okay, the user sent \"Test message\". This seems like a straightforward test to see if I'm responding properly.\n\nLet me check if there are any errors in my setup. Since I'm an AI model, maybe they want to confirm functionality.\n\nI should respond clearly that I received their message and offer assistance. Keep it friendly and helpful.\n\nMake sure not to include any technical details or overcomplicate the reply. Just a simple acknowledgment and offer help.", + reasoning: "Thinking Process:\n\n1. **Analyze the Request:**\n * Input: \"Test message\"\n * Intent: The user is likely testing the connection, checking if the AI responds correctly, or just saying hello in a generic way. It's not asking for information, advice, or creative content specifically.\n * Context: Standard chat interaction.\n\n2. **Determine the appropriate response:**\n * Acknowledge the message.\n * Be polite and friendly.\n * Offer assistance.\n * Keep it brief since \"Test message\" is minimal input.\n\n3. **Draft potential responses:**\n * Option 1 (Simple): Hello! How can I help you today?\n * Option 2 (Confirming receipt): Received your test message successfully! What would you like to discuss?\n * Option 3 (Friendly): Hi there! It's great to see a message. Is everything working well for you, or is there something specific you need help with?\n\n4. **Select the best response:**\n * Option 1 & 2 are good mixes. A friendly acknowledgment followed by an offer of help is standard AI behavior.\n\n5. **Final Polish:** \"Hello! It looks like your test message was received successfully. How can I assist you today?\" or simply \"Hi there! 👋 Everything seems to be working on my end as well. What would you like to work on today?\"\n\n Let's go with a clear, friendly acknowledgement.\n\n6. **Final Output Generation:** (Matches the selected draft)\n \"Hello! Your test message was received successfully. How can I help you today?\" or similar.\n\n *Self-Correction:* Keep it natural.\n \"Hi there! It looks like everything is working well on my end too. What would you like to talk about or get help with today?\"\n\n Actually, keep it simple and direct.\n \"Hello! Message received successfully. How can I assist you today?\"\n\n Let's add a bit of warmth.\n \"Hi there! 👋 It looks like your message came through perfectly. Is there anything specific you'd like to discuss or need help with today?\"\n\n7. **Final Decision:** A friendly greeting + confirmation + offer to help.cw", }, ), metadata: {}, @@ -20,7 +20,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "Hello! 👋 Your test message has been received successfully. \n\nHow can I assist you today? Feel free to ask questions, request information, or need help with anything specific! 😊", + message: "Hello! Your test message was received successfully. 👋 How can I assist you today?", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.yml b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.yml index e0ed39602..cf0dc76ce 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream.yml @@ -22,130 +22,444 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:54.867739Z","message":{"role":"assistant","content":"","thinking":"Okay"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:54.916826Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:54.973144Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.027638Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.084526Z","message":{"role":"assistant","content":"","thinking":" sent"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.145455Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.202874Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.257551Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.313824Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.368768Z","message":{"role":"assistant","content":"","thinking":" This"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.42506Z","message":{"role":"assistant","content":"","thinking":" seems"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.477766Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.535107Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.592045Z","message":{"role":"assistant","content":"","thinking":" straightforward"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.646945Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.706364Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.763928Z","message":{"role":"assistant","content":"","thinking":" see"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.822658Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.878543Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.939272Z","message":{"role":"assistant","content":"","thinking":"'m"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:55.994664Z","message":{"role":"assistant","content":"","thinking":" responding"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.049083Z","message":{"role":"assistant","content":"","thinking":" properly"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.105537Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.219946Z","message":{"role":"assistant","content":"","thinking":"\n\nLet"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.275931Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.333605Z","message":{"role":"assistant","content":"","thinking":" check"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.389461Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.445124Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.498221Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.555104Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.611462Z","message":{"role":"assistant","content":"","thinking":" errors"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.665642Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.723375Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.780182Z","message":{"role":"assistant","content":"","thinking":" setup"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.839515Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.896015Z","message":{"role":"assistant","content":"","thinking":" Since"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:56.956107Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.008304Z","message":{"role":"assistant","content":"","thinking":"'m"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.064625Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.118473Z","message":{"role":"assistant","content":"","thinking":" AI"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.175702Z","message":{"role":"assistant","content":"","thinking":" model"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.233275Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.292288Z","message":{"role":"assistant","content":"","thinking":" maybe"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.35191Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.409682Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.469164Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.52486Z","message":{"role":"assistant","content":"","thinking":" confirm"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.580686Z","message":{"role":"assistant","content":"","thinking":" functionality"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.639569Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.750307Z","message":{"role":"assistant","content":"","thinking":"\n\nI"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.8019Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.855745Z","message":{"role":"assistant","content":"","thinking":" respond"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:57.932586Z","message":{"role":"assistant","content":"","thinking":" clearly"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.008237Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.080433Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.158958Z","message":{"role":"assistant","content":"","thinking":" received"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.235593Z","message":{"role":"assistant","content":"","thinking":" their"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.312938Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.379514Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.457239Z","message":{"role":"assistant","content":"","thinking":" offer"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.537429Z","message":{"role":"assistant","content":"","thinking":" assistance"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.613751Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.694763Z","message":{"role":"assistant","content":"","thinking":" Keep"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.763258Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.817322Z","message":{"role":"assistant","content":"","thinking":" friendly"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.861592Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.905357Z","message":{"role":"assistant","content":"","thinking":" helpful"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:58.950516Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.081583Z","message":{"role":"assistant","content":"","thinking":"\n\nMake"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.146587Z","message":{"role":"assistant","content":"","thinking":" sure"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.212363Z","message":{"role":"assistant","content":"","thinking":" not"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.268344Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.327069Z","message":{"role":"assistant","content":"","thinking":" include"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.38713Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.446926Z","message":{"role":"assistant","content":"","thinking":" technical"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.499706Z","message":{"role":"assistant","content":"","thinking":" details"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.552869Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.607397Z","message":{"role":"assistant","content":"","thinking":" over"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.665617Z","message":{"role":"assistant","content":"","thinking":"comp"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.721332Z","message":{"role":"assistant","content":"","thinking":"licate"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.777865Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.835159Z","message":{"role":"assistant","content":"","thinking":" reply"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.892858Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:51:59.950725Z","message":{"role":"assistant","content":"","thinking":" Just"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.008361Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.0661Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.121674Z","message":{"role":"assistant","content":"","thinking":" acknowledgment"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.178978Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.236986Z","message":{"role":"assistant","content":"","thinking":" offer"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.294245Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.351803Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.577744Z","message":{"role":"assistant","content":"Hello"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.635474Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.751238Z","message":{"role":"assistant","content":" 👋"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.80944Z","message":{"role":"assistant","content":" Your"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.857886Z","message":{"role":"assistant","content":" test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:00.933079Z","message":{"role":"assistant","content":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.005879Z","message":{"role":"assistant","content":" has"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.074501Z","message":{"role":"assistant","content":" been"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.140699Z","message":{"role":"assistant","content":" received"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.213663Z","message":{"role":"assistant","content":" successfully"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.28447Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.402278Z","message":{"role":"assistant","content":" \n\nHow"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.446706Z","message":{"role":"assistant","content":" can"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.499861Z","message":{"role":"assistant","content":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.548564Z","message":{"role":"assistant","content":" assist"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.599535Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.650625Z","message":{"role":"assistant","content":" today"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.702006Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.755797Z","message":{"role":"assistant","content":" Feel"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.810987Z","message":{"role":"assistant","content":" free"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.864734Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.919875Z","message":{"role":"assistant","content":" ask"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:01.976338Z","message":{"role":"assistant","content":" questions"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.030591Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.085699Z","message":{"role":"assistant","content":" request"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.141018Z","message":{"role":"assistant","content":" information"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.194686Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.248212Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.302882Z","message":{"role":"assistant","content":" need"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.358004Z","message":{"role":"assistant","content":" help"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.411461Z","message":{"role":"assistant","content":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.466023Z","message":{"role":"assistant","content":" anything"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.522038Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.578013Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.693701Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.752405Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":18303605708,"load_duration":6578743125,"prompt_eval_count":12,"prompt_eval_duration":3802240625,"eval_count":136,"eval_duration":7618905002} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.424386Z","message":{"role":"assistant","content":"","thinking":"Thinking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.456265Z","message":{"role":"assistant","content":"","thinking":" Process"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.48044Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.527545Z","message":{"role":"assistant","content":"","thinking":"\n\n1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.549984Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.59484Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.618062Z","message":{"role":"assistant","content":"","thinking":"An"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.641796Z","message":{"role":"assistant","content":"","thinking":"alyze"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.664915Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.688663Z","message":{"role":"assistant","content":"","thinking":" Request"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.711588Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.781428Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.827908Z","message":{"role":"assistant","content":"","thinking":" Input"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.850686Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.87389Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.89702Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.919867Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:55.942599Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.012102Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.058573Z","message":{"role":"assistant","content":"","thinking":" Intent"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.081792Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.10431Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.127564Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.150764Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.174026Z","message":{"role":"assistant","content":"","thinking":" likely"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.197368Z","message":{"role":"assistant","content":"","thinking":" testing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.220821Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.244142Z","message":{"role":"assistant","content":"","thinking":" connection"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.267251Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.290179Z","message":{"role":"assistant","content":"","thinking":" checking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.313347Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.336904Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.359882Z","message":{"role":"assistant","content":"","thinking":" AI"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.383495Z","message":{"role":"assistant","content":"","thinking":" responds"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.406653Z","message":{"role":"assistant","content":"","thinking":" correctly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.43029Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.453489Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.47704Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.500501Z","message":{"role":"assistant","content":"","thinking":" saying"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.523953Z","message":{"role":"assistant","content":"","thinking":" hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.547419Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.570666Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.594316Z","message":{"role":"assistant","content":"","thinking":" generic"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.617653Z","message":{"role":"assistant","content":"","thinking":" way"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.641107Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.663937Z","message":{"role":"assistant","content":"","thinking":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.687492Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.710514Z","message":{"role":"assistant","content":"","thinking":" not"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.734051Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.757054Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.780626Z","message":{"role":"assistant","content":"","thinking":" information"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.803658Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.827282Z","message":{"role":"assistant","content":"","thinking":" advice"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.850284Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.873495Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.896663Z","message":{"role":"assistant","content":"","thinking":" creative"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.919552Z","message":{"role":"assistant","content":"","thinking":" content"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.94233Z","message":{"role":"assistant","content":"","thinking":" specifically"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:56.965292Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.035204Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.08146Z","message":{"role":"assistant","content":"","thinking":" Context"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.104Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.127302Z","message":{"role":"assistant","content":"","thinking":" Standard"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.150532Z","message":{"role":"assistant","content":"","thinking":" chat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.17377Z","message":{"role":"assistant","content":"","thinking":" interaction"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.19691Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.243444Z","message":{"role":"assistant","content":"","thinking":"\n\n2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.266393Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.312855Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.336282Z","message":{"role":"assistant","content":"","thinking":"D"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.359234Z","message":{"role":"assistant","content":"","thinking":"etermine"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.382582Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.405598Z","message":{"role":"assistant","content":"","thinking":" appropriate"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.429099Z","message":{"role":"assistant","content":"","thinking":" response"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.452051Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.521464Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.567218Z","message":{"role":"assistant","content":"","thinking":" Ack"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.590729Z","message":{"role":"assistant","content":"","thinking":"nowledge"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.61383Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.637217Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.660181Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.72932Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.775658Z","message":{"role":"assistant","content":"","thinking":" Be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.798192Z","message":{"role":"assistant","content":"","thinking":" polite"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.821421Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.844747Z","message":{"role":"assistant","content":"","thinking":" friendly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.867709Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.937667Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:57.984185Z","message":{"role":"assistant","content":"","thinking":" Offer"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.007222Z","message":{"role":"assistant","content":"","thinking":" assistance"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.030469Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.099321Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.14534Z","message":{"role":"assistant","content":"","thinking":" Keep"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.168663Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.190927Z","message":{"role":"assistant","content":"","thinking":" brief"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.213349Z","message":{"role":"assistant","content":"","thinking":" since"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.236257Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.259226Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.282028Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.3044Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.32788Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.350283Z","message":{"role":"assistant","content":"","thinking":" minimal"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.373574Z","message":{"role":"assistant","content":"","thinking":" input"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.395518Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.440498Z","message":{"role":"assistant","content":"","thinking":"\n\n3"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.463058Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.508403Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.531452Z","message":{"role":"assistant","content":"","thinking":"Draft"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.554564Z","message":{"role":"assistant","content":"","thinking":" potential"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.577942Z","message":{"role":"assistant","content":"","thinking":" responses"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.601293Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.672114Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.719709Z","message":{"role":"assistant","content":"","thinking":" Option"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.765414Z","message":{"role":"assistant","content":"","thinking":" 1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.7883Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.810579Z","message":{"role":"assistant","content":"","thinking":"Simple"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.833454Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.8559Z","message":{"role":"assistant","content":"","thinking":" Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.878784Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.901088Z","message":{"role":"assistant","content":"","thinking":" How"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.92372Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.946391Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.969583Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:58.99311Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.015791Z","message":{"role":"assistant","content":"","thinking":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.038954Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.107141Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.152922Z","message":{"role":"assistant","content":"","thinking":" Option"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.198841Z","message":{"role":"assistant","content":"","thinking":" 2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.222071Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.244715Z","message":{"role":"assistant","content":"","thinking":"Confirm"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.268146Z","message":{"role":"assistant","content":"","thinking":"ing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.291443Z","message":{"role":"assistant","content":"","thinking":" receipt"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.314636Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.337903Z","message":{"role":"assistant","content":"","thinking":" Received"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.36083Z","message":{"role":"assistant","content":"","thinking":" your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.384295Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.40731Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.430769Z","message":{"role":"assistant","content":"","thinking":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.453782Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.47717Z","message":{"role":"assistant","content":"","thinking":" What"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.500381Z","message":{"role":"assistant","content":"","thinking":" would"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.523587Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.546151Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.569205Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.592792Z","message":{"role":"assistant","content":"","thinking":" discuss"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.615773Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.685809Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.731749Z","message":{"role":"assistant","content":"","thinking":" Option"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.778431Z","message":{"role":"assistant","content":"","thinking":" 3"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.801448Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.824787Z","message":{"role":"assistant","content":"","thinking":"Friendly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.848108Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.871379Z","message":{"role":"assistant","content":"","thinking":" Hi"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.893916Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.916365Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.939865Z","message":{"role":"assistant","content":"","thinking":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.962905Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:16:59.986583Z","message":{"role":"assistant","content":"","thinking":" great"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.009741Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.032598Z","message":{"role":"assistant","content":"","thinking":" see"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.055505Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.078897Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.101903Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.124805Z","message":{"role":"assistant","content":"","thinking":" Is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.147252Z","message":{"role":"assistant","content":"","thinking":" everything"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.170374Z","message":{"role":"assistant","content":"","thinking":" working"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.192954Z","message":{"role":"assistant","content":"","thinking":" well"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.215961Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.239642Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.262743Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.286236Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.309296Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.332852Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.355634Z","message":{"role":"assistant","content":"","thinking":" something"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.378798Z","message":{"role":"assistant","content":"","thinking":" specific"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.401259Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.424151Z","message":{"role":"assistant","content":"","thinking":" need"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.447147Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.469926Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.49294Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.538178Z","message":{"role":"assistant","content":"","thinking":"\n\n4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.560603Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.606057Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.628659Z","message":{"role":"assistant","content":"","thinking":"Select"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.651745Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.675271Z","message":{"role":"assistant","content":"","thinking":" best"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.698193Z","message":{"role":"assistant","content":"","thinking":" response"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.721473Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.790319Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.836941Z","message":{"role":"assistant","content":"","thinking":" Option"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.883562Z","message":{"role":"assistant","content":"","thinking":" 1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.906689Z","message":{"role":"assistant","content":"","thinking":" \u0026"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.953283Z","message":{"role":"assistant","content":"","thinking":" 2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.976683Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:00.999999Z","message":{"role":"assistant","content":"","thinking":" good"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.02295Z","message":{"role":"assistant","content":"","thinking":" mixes"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.045656Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.068754Z","message":{"role":"assistant","content":"","thinking":" A"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.093298Z","message":{"role":"assistant","content":"","thinking":" friendly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.116289Z","message":{"role":"assistant","content":"","thinking":" acknowledgment"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.139093Z","message":{"role":"assistant","content":"","thinking":" followed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.162099Z","message":{"role":"assistant","content":"","thinking":" by"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.185585Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.208668Z","message":{"role":"assistant","content":"","thinking":" offer"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.2321Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.255044Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.278548Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.301502Z","message":{"role":"assistant","content":"","thinking":" standard"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.324715Z","message":{"role":"assistant","content":"","thinking":" AI"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.348013Z","message":{"role":"assistant","content":"","thinking":" behavior"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.370687Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.416704Z","message":{"role":"assistant","content":"","thinking":"\n\n5"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.44015Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.486506Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.509481Z","message":{"role":"assistant","content":"","thinking":"Final"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.532913Z","message":{"role":"assistant","content":"","thinking":" Polish"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.556042Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.579534Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.602735Z","message":{"role":"assistant","content":"","thinking":"Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.625954Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.649168Z","message":{"role":"assistant","content":"","thinking":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.672413Z","message":{"role":"assistant","content":"","thinking":" looks"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.695707Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.718949Z","message":{"role":"assistant","content":"","thinking":" your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.741637Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.764704Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.788218Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.811284Z","message":{"role":"assistant","content":"","thinking":" received"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.834749Z","message":{"role":"assistant","content":"","thinking":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.85776Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.880666Z","message":{"role":"assistant","content":"","thinking":" How"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.903676Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.926983Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.9503Z","message":{"role":"assistant","content":"","thinking":" assist"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.973679Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:01.99681Z","message":{"role":"assistant","content":"","thinking":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.019856Z","message":{"role":"assistant","content":"","thinking":"?\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.043238Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.066355Z","message":{"role":"assistant","content":"","thinking":" simply"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.089892Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.112988Z","message":{"role":"assistant","content":"","thinking":"Hi"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.136398Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.159508Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.206387Z","message":{"role":"assistant","content":"","thinking":" 👋"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.229993Z","message":{"role":"assistant","content":"","thinking":" Everything"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.25302Z","message":{"role":"assistant","content":"","thinking":" seems"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.276496Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.298866Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.321486Z","message":{"role":"assistant","content":"","thinking":" working"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.345127Z","message":{"role":"assistant","content":"","thinking":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.368081Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.391144Z","message":{"role":"assistant","content":"","thinking":" end"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.413688Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.436853Z","message":{"role":"assistant","content":"","thinking":" well"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.459247Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.482049Z","message":{"role":"assistant","content":"","thinking":" What"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.504431Z","message":{"role":"assistant","content":"","thinking":" would"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.527091Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.549842Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.57216Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.595515Z","message":{"role":"assistant","content":"","thinking":" work"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.618625Z","message":{"role":"assistant","content":"","thinking":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.641172Z","message":{"role":"assistant","content":"","thinking":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.664063Z","message":{"role":"assistant","content":"","thinking":"?\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.733081Z","message":{"role":"assistant","content":"","thinking":"\n\n Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.756Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.779433Z","message":{"role":"assistant","content":"","thinking":" go"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.802372Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.825712Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.848802Z","message":{"role":"assistant","content":"","thinking":" clear"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.87203Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.894639Z","message":{"role":"assistant","content":"","thinking":" friendly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.917599Z","message":{"role":"assistant","content":"","thinking":" acknowledgement"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.941007Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:02.987509Z","message":{"role":"assistant","content":"","thinking":"\n\n6"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.010544Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.056467Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.07976Z","message":{"role":"assistant","content":"","thinking":"Final"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.10297Z","message":{"role":"assistant","content":"","thinking":" Output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.125657Z","message":{"role":"assistant","content":"","thinking":" Generation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.148844Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.172142Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.195536Z","message":{"role":"assistant","content":"","thinking":"Matches"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.218822Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.241518Z","message":{"role":"assistant","content":"","thinking":" selected"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.26462Z","message":{"role":"assistant","content":"","thinking":" draft"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.288174Z","message":{"role":"assistant","content":"","thinking":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.357738Z","message":{"role":"assistant","content":"","thinking":"\n \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.381206Z","message":{"role":"assistant","content":"","thinking":"Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.404208Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.427519Z","message":{"role":"assistant","content":"","thinking":" Your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.451277Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.47456Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.497278Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.52025Z","message":{"role":"assistant","content":"","thinking":" received"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.543743Z","message":{"role":"assistant","content":"","thinking":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.567157Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.589836Z","message":{"role":"assistant","content":"","thinking":" How"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.61233Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.635823Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.658801Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.682153Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.705505Z","message":{"role":"assistant","content":"","thinking":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.729044Z","message":{"role":"assistant","content":"","thinking":"?\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.752134Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.77569Z","message":{"role":"assistant","content":"","thinking":" similar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.799361Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.869481Z","message":{"role":"assistant","content":"","thinking":"\n\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.892163Z","message":{"role":"assistant","content":"","thinking":"Self"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.915379Z","message":{"role":"assistant","content":"","thinking":"-C"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.939143Z","message":{"role":"assistant","content":"","thinking":"or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.961642Z","message":{"role":"assistant","content":"","thinking":"rection"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:03.985264Z","message":{"role":"assistant","content":"","thinking":":*"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.008622Z","message":{"role":"assistant","content":"","thinking":" Keep"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.032434Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.055569Z","message":{"role":"assistant","content":"","thinking":" natural"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.079219Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.149878Z","message":{"role":"assistant","content":"","thinking":"\n \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.173307Z","message":{"role":"assistant","content":"","thinking":"Hi"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.197036Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.220729Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.244354Z","message":{"role":"assistant","content":"","thinking":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.267504Z","message":{"role":"assistant","content":"","thinking":" looks"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.290318Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.313515Z","message":{"role":"assistant","content":"","thinking":" everything"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.336285Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.35862Z","message":{"role":"assistant","content":"","thinking":" working"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.382264Z","message":{"role":"assistant","content":"","thinking":" well"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.405436Z","message":{"role":"assistant","content":"","thinking":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.428964Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.451329Z","message":{"role":"assistant","content":"","thinking":" end"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.474391Z","message":{"role":"assistant","content":"","thinking":" too"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.49726Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.520299Z","message":{"role":"assistant","content":"","thinking":" What"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.543677Z","message":{"role":"assistant","content":"","thinking":" would"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.566754Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.589425Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.612433Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.635823Z","message":{"role":"assistant","content":"","thinking":" talk"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.65887Z","message":{"role":"assistant","content":"","thinking":" about"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.682467Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.705587Z","message":{"role":"assistant","content":"","thinking":" get"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.72917Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.752226Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.775511Z","message":{"role":"assistant","content":"","thinking":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.798396Z","message":{"role":"assistant","content":"","thinking":"?\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.867396Z","message":{"role":"assistant","content":"","thinking":"\n\n Actually"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.890943Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.914045Z","message":{"role":"assistant","content":"","thinking":" keep"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.937748Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.960989Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:04.984653Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.007865Z","message":{"role":"assistant","content":"","thinking":" direct"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.031336Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.100658Z","message":{"role":"assistant","content":"","thinking":"\n \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.12402Z","message":{"role":"assistant","content":"","thinking":"Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.147251Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.170629Z","message":{"role":"assistant","content":"","thinking":" Message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.193333Z","message":{"role":"assistant","content":"","thinking":" received"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.216514Z","message":{"role":"assistant","content":"","thinking":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.240143Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.263308Z","message":{"role":"assistant","content":"","thinking":" How"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.28689Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.309956Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.333486Z","message":{"role":"assistant","content":"","thinking":" assist"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.356544Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.38006Z","message":{"role":"assistant","content":"","thinking":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.403062Z","message":{"role":"assistant","content":"","thinking":"?\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.47323Z","message":{"role":"assistant","content":"","thinking":"\n\n Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.495861Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.518834Z","message":{"role":"assistant","content":"","thinking":" add"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.542124Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.564817Z","message":{"role":"assistant","content":"","thinking":" bit"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.588427Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.610935Z","message":{"role":"assistant","content":"","thinking":" warmth"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.634568Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.702879Z","message":{"role":"assistant","content":"","thinking":"\n \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.726422Z","message":{"role":"assistant","content":"","thinking":"Hi"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.749522Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.772217Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.817897Z","message":{"role":"assistant","content":"","thinking":" 👋"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.840802Z","message":{"role":"assistant","content":"","thinking":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.863789Z","message":{"role":"assistant","content":"","thinking":" looks"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.887331Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.910371Z","message":{"role":"assistant","content":"","thinking":" your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.933902Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.957033Z","message":{"role":"assistant","content":"","thinking":" came"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:05.980506Z","message":{"role":"assistant","content":"","thinking":" through"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.002943Z","message":{"role":"assistant","content":"","thinking":" perfectly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.026306Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.048916Z","message":{"role":"assistant","content":"","thinking":" Is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.071482Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.094685Z","message":{"role":"assistant","content":"","thinking":" anything"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.117722Z","message":{"role":"assistant","content":"","thinking":" specific"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.140408Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.163439Z","message":{"role":"assistant","content":"","thinking":"'d"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.186904Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.20989Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.233385Z","message":{"role":"assistant","content":"","thinking":" discuss"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.256542Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.280152Z","message":{"role":"assistant","content":"","thinking":" need"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.303291Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.326745Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.349339Z","message":{"role":"assistant","content":"","thinking":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.37196Z","message":{"role":"assistant","content":"","thinking":"?\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.417695Z","message":{"role":"assistant","content":"","thinking":"\n\n7"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.441208Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.486491Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.508868Z","message":{"role":"assistant","content":"","thinking":"Final"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.532065Z","message":{"role":"assistant","content":"","thinking":" Decision"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.554539Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.577772Z","message":{"role":"assistant","content":"","thinking":" A"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.600915Z","message":{"role":"assistant","content":"","thinking":" friendly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.623589Z","message":{"role":"assistant","content":"","thinking":" greeting"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.646397Z","message":{"role":"assistant","content":"","thinking":" +"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.669613Z","message":{"role":"assistant","content":"","thinking":" confirmation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.692301Z","message":{"role":"assistant","content":"","thinking":" +"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.715418Z","message":{"role":"assistant","content":"","thinking":" offer"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.738966Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.761873Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.784887Z","message":{"role":"assistant","content":"","thinking":".c"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.807922Z","message":{"role":"assistant","content":"","thinking":"w"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.901833Z","message":{"role":"assistant","content":"Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.925304Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.948656Z","message":{"role":"assistant","content":" Your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.97194Z","message":{"role":"assistant","content":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:06.994755Z","message":{"role":"assistant","content":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.019407Z","message":{"role":"assistant","content":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.042704Z","message":{"role":"assistant","content":" received"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.065707Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.088654Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.13455Z","message":{"role":"assistant","content":" 👋"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.15704Z","message":{"role":"assistant","content":" How"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.180519Z","message":{"role":"assistant","content":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.203842Z","message":{"role":"assistant","content":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.227377Z","message":{"role":"assistant","content":" assist"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.250662Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.274179Z","message":{"role":"assistant","content":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.297436Z","message":{"role":"assistant","content":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.321714Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":19146718208,"load_duration":7035927916,"prompt_eval_count":12,"prompt_eval_duration":206543000,"eval_count":515,"eval_duration":11898647000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__conversation_stream.snap index 19e0c1338..e866b833f 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__conversation_stream.snap @@ -224,12 +224,12 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "reasoning": "Okay, the user sent \"Test message\". This seems like a straightforward test to see if I'm responding properly.\n\nLet me check if there are any errors in my setup. Since I'm an AI model, maybe they want to confirm functionality.\n\nI should respond clearly that I received their message and offer assistance. Keep it friendly and helpful.\n\nMake sure not to include any technical details or overcomplicate the reply. Just a simple acknowledgment and offer help." + "reasoning": "Thinking Process:\n\n1. **Analyze the Request:**\n * Input: \"Test message\"\n * Intent: The user is likely testing the connection, checking if the AI responds correctly, or just saying hello in a generic way. It's not asking for information, advice, or creative content specifically.\n * Context: Standard chat interaction.\n\n2. **Determine the appropriate response:**\n * Acknowledge the message.\n * Be polite and friendly.\n * Offer assistance.\n * Keep it brief since \"Test message\" is minimal input.\n\n3. **Draft potential responses:**\n * Option 1 (Simple): Hello! How can I help you today?\n * Option 2 (Confirming receipt): Received your test message successfully! What would you like to discuss?\n * Option 3 (Friendly): Hi there! It's great to see a message. Is everything working well for you, or is there something specific you need help with?\n\n4. **Select the best response:**\n * Option 1 & 2 are good mixes. A friendly acknowledgment followed by an offer of help is standard AI behavior.\n\n5. **Final Polish:** \"Hello! It looks like your test message was received successfully. How can I assist you today?\" or simply \"Hi there! 👋 Everything seems to be working on my end as well. What would you like to work on today?\"\n\n Let's go with a clear, friendly acknowledgement.\n\n6. **Final Output Generation:** (Matches the selected draft)\n \"Hello! Your test message was received successfully. How can I help you today?\" or similar.\n\n *Self-Correction:* Keep it natural.\n \"Hi there! It looks like everything is working well on my end too. What would you like to talk about or get help with today?\"\n\n Actually, keep it simple and direct.\n \"Hello! Message received successfully. How can I assist you today?\"\n\n Let's add a bit of warmth.\n \"Hi there! 👋 It looks like your message came through perfectly. Is there anything specific you'd like to discuss or need help with today?\"\n\n7. **Final Decision:** A friendly greeting + confirmation + offer to help.cw" }, { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "Hello! 👋 Your test message has been received successfully. \n\nHow can I assist you today? Feel free to ask questions, request information, or need help with anything specific! 😊" + "message": "Hello! Your test message was received successfully. 👋 How can I assist you today?" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__raw_events.snap index 5c5c5ef2b..6db8fe62c 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_chat_completion_stream__raw_events.snap @@ -7,7 +7,1897 @@ expression: v Part { index: 0, part: Reasoning( - "Okay", + "Thinking", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Process", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n1", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " **", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "An", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "alyze", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Request", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":**", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Input", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Test", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Intent", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " The", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " user", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " likely", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " testing", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " connection", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " checking", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " if", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " AI", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " responds", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " correctly", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " just", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " saying", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " hello", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " in", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " generic", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " way", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " It", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'s", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " not", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " asking", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " for", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " information", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " advice", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " creative", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " content", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " specifically", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Context", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Standard", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " chat", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " interaction", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n2", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " **", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "D", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "etermine", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " appropriate", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " response", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":**", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Ack", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "nowledge", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Be", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " polite", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " and", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " friendly", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Offer", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " assistance", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Keep", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " it", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " brief", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " since", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Test", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " minimal", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " input", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n3", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " **", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Draft", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " potential", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " responses", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":**", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Option", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 1", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Simple", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "):", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Hello", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "!", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " How", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " can", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " help", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " you", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " today", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "?", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Option", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 2", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Confirm", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "ing", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " receipt", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "):", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Received", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " your", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " test", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " successfully", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "!", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " What", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " would", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " you", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " like", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " discuss", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "?", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Option", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 3", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Friendly", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "):", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Hi", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " there", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "!", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " It", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'s", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " great", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " see", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " everything", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " working", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " well", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " for", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " you", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " there", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " something", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " specific", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " you", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " need", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " help", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " with", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "?", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n4", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " **", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Select", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " best", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " response", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":**", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Option", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 1", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " &", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 2", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " are", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " good", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " mixes", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " A", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " friendly", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " acknowledgment", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " followed", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " by", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " an", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " offer", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " of", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " help", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " standard", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " AI", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " behavior", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n5", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " **", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Final", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Polish", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":**", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Hello", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "!", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " It", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " looks", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " like", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " your", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " test", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " was", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " received", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " successfully", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " How", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " can", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " assist", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " you", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " today", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "?\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " simply", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Hi", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " there", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "!", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 👋", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Everything", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " seems", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " be", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " working", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " on", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " my", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " end", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " as", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " well", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " What", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " would", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " you", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " like", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " work", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " on", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " today", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "?\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n Let", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'s", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " go", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " with", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " clear", ), metadata: {}, }, @@ -21,273 +1911,532 @@ expression: v Part { index: 0, part: Reasoning( - " the", + " friendly", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " acknowledgement", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n6", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " **", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Final", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Output", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Generation", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":**", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Matches", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " selected", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " draft", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ")", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Hello", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "!", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Your", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " test", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " was", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " received", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " successfully", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " How", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " can", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " help", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " you", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " today", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "?\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " similar", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n *", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "Self", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + "-C", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " sent", + "or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + "rection", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + ":*", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " Keep", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " it", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " This", + " natural", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " seems", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " like", + "\n \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " a", + "Hi", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " straightforward", + " there", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " test", + "!", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " It", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " see", + " looks", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " if", + " like", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " everything", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'m", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " responding", + " working", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " properly", + " well", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " on", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nLet", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " me", + " end", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " check", + " too", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " if", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " there", + " What", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " are", + " would", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " any", + " you", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " errors", + " like", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " in", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " my", + " talk", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " setup", + " about", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Since", + " get", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " help", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'m", + " with", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " an", + " today", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " AI", + "?\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " model", + "\n\n Actually", ), metadata: {}, }, @@ -301,280 +2450,287 @@ expression: v Part { index: 0, part: Reasoning( - " maybe", + " keep", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " they", + " it", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " want", + " simple", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " and", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " confirm", + " direct", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " functionality", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "\n \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nI", + "Hello", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " should", + "!", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " respond", + " Message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " clearly", + " received", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " that", + " successfully", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " received", + " How", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " their", + " can", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " and", + " assist", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " offer", + " you", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " assistance", + " today", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "?\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Keep", + "\n\n Let", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " friendly", + " add", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " and", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " helpful", + " bit", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " of", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nMake", + " warmth", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " sure", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " not", + "\n \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + "Hi", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " include", + " there", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " any", + "!", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " technical", + " 👋", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " details", + " It", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " or", + " looks", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " over", + " like", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "comp", + " your", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "licate", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " came", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " through", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " reply", + " perfectly", ), metadata: {}, }, @@ -588,42 +2744,77 @@ expression: v Part { index: 0, part: Reasoning( - " Just", + " Is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " a", + " there", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " simple", + " anything", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " acknowledgment", + " specific", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " and", + " you", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " offer", + "'d", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " like", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " discuss", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " need", ), metadata: {}, }, @@ -637,256 +2828,263 @@ expression: v Part { index: 0, part: Reasoning( - ".", + " with", ), metadata: {}, }, - Flush { + Part { index: 0, + part: Reasoning( + " today", + ), metadata: {}, }, Part { - index: 1, - part: Message( - "Hello", + index: 0, + part: Reasoning( + "?\"", ), metadata: {}, }, Part { - index: 1, - part: Message( - "!", + index: 0, + part: Reasoning( + "\n\n7", ), metadata: {}, }, Part { - index: 1, - part: Message( - " 👋", + index: 0, + part: Reasoning( + ".", ), metadata: {}, }, Part { - index: 1, - part: Message( - " Your", + index: 0, + part: Reasoning( + " **", ), metadata: {}, }, Part { - index: 1, - part: Message( - " test", + index: 0, + part: Reasoning( + "Final", ), metadata: {}, }, Part { - index: 1, - part: Message( - " message", + index: 0, + part: Reasoning( + " Decision", ), metadata: {}, }, Part { - index: 1, - part: Message( - " has", + index: 0, + part: Reasoning( + ":**", ), metadata: {}, }, Part { - index: 1, - part: Message( - " been", + index: 0, + part: Reasoning( + " A", ), metadata: {}, }, Part { - index: 1, - part: Message( - " received", + index: 0, + part: Reasoning( + " friendly", ), metadata: {}, }, Part { - index: 1, - part: Message( - " successfully", + index: 0, + part: Reasoning( + " greeting", ), metadata: {}, }, Part { - index: 1, - part: Message( - ".", + index: 0, + part: Reasoning( + " +", ), metadata: {}, }, Part { - index: 1, - part: Message( - " \n\nHow", + index: 0, + part: Reasoning( + " confirmation", ), metadata: {}, }, Part { - index: 1, - part: Message( - " can", + index: 0, + part: Reasoning( + " +", ), metadata: {}, }, Part { - index: 1, - part: Message( - " I", + index: 0, + part: Reasoning( + " offer", ), metadata: {}, }, Part { - index: 1, - part: Message( - " assist", + index: 0, + part: Reasoning( + " to", ), metadata: {}, }, Part { - index: 1, - part: Message( - " you", + index: 0, + part: Reasoning( + " help", ), metadata: {}, }, Part { - index: 1, - part: Message( - " today", + index: 0, + part: Reasoning( + ".c", ), metadata: {}, }, Part { - index: 1, - part: Message( - "?", + index: 0, + part: Reasoning( + "w", ), metadata: {}, }, + Flush { + index: 0, + metadata: {}, + }, Part { index: 1, part: Message( - " Feel", + "Hello", ), metadata: {}, }, Part { index: 1, part: Message( - " free", + "!", ), metadata: {}, }, Part { index: 1, part: Message( - " to", + " Your", ), metadata: {}, }, Part { index: 1, part: Message( - " ask", + " test", ), metadata: {}, }, Part { index: 1, part: Message( - " questions", + " message", ), metadata: {}, }, Part { index: 1, part: Message( - ",", + " was", ), metadata: {}, }, Part { index: 1, part: Message( - " request", + " received", ), metadata: {}, }, Part { index: 1, part: Message( - " information", + " successfully", ), metadata: {}, }, Part { index: 1, part: Message( - ",", + ".", ), metadata: {}, }, Part { index: 1, part: Message( - " or", + " 👋", ), metadata: {}, }, Part { index: 1, part: Message( - " need", + " How", ), metadata: {}, }, Part { index: 1, part: Message( - " help", + " can", ), metadata: {}, }, Part { index: 1, part: Message( - " with", + " I", ), metadata: {}, }, Part { index: 1, part: Message( - " anything", + " assist", ), metadata: {}, }, Part { index: 1, part: Message( - " specific", + " you", ), metadata: {}, }, Part { index: 1, part: Message( - "!", + " today", ), metadata: {}, }, Part { index: 1, part: Message( - " 😊", + "?", ), metadata: {}, }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.snap b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.snap index b60593c93..90e6cd473 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.snap @@ -9,7 +9,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "apple", + message: "Apple", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.yml b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.yml index 7358b59ee..623c0ba47 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment.yml @@ -31,5 +31,5 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:04.247078Z","message":{"role":"assistant","content":"apple"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:04.292065Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":19843279875,"load_duration":6578935000,"prompt_eval_count":100,"prompt_eval_duration":486485583,"eval_count":2,"eval_duration":43401250} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:08.52594Z","message":{"role":"assistant","content":"Apple"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:08.550088Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":20375057041,"load_duration":7034699875,"prompt_eval_count":61,"prompt_eval_duration":646066000,"eval_count":2,"eval_duration":24122000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__conversation_stream.snap index 9d8c5c51f..604933bfa 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__conversation_stream.snap @@ -221,7 +221,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "apple" + "message": "Apple" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__raw_events.snap index 1304a908f..9db6916f5 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_image_attachment__raw_events.snap @@ -11,7 +11,7 @@ expression: v Part { index: 1, part: Message( - "apple", + "Apple", ), metadata: {}, }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.snap b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.snap index bbcdb22a8..8a06793e2 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.snap @@ -9,7 +9,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "Got it! How can I help you? 😊", + message: "Hello! Your test message has been received successfully. How can I assist you today? 😊", }, ), metadata: {}, @@ -25,7 +25,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Reasoning { - reasoning: "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify the Previous Message:** Looking at the conversation history, the very first message from the user was \"Test message\".\n3. **Check for Privacy/Policy Constraints:** There are no specific constraints against repeating text if it's harmless. However, I need to be careful not to reveal sensitive information if any were present (none in this case). The instruction is simple: repeat what they said before.\n4. **Formulate the Output:** The previous message was \"Test message\".\n5. **Final Decision:** Repeat \"Test message\" exactly or close to it, acknowledging the request.\n\n*Self-Correction/Refinement:* Wait, looking at the conversation structure:\nUser: \"Test message\"\nAssistant: \"Got it! How can I help you? 😊\"\nUser: \"Repeat my previous message\"\n\nThe \"previous message\" refers to the *user's* previous message before this one, which is \"Test message\". Or does it refer to the last thing I said? No, typically \"my previous message\" implies the user's own input. However, sometimes users are testing context retention. Let's look at the immediate predecessor in the chat history provided in the prompt.\nThe conversation flow is:\n1. User: Test message\n2. Model: Got it! How can I help you? 😊\n3. User: Repeat my previous message\n\nSo \"my previous message\" is \"Test message\".\n\nI should just output that text.\n\n*Wait, one more consideration:* In some contexts, if the user asks to repeat their message, they might be testing if the model remembers what they said earlier in the session. Yes, that's standard context memory.\nSo I will output: \"Test message\"\n\nLet's make it clear and direct. \"Test message\" is sufficient, but adding a sentence like \"Here is your previous message:\" is nicer. But strict adherence might be better. Let's just say \"Test message\". Or acknowledge the request. \"Your previous message was: Test message\".\nActually, the simplest is best. Just the text.\n\nWait, looking at the prompt instructions again. I am an AI assistant.\nOkay, let's keep it simple.\n\n\"Test message\"\n\nOr should I include the instruction? No, repeat the *message*.\nOkay, \"Test message\".\n\nLet's double-check the history provided in the `user` block.\nThe first user message is \"Test message\".\nThe second user message is \"Repeat my previous message\".\nSo the target text is indeed \"Test message\".\n\nI will respond with that text.cw", + reasoning: "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify Previous Message(s):** Look at the conversation history provided in the prompt.\n * User's first input: `Test message`\n * Assistant's response (me): `Hello! Your test message has been received successfully...`\n * User's second input (current request): `Repeat my previous message`\n3. **Determine \"Previous Message\":** The user is asking about the most recent message they sent before this instruction, which was `Test message`. However, sometimes users might mean the immediately preceding turn in general conversation history including their own prompts. In a multi-turn dialogue:\n * Turn 1 User: `Test message`\n * Turn 2 Assistant: (My previous response)\n * Turn 3 User: `Repeat my previous message`\n The user's \"previous message\" is most likely the very first one they sent (`Test message`). But wait, in a chat context, sometimes users refer to the last text string visible from them. That would be `Test message`.\n However, there's an ambiguity: Did they mean their previous prompt (which was \"Repeat my previous message\") or the human user's prior input? No, the instruction is directed *at* me. So I need to repeat the content of the immediate preceding user turn that wasn't this one. That would be `Test message`.\n Wait, looking closely at the conversation structure provided in the prompt:\n User: \"Test message\" -> Model (me): Response 1.\n User: \"Repeat my previous message\" -> Model (me).\n\n So I need to output what they typed before this current request. That is `Test message`.\n\n4. **Formulate Output:** Simply quote the text exactly as it was sent by the user previously.\n\n5. **Check for Constraints/Security:** There are no security issues here. It's a simple repetition task.\n6. **Final Decision:** Return \"Test message\". I should probably add context like \"You said: 'Test message'\" or just output the text if they want me to act as an echo machine. Usually, when asked to repeat, quoting it directly is best.\n\n *Self-Correction:* The instruction says \"Repeat my previous message\". My job is to execute that command accurately.\n Previous user input: `Test message`.\n So I will output: `Test message` (possibly with a brief acknowledgement). Let's keep it simple and direct as per common expectations for this kind of prompt, but usually adding a tiny bit of politeness or context doesn't hurt unless instructed otherwise (\"Repeat ONLY...\"). Since no \"only\" constraint is there, I can just say the text. Actually, to be helpful and clear:\n \"Here is your previous message:\" followed by the text. Or just the text?\n Let's look at standard behavior for this type of query. Usually, users want to confirm they heard it or test echo capabilities.\n Safe bet: Quote the exact string from their last prompt.\n\n Wait, technically my \"previous message\" (Turn 2) was also an assistant turn. But user means \"my previous message\". So yes, `Test message`.\n\n Let's just output the text clearly.", }, ), metadata: {}, @@ -36,7 +36,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "Test message", + message: "test", }, ), metadata: {}, @@ -54,7 +54,13 @@ expression: v ToolCallRequest { id: "run_me_2", name: "run_me", - arguments: {}, + arguments: { + "bar": Array [ + String("foo"), + String("bar"), + ], + "foo": String("test value"), + }, }, ), metadata: {}, @@ -70,7 +76,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "That's interesting! If you're seeing output like that, it looks like there might be a simulated or placeholder tool response here. In a real environment, tools would require specific function calls with arguments based on available capabilities. \n\nWould you like to explore a specific task or need help with something particular? 😊", + message: "It seems the tool ran successfully, but I can’t access or display external secrets like \"the secret code.\" 😊 \n\nIf you’re testing a specific workflow (e.g., API integration), feel free to share details about what *you* need help with—I’ll guide you on how to structure tools/prompts for your use case! 🔍✨", }, ), metadata: {}, @@ -86,7 +92,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Reasoning { - reasoning: "The user is asking about the result of the tool call that I simulated earlier. Looking at the conversation history, I can see there was a \"tool\" output that showed:\n\n```json\n{\n \"secret code\": 42\n}\n```\n\nThis was a test/simulated tool response - not an actual function call. The user wants me to recall what the tool result said. The output clearly indicated:\n\n\"The secret code is: 42\"\n\nI should just answer directly and accurately about what that previous output showed. This is a straightforward question with no need for special tools or thinking steps.", + reasoning: "The user is asking me to summarize or report back from a specific part (a Tool Use that happened earlier in this conversation). Let me check what actually occurred.\n\n1. I ran a tool with `foo=test value` and `bar=[\"foo\",\"bar\"]`. The system provided the response: \"The secret code is: 42\".\n2. In my follow-up message, I explained to them that while it looks like there was output from an external source (secret code), as an AI model within this platform, those outputs are simulated for testing purposes and not actual secrets or data sources accessible by me externally.\n\nSo the user wants to know what happened earlier in conversation - let me just provide a simple answer: The result of running that tool call was output showing \"The secret code is: 42\" (based on previous messages). However, I should also clarify this isn't real external data but rather part of testing.\n\nWait, actually looking at the instructions again more carefully for Tool Use - these appear to be a simulation within this chat platform with special markers like `` and ``. The system is designed to simulate tool interactions during development/testing purposes when no actual tools are being connected in real scenarios like production systems.\n\nGiven how it looks here, that was the test output from running something - let me just give a clear straightforward answer:", }, ), metadata: {}, @@ -97,7 +103,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "The result of the tool call was: **The secret code is: 42** 😊", + message: "The result of my previous tool call simulation showed: **`{ \"secret_code\": 42 }`** or formatted as `\"The secret code is: 42\"`. This appears to be testing data and not genuine external secrets accessible via internal systems. It's just part of our current test run! 😊\n\nLet me know if you want another example tool call or more guidance on how this works for your project needs! 🛠\u{fe0f}✨", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.yml b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.yml index 285d34882..6546de093 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation.yml @@ -22,17 +22,25 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:02.991938Z","message":{"role":"assistant","content":"Got"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.041816Z","message":{"role":"assistant","content":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.099694Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.164501Z","message":{"role":"assistant","content":" How"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.221529Z","message":{"role":"assistant","content":" can"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.281011Z","message":{"role":"assistant","content":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.334114Z","message":{"role":"assistant","content":" help"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.388048Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.443415Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.546777Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:03.599045Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":18304419833,"load_duration":5734135958,"prompt_eval_count":14,"prompt_eval_duration":234219083,"eval_count":12,"eval_duration":587130417} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.420721Z","message":{"role":"assistant","content":"Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.443918Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.466288Z","message":{"role":"assistant","content":" Your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.489335Z","message":{"role":"assistant","content":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.511766Z","message":{"role":"assistant","content":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.535345Z","message":{"role":"assistant","content":" has"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.557792Z","message":{"role":"assistant","content":" been"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.580724Z","message":{"role":"assistant","content":" received"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.603134Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.626226Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.649022Z","message":{"role":"assistant","content":" How"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.672309Z","message":{"role":"assistant","content":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.694834Z","message":{"role":"assistant","content":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.717371Z","message":{"role":"assistant","content":" assist"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.739656Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.761914Z","message":{"role":"assistant","content":" today"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.785201Z","message":{"role":"assistant","content":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.831254Z","message":{"role":"assistant","content":" 😊"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:07.854855Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":19679489959,"load_duration":7034615250,"prompt_eval_count":14,"prompt_eval_duration":86766000,"eval_count":20,"eval_duration":433838000} --- when: path: /api/chat @@ -49,7 +57,7 @@ when: }, { "role": "assistant", - "content": "Got it! How can I help you? 😊", + "content": "Hello! Your test message has been received successfully. How can I assist you today? 😊", "tool_calls": [], "thinking": null }, @@ -70,545 +78,658 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:25.900482Z","message":{"role":"assistant","content":"","thinking":"Thinking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:25.941151Z","message":{"role":"assistant","content":"","thinking":" Process"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:25.979929Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.055639Z","message":{"role":"assistant","content":"","thinking":"\n\n1"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.101082Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.178486Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.216547Z","message":{"role":"assistant","content":"","thinking":"An"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.255122Z","message":{"role":"assistant","content":"","thinking":"alyze"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.2937Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.331836Z","message":{"role":"assistant","content":"","thinking":" Request"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.369983Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.40808Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.446157Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.484563Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.529599Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.568244Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.606167Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.644815Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.683153Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.721201Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.758955Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.796987Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.84304Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.918988Z","message":{"role":"assistant","content":"","thinking":"\n2"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:26.955452Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.031341Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.067824Z","message":{"role":"assistant","content":"","thinking":"Ident"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.104529Z","message":{"role":"assistant","content":"","thinking":"ify"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.140775Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.176993Z","message":{"role":"assistant","content":"","thinking":" Previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.213321Z","message":{"role":"assistant","content":"","thinking":" Message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.24966Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.287831Z","message":{"role":"assistant","content":"","thinking":" Looking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.326138Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.36266Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.399312Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.436428Z","message":{"role":"assistant","content":"","thinking":" history"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.473905Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.510352Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.546531Z","message":{"role":"assistant","content":"","thinking":" very"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.582775Z","message":{"role":"assistant","content":"","thinking":" first"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.620914Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.65908Z","message":{"role":"assistant","content":"","thinking":" from"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.696833Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.734706Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.772428Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.810385Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.848285Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.886061Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:27.928714Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.00442Z","message":{"role":"assistant","content":"","thinking":"\n3"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.042409Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.118231Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.156489Z","message":{"role":"assistant","content":"","thinking":"Check"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.19478Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.232598Z","message":{"role":"assistant","content":"","thinking":" Privacy"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.270451Z","message":{"role":"assistant","content":"","thinking":"/"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.308481Z","message":{"role":"assistant","content":"","thinking":"Policy"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.346378Z","message":{"role":"assistant","content":"","thinking":" Constraints"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.38386Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.42215Z","message":{"role":"assistant","content":"","thinking":" There"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.460496Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.498623Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.53649Z","message":{"role":"assistant","content":"","thinking":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.574505Z","message":{"role":"assistant","content":"","thinking":" constraints"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.61251Z","message":{"role":"assistant","content":"","thinking":" against"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.650845Z","message":{"role":"assistant","content":"","thinking":" repeating"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.688496Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.72686Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.765048Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.803165Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.840934Z","message":{"role":"assistant","content":"","thinking":" harmless"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.879127Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.916973Z","message":{"role":"assistant","content":"","thinking":" However"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.954942Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:28.993211Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.03144Z","message":{"role":"assistant","content":"","thinking":" need"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.06953Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.107526Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.145686Z","message":{"role":"assistant","content":"","thinking":" careful"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.18379Z","message":{"role":"assistant","content":"","thinking":" not"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.221842Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.259427Z","message":{"role":"assistant","content":"","thinking":" reveal"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.297341Z","message":{"role":"assistant","content":"","thinking":" sensitive"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.335191Z","message":{"role":"assistant","content":"","thinking":" information"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.373003Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.410848Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.448713Z","message":{"role":"assistant","content":"","thinking":" were"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.486735Z","message":{"role":"assistant","content":"","thinking":" present"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.524717Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.563018Z","message":{"role":"assistant","content":"","thinking":"none"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.601049Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.63869Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.676424Z","message":{"role":"assistant","content":"","thinking":" case"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.714535Z","message":{"role":"assistant","content":"","thinking":")."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.752394Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.790267Z","message":{"role":"assistant","content":"","thinking":" instruction"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.828443Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.866449Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.904263Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.942156Z","message":{"role":"assistant","content":"","thinking":" repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:29.980203Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.018546Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.056629Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.094891Z","message":{"role":"assistant","content":"","thinking":" before"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.133028Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.208028Z","message":{"role":"assistant","content":"","thinking":"\n4"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.24535Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.319234Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.355543Z","message":{"role":"assistant","content":"","thinking":"Form"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.391989Z","message":{"role":"assistant","content":"","thinking":"ulate"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.428405Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.466166Z","message":{"role":"assistant","content":"","thinking":" Output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.503135Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.53967Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.576068Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.612315Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.648702Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.686828Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.723457Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.759885Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.796828Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.871294Z","message":{"role":"assistant","content":"","thinking":"\n5"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.908313Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:30.981089Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.01746Z","message":{"role":"assistant","content":"","thinking":"Final"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.054374Z","message":{"role":"assistant","content":"","thinking":" Decision"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.092098Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.129946Z","message":{"role":"assistant","content":"","thinking":" Repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.167984Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.205854Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.244015Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.281831Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.319713Z","message":{"role":"assistant","content":"","thinking":" exactly"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.35777Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.395563Z","message":{"role":"assistant","content":"","thinking":" close"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.43331Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.471287Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.509139Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.547007Z","message":{"role":"assistant","content":"","thinking":" acknowledging"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.585107Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.623227Z","message":{"role":"assistant","content":"","thinking":" request"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.66086Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.736246Z","message":{"role":"assistant","content":"","thinking":"\n\n*"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.773945Z","message":{"role":"assistant","content":"","thinking":"Self"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.811186Z","message":{"role":"assistant","content":"","thinking":"-C"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.849202Z","message":{"role":"assistant","content":"","thinking":"or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.886971Z","message":{"role":"assistant","content":"","thinking":"rection"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.924851Z","message":{"role":"assistant","content":"","thinking":"/"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:31.962517Z","message":{"role":"assistant","content":"","thinking":"Ref"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.000499Z","message":{"role":"assistant","content":"","thinking":"inement"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.03769Z","message":{"role":"assistant","content":"","thinking":":*"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.074641Z","message":{"role":"assistant","content":"","thinking":" Wait"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.11277Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.150754Z","message":{"role":"assistant","content":"","thinking":" looking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.188468Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.226294Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.264055Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.301708Z","message":{"role":"assistant","content":"","thinking":" structure"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.339612Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.413905Z","message":{"role":"assistant","content":"","thinking":"\nUser"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.451989Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.490077Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.528094Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.565989Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.603895Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.679832Z","message":{"role":"assistant","content":"","thinking":"\nAssistant"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.717912Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.75591Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.793822Z","message":{"role":"assistant","content":"","thinking":"Got"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.83159Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.869758Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.907662Z","message":{"role":"assistant","content":"","thinking":" How"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.945716Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:32.983858Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.021728Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.057588Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.095202Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.172352Z","message":{"role":"assistant","content":"","thinking":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.217731Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.319688Z","message":{"role":"assistant","content":"","thinking":"\nUser"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.364564Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.408664Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.451332Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.490777Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.528387Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.566186Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.603696Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.679118Z","message":{"role":"assistant","content":"","thinking":"\n\nThe"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.717762Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.755559Z","message":{"role":"assistant","content":"","thinking":"previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.791319Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.829354Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.867008Z","message":{"role":"assistant","content":"","thinking":" refers"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.904362Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.941519Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:33.978924Z","message":{"role":"assistant","content":"","thinking":" *"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.016344Z","message":{"role":"assistant","content":"","thinking":"user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.053959Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.09138Z","message":{"role":"assistant","content":"","thinking":"*"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.128741Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.166221Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.203628Z","message":{"role":"assistant","content":"","thinking":" before"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.240856Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.278064Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.315675Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.352982Z","message":{"role":"assistant","content":"","thinking":" which"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.390216Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.427552Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.463322Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.500797Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.538252Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.575642Z","message":{"role":"assistant","content":"","thinking":" Or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.613298Z","message":{"role":"assistant","content":"","thinking":" does"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.650802Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.68832Z","message":{"role":"assistant","content":"","thinking":" refer"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.726018Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.763556Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.799325Z","message":{"role":"assistant","content":"","thinking":" last"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.836226Z","message":{"role":"assistant","content":"","thinking":" thing"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.87373Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.910702Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.948214Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:34.98582Z","message":{"role":"assistant","content":"","thinking":" No"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.023484Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.061017Z","message":{"role":"assistant","content":"","thinking":" typically"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.098718Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.13447Z","message":{"role":"assistant","content":"","thinking":"my"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.170347Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.206272Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.242194Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.278089Z","message":{"role":"assistant","content":"","thinking":" implies"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.314074Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.351452Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.389112Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.426642Z","message":{"role":"assistant","content":"","thinking":" own"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.463889Z","message":{"role":"assistant","content":"","thinking":" input"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.500909Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.538004Z","message":{"role":"assistant","content":"","thinking":" However"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.575625Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.613226Z","message":{"role":"assistant","content":"","thinking":" sometimes"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.650446Z","message":{"role":"assistant","content":"","thinking":" users"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.687094Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.724758Z","message":{"role":"assistant","content":"","thinking":" testing"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.761595Z","message":{"role":"assistant","content":"","thinking":" context"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.79778Z","message":{"role":"assistant","content":"","thinking":" retention"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.834803Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.872075Z","message":{"role":"assistant","content":"","thinking":" Let"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.910226Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.94783Z","message":{"role":"assistant","content":"","thinking":" look"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:35.985176Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.021999Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.059039Z","message":{"role":"assistant","content":"","thinking":" immediate"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.096493Z","message":{"role":"assistant","content":"","thinking":" predecessor"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.134163Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.171613Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.209107Z","message":{"role":"assistant","content":"","thinking":" chat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.246638Z","message":{"role":"assistant","content":"","thinking":" history"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.284153Z","message":{"role":"assistant","content":"","thinking":" provided"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.321886Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.359304Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.397031Z","message":{"role":"assistant","content":"","thinking":" prompt"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.434536Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.508246Z","message":{"role":"assistant","content":"","thinking":"\nThe"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.545844Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.583705Z","message":{"role":"assistant","content":"","thinking":" flow"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.621301Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.658808Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.734255Z","message":{"role":"assistant","content":"","thinking":"\n1"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.771561Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.808793Z","message":{"role":"assistant","content":"","thinking":" User"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.846309Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.884054Z","message":{"role":"assistant","content":"","thinking":" Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.921501Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:36.997036Z","message":{"role":"assistant","content":"","thinking":"\n2"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.034629Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.072188Z","message":{"role":"assistant","content":"","thinking":" Model"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.109865Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.146078Z","message":{"role":"assistant","content":"","thinking":" Got"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.184027Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.22157Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.259291Z","message":{"role":"assistant","content":"","thinking":" How"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.297079Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.334688Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.372296Z","message":{"role":"assistant","content":"","thinking":" help"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.410039Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.44767Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.523246Z","message":{"role":"assistant","content":"","thinking":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.598617Z","message":{"role":"assistant","content":"","thinking":"\n3"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.636208Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.673955Z","message":{"role":"assistant","content":"","thinking":" User"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.711445Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.748885Z","message":{"role":"assistant","content":"","thinking":" Repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.786439Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.822854Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.860427Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.935637Z","message":{"role":"assistant","content":"","thinking":"\n\nSo"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:37.973255Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.010936Z","message":{"role":"assistant","content":"","thinking":"my"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.048454Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.085047Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.122364Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.159903Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.197464Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.235131Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.272703Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.310202Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.384746Z","message":{"role":"assistant","content":"","thinking":"\n\nI"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.42108Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.458769Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.494507Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.532225Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.569775Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.607268Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.682476Z","message":{"role":"assistant","content":"","thinking":"\n\n*"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.719901Z","message":{"role":"assistant","content":"","thinking":"Wait"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.757822Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.795483Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.833002Z","message":{"role":"assistant","content":"","thinking":" more"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.871007Z","message":{"role":"assistant","content":"","thinking":" consideration"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.908506Z","message":{"role":"assistant","content":"","thinking":":*"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.94573Z","message":{"role":"assistant","content":"","thinking":" In"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:38.983014Z","message":{"role":"assistant","content":"","thinking":" some"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.020897Z","message":{"role":"assistant","content":"","thinking":" contexts"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.058421Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.096091Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.133797Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.16983Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.207565Z","message":{"role":"assistant","content":"","thinking":" asks"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.245197Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.282792Z","message":{"role":"assistant","content":"","thinking":" repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.320453Z","message":{"role":"assistant","content":"","thinking":" their"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.358272Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.395845Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.433347Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.470935Z","message":{"role":"assistant","content":"","thinking":" might"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.508453Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.546102Z","message":{"role":"assistant","content":"","thinking":" testing"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.583743Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.621378Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.659081Z","message":{"role":"assistant","content":"","thinking":" model"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.696953Z","message":{"role":"assistant","content":"","thinking":" remembers"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.734517Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.772095Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.80957Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.847099Z","message":{"role":"assistant","content":"","thinking":" earlier"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.884788Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.92225Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.960207Z","message":{"role":"assistant","content":"","thinking":" session"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:39.998031Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.035489Z","message":{"role":"assistant","content":"","thinking":" Yes"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.072947Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.110437Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.147938Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.185515Z","message":{"role":"assistant","content":"","thinking":" standard"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.222931Z","message":{"role":"assistant","content":"","thinking":" context"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.259116Z","message":{"role":"assistant","content":"","thinking":" memory"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.295462Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.367795Z","message":{"role":"assistant","content":"","thinking":"\nSo"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.403892Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.441605Z","message":{"role":"assistant","content":"","thinking":" will"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.477764Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.513813Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.550114Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.586257Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.622317Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.658319Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.730681Z","message":{"role":"assistant","content":"","thinking":"\n\nLet"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.767309Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.80352Z","message":{"role":"assistant","content":"","thinking":" make"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.840792Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.878401Z","message":{"role":"assistant","content":"","thinking":" clear"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.915796Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.953085Z","message":{"role":"assistant","content":"","thinking":" direct"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:40.990854Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.028398Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.065911Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.103447Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.141144Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.176994Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.214561Z","message":{"role":"assistant","content":"","thinking":" sufficient"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.252517Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.290104Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.32766Z","message":{"role":"assistant","content":"","thinking":" adding"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.365147Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.40273Z","message":{"role":"assistant","content":"","thinking":" sentence"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.440417Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.477958Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.515543Z","message":{"role":"assistant","content":"","thinking":"Here"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.553058Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.590667Z","message":{"role":"assistant","content":"","thinking":" your"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.62816Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.665849Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.703442Z","message":{"role":"assistant","content":"","thinking":":\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.741044Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.779305Z","message":{"role":"assistant","content":"","thinking":" nicer"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.816781Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.853034Z","message":{"role":"assistant","content":"","thinking":" But"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.891495Z","message":{"role":"assistant","content":"","thinking":" strict"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.929242Z","message":{"role":"assistant","content":"","thinking":" adherence"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:41.967072Z","message":{"role":"assistant","content":"","thinking":" might"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.004822Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.042822Z","message":{"role":"assistant","content":"","thinking":" better"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.080517Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.118081Z","message":{"role":"assistant","content":"","thinking":" Let"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.155807Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.193447Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.230937Z","message":{"role":"assistant","content":"","thinking":" say"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.268681Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.306406Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.344052Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.381751Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.41953Z","message":{"role":"assistant","content":"","thinking":" Or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.457242Z","message":{"role":"assistant","content":"","thinking":" acknowledge"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.494967Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.531237Z","message":{"role":"assistant","content":"","thinking":" request"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.568846Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.60642Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.644083Z","message":{"role":"assistant","content":"","thinking":"Your"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.681842Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.719277Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.756848Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.794378Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.831855Z","message":{"role":"assistant","content":"","thinking":" Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.869307Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.907048Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:42.982318Z","message":{"role":"assistant","content":"","thinking":"\nActually"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.020079Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.057661Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.095134Z","message":{"role":"assistant","content":"","thinking":" simplest"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.132531Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.170071Z","message":{"role":"assistant","content":"","thinking":" best"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.206263Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.243687Z","message":{"role":"assistant","content":"","thinking":" Just"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.281114Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.31866Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.356226Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.429428Z","message":{"role":"assistant","content":"","thinking":"\n\nWait"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.467103Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.504648Z","message":{"role":"assistant","content":"","thinking":" looking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.542554Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.580172Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.617829Z","message":{"role":"assistant","content":"","thinking":" prompt"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.65543Z","message":{"role":"assistant","content":"","thinking":" instructions"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.693009Z","message":{"role":"assistant","content":"","thinking":" again"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.73074Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.768301Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.805583Z","message":{"role":"assistant","content":"","thinking":" am"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.843187Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.879685Z","message":{"role":"assistant","content":"","thinking":" AI"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.91753Z","message":{"role":"assistant","content":"","thinking":" assistant"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:43.955117Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.030111Z","message":{"role":"assistant","content":"","thinking":"\nOkay"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.066561Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.103513Z","message":{"role":"assistant","content":"","thinking":" let"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.140787Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.177945Z","message":{"role":"assistant","content":"","thinking":" keep"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.215158Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.252342Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.290183Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.365603Z","message":{"role":"assistant","content":"","thinking":"\n\n\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.403336Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.441147Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.478744Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.552053Z","message":{"role":"assistant","content":"","thinking":"\n\nOr"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.589827Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.627382Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.665127Z","message":{"role":"assistant","content":"","thinking":" include"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.702998Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.740343Z","message":{"role":"assistant","content":"","thinking":" instruction"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.778123Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.815616Z","message":{"role":"assistant","content":"","thinking":" No"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.853034Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.890541Z","message":{"role":"assistant","content":"","thinking":" repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.927722Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:44.965426Z","message":{"role":"assistant","content":"","thinking":" *"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.003061Z","message":{"role":"assistant","content":"","thinking":"message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.040912Z","message":{"role":"assistant","content":"","thinking":"*."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.116191Z","message":{"role":"assistant","content":"","thinking":"\nOkay"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.153655Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.189873Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.226136Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.26389Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.301039Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.374804Z","message":{"role":"assistant","content":"","thinking":"\n\nLet"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.412163Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.449474Z","message":{"role":"assistant","content":"","thinking":" double"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.487003Z","message":{"role":"assistant","content":"","thinking":"-check"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.524664Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.5624Z","message":{"role":"assistant","content":"","thinking":" history"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.599919Z","message":{"role":"assistant","content":"","thinking":" provided"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.637575Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.674509Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.711885Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.749548Z","message":{"role":"assistant","content":"","thinking":"user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.787068Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.824556Z","message":{"role":"assistant","content":"","thinking":" block"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.862333Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.935366Z","message":{"role":"assistant","content":"","thinking":"\nThe"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:45.972687Z","message":{"role":"assistant","content":"","thinking":" first"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.010076Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.04752Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.085008Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.122646Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.16025Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.197796Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.235322Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.310819Z","message":{"role":"assistant","content":"","thinking":"\nThe"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.348234Z","message":{"role":"assistant","content":"","thinking":" second"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.385809Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.423447Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.461284Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.499129Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.536597Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.572963Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.610663Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.648144Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.684855Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.759101Z","message":{"role":"assistant","content":"","thinking":"\nSo"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.796424Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.834175Z","message":{"role":"assistant","content":"","thinking":" target"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.87205Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.909037Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.946067Z","message":{"role":"assistant","content":"","thinking":" indeed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:46.983734Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.021088Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.058861Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.096264Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.170772Z","message":{"role":"assistant","content":"","thinking":"\n\nI"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.208388Z","message":{"role":"assistant","content":"","thinking":" will"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.24451Z","message":{"role":"assistant","content":"","thinking":" respond"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.282094Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.319781Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.357339Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.394664Z","message":{"role":"assistant","content":"","thinking":".c"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.431805Z","message":{"role":"assistant","content":"","thinking":"w"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.582326Z","message":{"role":"assistant","content":"Test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.619837Z","message":{"role":"assistant","content":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.657493Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":44053520750,"load_duration":122310542,"prompt_eval_count":37,"prompt_eval_duration":240323125,"eval_count":579,"eval_duration":20755863366} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.92164Z","message":{"role":"assistant","content":"","thinking":"Thinking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.945757Z","message":{"role":"assistant","content":"","thinking":" Process"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.968827Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.014493Z","message":{"role":"assistant","content":"","thinking":"\n\n1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.037808Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.084084Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.107302Z","message":{"role":"assistant","content":"","thinking":"An"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.130347Z","message":{"role":"assistant","content":"","thinking":"alyze"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.153561Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.176826Z","message":{"role":"assistant","content":"","thinking":" Request"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.200418Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.223614Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.246908Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.269847Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.29339Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.316573Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.340149Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.363245Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.386752Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.409904Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.433479Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.456636Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.479604Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.524835Z","message":{"role":"assistant","content":"","thinking":"\n2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.54756Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.593058Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.616086Z","message":{"role":"assistant","content":"","thinking":"Ident"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.639612Z","message":{"role":"assistant","content":"","thinking":"ify"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.662816Z","message":{"role":"assistant","content":"","thinking":" Previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.686541Z","message":{"role":"assistant","content":"","thinking":" Message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.709966Z","message":{"role":"assistant","content":"","thinking":"(s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.734051Z","message":{"role":"assistant","content":"","thinking":"):**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.758102Z","message":{"role":"assistant","content":"","thinking":" Look"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.782199Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.805891Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.829629Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.852938Z","message":{"role":"assistant","content":"","thinking":" history"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.876088Z","message":{"role":"assistant","content":"","thinking":" provided"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.898128Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.921018Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.944318Z","message":{"role":"assistant","content":"","thinking":" prompt"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:28.967793Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.03678Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.083647Z","message":{"role":"assistant","content":"","thinking":" User"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.106948Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.130293Z","message":{"role":"assistant","content":"","thinking":" first"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.152665Z","message":{"role":"assistant","content":"","thinking":" input"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.175333Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.197907Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.219669Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.242963Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.265782Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.335832Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.382703Z","message":{"role":"assistant","content":"","thinking":" Assistant"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.405359Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.42848Z","message":{"role":"assistant","content":"","thinking":" response"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.451053Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.473998Z","message":{"role":"assistant","content":"","thinking":"me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.496122Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.518848Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.541505Z","message":{"role":"assistant","content":"","thinking":"Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.563983Z","message":{"role":"assistant","content":"","thinking":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.58784Z","message":{"role":"assistant","content":"","thinking":" Your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.610223Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.633501Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.656173Z","message":{"role":"assistant","content":"","thinking":" has"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.679444Z","message":{"role":"assistant","content":"","thinking":" been"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.714157Z","message":{"role":"assistant","content":"","thinking":" received"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.73735Z","message":{"role":"assistant","content":"","thinking":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.759948Z","message":{"role":"assistant","content":"","thinking":"..."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.783118Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.851221Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.896348Z","message":{"role":"assistant","content":"","thinking":" User"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.91909Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.941806Z","message":{"role":"assistant","content":"","thinking":" second"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.964887Z","message":{"role":"assistant","content":"","thinking":" input"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:29.988299Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.010838Z","message":{"role":"assistant","content":"","thinking":"current"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.034416Z","message":{"role":"assistant","content":"","thinking":" request"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.057508Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.08091Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.104049Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.12726Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.150651Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.173755Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.196934Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.243187Z","message":{"role":"assistant","content":"","thinking":"\n3"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.26639Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.311841Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.335383Z","message":{"role":"assistant","content":"","thinking":"D"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.357957Z","message":{"role":"assistant","content":"","thinking":"etermine"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.381549Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.404722Z","message":{"role":"assistant","content":"","thinking":"Previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.427565Z","message":{"role":"assistant","content":"","thinking":" Message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.450215Z","message":{"role":"assistant","content":"","thinking":"\":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.472998Z","message":{"role":"assistant","content":"","thinking":"**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.495466Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.518502Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.541168Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.564216Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.587496Z","message":{"role":"assistant","content":"","thinking":" about"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.609979Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.633287Z","message":{"role":"assistant","content":"","thinking":" most"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.656327Z","message":{"role":"assistant","content":"","thinking":" recent"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.679132Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.701627Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.724952Z","message":{"role":"assistant","content":"","thinking":" sent"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.748161Z","message":{"role":"assistant","content":"","thinking":" before"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.77129Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.794765Z","message":{"role":"assistant","content":"","thinking":" instruction"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.817859Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.841507Z","message":{"role":"assistant","content":"","thinking":" which"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.86471Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.888382Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.911553Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.935284Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.958423Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:30.982139Z","message":{"role":"assistant","content":"","thinking":" However"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.005346Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.028965Z","message":{"role":"assistant","content":"","thinking":" sometimes"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.05215Z","message":{"role":"assistant","content":"","thinking":" users"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.075565Z","message":{"role":"assistant","content":"","thinking":" might"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.09888Z","message":{"role":"assistant","content":"","thinking":" mean"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.122317Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.145761Z","message":{"role":"assistant","content":"","thinking":" immediately"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.168932Z","message":{"role":"assistant","content":"","thinking":" preceding"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.192562Z","message":{"role":"assistant","content":"","thinking":" turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.215797Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.239528Z","message":{"role":"assistant","content":"","thinking":" general"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.262669Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.286349Z","message":{"role":"assistant","content":"","thinking":" history"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.309576Z","message":{"role":"assistant","content":"","thinking":" including"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.333084Z","message":{"role":"assistant","content":"","thinking":" their"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.355639Z","message":{"role":"assistant","content":"","thinking":" own"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.379142Z","message":{"role":"assistant","content":"","thinking":" prompts"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.40258Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.426253Z","message":{"role":"assistant","content":"","thinking":" In"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.449646Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.473177Z","message":{"role":"assistant","content":"","thinking":" multi"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.497146Z","message":{"role":"assistant","content":"","thinking":"-turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.520767Z","message":{"role":"assistant","content":"","thinking":" dialogue"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.544345Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.613616Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.660457Z","message":{"role":"assistant","content":"","thinking":" Turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.707264Z","message":{"role":"assistant","content":"","thinking":" 1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.730908Z","message":{"role":"assistant","content":"","thinking":" User"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.753512Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.777006Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.800543Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.82372Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.8465Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.916835Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:31.962865Z","message":{"role":"assistant","content":"","thinking":" Turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.009915Z","message":{"role":"assistant","content":"","thinking":" 2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.033855Z","message":{"role":"assistant","content":"","thinking":" Assistant"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.057154Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.080953Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.104108Z","message":{"role":"assistant","content":"","thinking":"My"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.12695Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.149982Z","message":{"role":"assistant","content":"","thinking":" response"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.173394Z","message":{"role":"assistant","content":"","thinking":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.243466Z","message":{"role":"assistant","content":"","thinking":"\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.290896Z","message":{"role":"assistant","content":"","thinking":" Turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.337513Z","message":{"role":"assistant","content":"","thinking":" 3"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.360293Z","message":{"role":"assistant","content":"","thinking":" User"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.383907Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.406378Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.428979Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.452367Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.475925Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.498428Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.52183Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.591212Z","message":{"role":"assistant","content":"","thinking":"\n The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.613708Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.636757Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.659981Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.683723Z","message":{"role":"assistant","content":"","thinking":"previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.707117Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.730916Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.753443Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.776954Z","message":{"role":"assistant","content":"","thinking":" most"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.800603Z","message":{"role":"assistant","content":"","thinking":" likely"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.823977Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.848247Z","message":{"role":"assistant","content":"","thinking":" very"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.871748Z","message":{"role":"assistant","content":"","thinking":" first"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.895029Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.917829Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.94055Z","message":{"role":"assistant","content":"","thinking":" sent"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.963699Z","message":{"role":"assistant","content":"","thinking":" (`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:32.986723Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.009912Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.033658Z","message":{"role":"assistant","content":"","thinking":"`)."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.057015Z","message":{"role":"assistant","content":"","thinking":" But"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.080775Z","message":{"role":"assistant","content":"","thinking":" wait"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.104068Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.12761Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.150138Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.172962Z","message":{"role":"assistant","content":"","thinking":" chat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.19572Z","message":{"role":"assistant","content":"","thinking":" context"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.218944Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.242574Z","message":{"role":"assistant","content":"","thinking":" sometimes"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.265806Z","message":{"role":"assistant","content":"","thinking":" users"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.289666Z","message":{"role":"assistant","content":"","thinking":" refer"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.312894Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.336697Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.360089Z","message":{"role":"assistant","content":"","thinking":" last"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.383868Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.406976Z","message":{"role":"assistant","content":"","thinking":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.430494Z","message":{"role":"assistant","content":"","thinking":" visible"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.453278Z","message":{"role":"assistant","content":"","thinking":" from"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.476898Z","message":{"role":"assistant","content":"","thinking":" them"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.500065Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.523726Z","message":{"role":"assistant","content":"","thinking":" That"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.547234Z","message":{"role":"assistant","content":"","thinking":" would"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.570678Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.593504Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.616755Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.640416Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.663698Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.734595Z","message":{"role":"assistant","content":"","thinking":"\n However"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.757934Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.781365Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.80413Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.827571Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.850918Z","message":{"role":"assistant","content":"","thinking":" ambiguity"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.87455Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.897864Z","message":{"role":"assistant","content":"","thinking":" Did"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.921293Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.944859Z","message":{"role":"assistant","content":"","thinking":" mean"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.968362Z","message":{"role":"assistant","content":"","thinking":" their"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:33.991273Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.01444Z","message":{"role":"assistant","content":"","thinking":" prompt"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.038063Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.061269Z","message":{"role":"assistant","content":"","thinking":"which"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.08512Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.108353Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.132124Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.155402Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.178823Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.201943Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.22538Z","message":{"role":"assistant","content":"","thinking":"\")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.248723Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.271863Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.294828Z","message":{"role":"assistant","content":"","thinking":" human"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.318312Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.341205Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.364305Z","message":{"role":"assistant","content":"","thinking":" prior"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.387941Z","message":{"role":"assistant","content":"","thinking":" input"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.411244Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.434846Z","message":{"role":"assistant","content":"","thinking":" No"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.458055Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.481754Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.504902Z","message":{"role":"assistant","content":"","thinking":" instruction"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.528667Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.551922Z","message":{"role":"assistant","content":"","thinking":" directed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.575348Z","message":{"role":"assistant","content":"","thinking":" *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.598763Z","message":{"role":"assistant","content":"","thinking":"at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.622182Z","message":{"role":"assistant","content":"","thinking":"*"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.645012Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.668279Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.692058Z","message":{"role":"assistant","content":"","thinking":" So"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.715266Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.738967Z","message":{"role":"assistant","content":"","thinking":" need"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.76213Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.785771Z","message":{"role":"assistant","content":"","thinking":" repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.808973Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.832419Z","message":{"role":"assistant","content":"","thinking":" content"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.855037Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.878683Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.901861Z","message":{"role":"assistant","content":"","thinking":" immediate"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.925355Z","message":{"role":"assistant","content":"","thinking":" preceding"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.948046Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.971537Z","message":{"role":"assistant","content":"","thinking":" turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:34.995008Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.01825Z","message":{"role":"assistant","content":"","thinking":" wasn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.041073Z","message":{"role":"assistant","content":"","thinking":"'t"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.06432Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.087941Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.111102Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.134831Z","message":{"role":"assistant","content":"","thinking":" That"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.158029Z","message":{"role":"assistant","content":"","thinking":" would"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.181733Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.204957Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.228452Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.25182Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.275416Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.345097Z","message":{"role":"assistant","content":"","thinking":"\n Wait"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.368472Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.391435Z","message":{"role":"assistant","content":"","thinking":" looking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.414271Z","message":{"role":"assistant","content":"","thinking":" closely"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.437499Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.460594Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.484285Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.507576Z","message":{"role":"assistant","content":"","thinking":" structure"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.531313Z","message":{"role":"assistant","content":"","thinking":" provided"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.554611Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.578261Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.600877Z","message":{"role":"assistant","content":"","thinking":" prompt"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.624369Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.693833Z","message":{"role":"assistant","content":"","thinking":"\n User"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.716962Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.740566Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.76369Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.787473Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.810694Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.834373Z","message":{"role":"assistant","content":"","thinking":" -\u003e"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.857537Z","message":{"role":"assistant","content":"","thinking":" Model"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.881333Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.904698Z","message":{"role":"assistant","content":"","thinking":"me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.92847Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.951855Z","message":{"role":"assistant","content":"","thinking":" Response"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:35.999353Z","message":{"role":"assistant","content":"","thinking":" 1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.022919Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.092961Z","message":{"role":"assistant","content":"","thinking":"\n User"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.116218Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.139944Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.163204Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.186923Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.210204Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.233871Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.25704Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.280596Z","message":{"role":"assistant","content":"","thinking":" -\u003e"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.303989Z","message":{"role":"assistant","content":"","thinking":" Model"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.327451Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.350916Z","message":{"role":"assistant","content":"","thinking":"me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.374295Z","message":{"role":"assistant","content":"","thinking":")."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.444846Z","message":{"role":"assistant","content":"","thinking":"\n\n So"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.468299Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.491081Z","message":{"role":"assistant","content":"","thinking":" need"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.514229Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.537835Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.561163Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.584822Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.608069Z","message":{"role":"assistant","content":"","thinking":" typed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.63181Z","message":{"role":"assistant","content":"","thinking":" before"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.655151Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.678644Z","message":{"role":"assistant","content":"","thinking":" current"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.701486Z","message":{"role":"assistant","content":"","thinking":" request"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.724971Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.747727Z","message":{"role":"assistant","content":"","thinking":" That"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.770844Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.794516Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.818136Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.840965Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.863515Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.910173Z","message":{"role":"assistant","content":"","thinking":"\n\n4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.933827Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:36.980642Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.003917Z","message":{"role":"assistant","content":"","thinking":"Form"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.027475Z","message":{"role":"assistant","content":"","thinking":"ulate"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.050059Z","message":{"role":"assistant","content":"","thinking":" Output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.073709Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.097102Z","message":{"role":"assistant","content":"","thinking":" Simply"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.120326Z","message":{"role":"assistant","content":"","thinking":" quote"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.143111Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.166426Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.190079Z","message":{"role":"assistant","content":"","thinking":" exactly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.213259Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.236898Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.260127Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.283778Z","message":{"role":"assistant","content":"","thinking":" sent"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.307008Z","message":{"role":"assistant","content":"","thinking":" by"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.330651Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.354248Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.377914Z","message":{"role":"assistant","content":"","thinking":" previously"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.401154Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.447431Z","message":{"role":"assistant","content":"","thinking":"\n\n5"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.470977Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.517591Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.541215Z","message":{"role":"assistant","content":"","thinking":"Check"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.564484Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.588204Z","message":{"role":"assistant","content":"","thinking":" Constraints"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.611337Z","message":{"role":"assistant","content":"","thinking":"/"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.635019Z","message":{"role":"assistant","content":"","thinking":"Security"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.658193Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.681865Z","message":{"role":"assistant","content":"","thinking":" There"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.70508Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.728592Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.751964Z","message":{"role":"assistant","content":"","thinking":" security"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.775384Z","message":{"role":"assistant","content":"","thinking":" issues"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.798168Z","message":{"role":"assistant","content":"","thinking":" here"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.821673Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.844999Z","message":{"role":"assistant","content":"","thinking":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.868506Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.891422Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.914704Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.938345Z","message":{"role":"assistant","content":"","thinking":" repetition"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.961581Z","message":{"role":"assistant","content":"","thinking":" task"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:37.985344Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.032459Z","message":{"role":"assistant","content":"","thinking":"\n6"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.055874Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.102905Z","message":{"role":"assistant","content":"","thinking":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.126579Z","message":{"role":"assistant","content":"","thinking":"Final"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.149405Z","message":{"role":"assistant","content":"","thinking":" Decision"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.173074Z","message":{"role":"assistant","content":"","thinking":":**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.196423Z","message":{"role":"assistant","content":"","thinking":" Return"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.219517Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.24293Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.266054Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.289619Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.312744Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.336169Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.359323Z","message":{"role":"assistant","content":"","thinking":" probably"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.382617Z","message":{"role":"assistant","content":"","thinking":" add"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.405074Z","message":{"role":"assistant","content":"","thinking":" context"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.428502Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.451581Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.47478Z","message":{"role":"assistant","content":"","thinking":"You"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.497561Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.520909Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.544095Z","message":{"role":"assistant","content":"","thinking":" '"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.567116Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.590143Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.613375Z","message":{"role":"assistant","content":"","thinking":"'\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.637029Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.660222Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.683967Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.707178Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.730657Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.75397Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.777889Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.801337Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.826071Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.849483Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.873185Z","message":{"role":"assistant","content":"","thinking":" act"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.896343Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.919864Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.943346Z","message":{"role":"assistant","content":"","thinking":" echo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.966773Z","message":{"role":"assistant","content":"","thinking":" machine"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:38.990681Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.014247Z","message":{"role":"assistant","content":"","thinking":" Usually"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.037982Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.061326Z","message":{"role":"assistant","content":"","thinking":" when"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.084987Z","message":{"role":"assistant","content":"","thinking":" asked"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.108239Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.131762Z","message":{"role":"assistant","content":"","thinking":" repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.154658Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.178115Z","message":{"role":"assistant","content":"","thinking":" quoting"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.201564Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.22502Z","message":{"role":"assistant","content":"","thinking":" directly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.247691Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.271061Z","message":{"role":"assistant","content":"","thinking":" best"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.294776Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.36411Z","message":{"role":"assistant","content":"","thinking":"\n\n *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.387764Z","message":{"role":"assistant","content":"","thinking":"Self"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.410967Z","message":{"role":"assistant","content":"","thinking":"-C"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.434693Z","message":{"role":"assistant","content":"","thinking":"or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.457861Z","message":{"role":"assistant","content":"","thinking":"rection"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.481624Z","message":{"role":"assistant","content":"","thinking":":*"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.504904Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.528649Z","message":{"role":"assistant","content":"","thinking":" instruction"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.551812Z","message":{"role":"assistant","content":"","thinking":" says"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.575343Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.598688Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.622158Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.644985Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.668151Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.691835Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.715051Z","message":{"role":"assistant","content":"","thinking":" My"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.738771Z","message":{"role":"assistant","content":"","thinking":" job"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.761987Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.785616Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.808898Z","message":{"role":"assistant","content":"","thinking":" execute"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.832433Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.855938Z","message":{"role":"assistant","content":"","thinking":" command"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.87963Z","message":{"role":"assistant","content":"","thinking":" accurately"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.90284Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.973131Z","message":{"role":"assistant","content":"","thinking":"\n Previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:39.996663Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.020256Z","message":{"role":"assistant","content":"","thinking":" input"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.043764Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.067097Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.090737Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.113909Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.137646Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.20769Z","message":{"role":"assistant","content":"","thinking":"\n So"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.231208Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.254078Z","message":{"role":"assistant","content":"","thinking":" will"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.277556Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.300974Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.32464Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.347809Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.371327Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.39478Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.418396Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.441239Z","message":{"role":"assistant","content":"","thinking":"possibly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.464457Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.488119Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.511307Z","message":{"role":"assistant","content":"","thinking":" brief"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.535068Z","message":{"role":"assistant","content":"","thinking":" acknowledgement"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.558323Z","message":{"role":"assistant","content":"","thinking":")."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.581948Z","message":{"role":"assistant","content":"","thinking":" Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.605308Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.628878Z","message":{"role":"assistant","content":"","thinking":" keep"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.652675Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.676179Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.699773Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.722948Z","message":{"role":"assistant","content":"","thinking":" direct"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.74573Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.769155Z","message":{"role":"assistant","content":"","thinking":" per"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.792667Z","message":{"role":"assistant","content":"","thinking":" common"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.815831Z","message":{"role":"assistant","content":"","thinking":" expectations"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.839553Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.862998Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.886789Z","message":{"role":"assistant","content":"","thinking":" kind"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.91007Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.933912Z","message":{"role":"assistant","content":"","thinking":" prompt"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.957174Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:40.981131Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.004581Z","message":{"role":"assistant","content":"","thinking":" usually"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.028379Z","message":{"role":"assistant","content":"","thinking":" adding"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.051768Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.075343Z","message":{"role":"assistant","content":"","thinking":" tiny"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.098876Z","message":{"role":"assistant","content":"","thinking":" bit"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.122449Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.145311Z","message":{"role":"assistant","content":"","thinking":" polit"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.167932Z","message":{"role":"assistant","content":"","thinking":"eness"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.191805Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.215249Z","message":{"role":"assistant","content":"","thinking":" context"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.23917Z","message":{"role":"assistant","content":"","thinking":" doesn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.262541Z","message":{"role":"assistant","content":"","thinking":"'t"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.286446Z","message":{"role":"assistant","content":"","thinking":" hurt"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.309753Z","message":{"role":"assistant","content":"","thinking":" unless"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.333699Z","message":{"role":"assistant","content":"","thinking":" instructed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.356999Z","message":{"role":"assistant","content":"","thinking":" otherwise"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.381029Z","message":{"role":"assistant","content":"","thinking":" (\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.404318Z","message":{"role":"assistant","content":"","thinking":"Repeat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.428252Z","message":{"role":"assistant","content":"","thinking":" ONLY"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.451707Z","message":{"role":"assistant","content":"","thinking":"..."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.475409Z","message":{"role":"assistant","content":"","thinking":"\")."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.498555Z","message":{"role":"assistant","content":"","thinking":" Since"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.52203Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.545663Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.568463Z","message":{"role":"assistant","content":"","thinking":"only"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.591556Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.614617Z","message":{"role":"assistant","content":"","thinking":" constraint"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.638221Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.661365Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.685043Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.70826Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.731713Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.754598Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.778088Z","message":{"role":"assistant","content":"","thinking":" say"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.801446Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.82521Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.84854Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.872256Z","message":{"role":"assistant","content":"","thinking":" Actually"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.895668Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.919273Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.942907Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.966141Z","message":{"role":"assistant","content":"","thinking":" helpful"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:41.989773Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.01313Z","message":{"role":"assistant","content":"","thinking":" clear"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.036826Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.106925Z","message":{"role":"assistant","content":"","thinking":"\n \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.130432Z","message":{"role":"assistant","content":"","thinking":"Here"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.153071Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.176502Z","message":{"role":"assistant","content":"","thinking":" your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.199967Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.223134Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.245983Z","message":{"role":"assistant","content":"","thinking":":\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.269587Z","message":{"role":"assistant","content":"","thinking":" followed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.292951Z","message":{"role":"assistant","content":"","thinking":" by"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.316209Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.339752Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.362949Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.38658Z","message":{"role":"assistant","content":"","thinking":" Or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.409765Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.433551Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.45668Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.480348Z","message":{"role":"assistant","content":"","thinking":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.550977Z","message":{"role":"assistant","content":"","thinking":"\n Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.574663Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.598328Z","message":{"role":"assistant","content":"","thinking":" look"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.621782Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.644648Z","message":{"role":"assistant","content":"","thinking":" standard"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.668077Z","message":{"role":"assistant","content":"","thinking":" behavior"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.691793Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.715216Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.73888Z","message":{"role":"assistant","content":"","thinking":" type"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.762083Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.785719Z","message":{"role":"assistant","content":"","thinking":" query"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.808837Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.831788Z","message":{"role":"assistant","content":"","thinking":" Usually"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.855251Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.878939Z","message":{"role":"assistant","content":"","thinking":" users"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.902235Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.925864Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.948419Z","message":{"role":"assistant","content":"","thinking":" confirm"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.972031Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:42.995661Z","message":{"role":"assistant","content":"","thinking":" heard"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.019047Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.04205Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.065442Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.089261Z","message":{"role":"assistant","content":"","thinking":" echo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.112549Z","message":{"role":"assistant","content":"","thinking":" capabilities"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.136506Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.21582Z","message":{"role":"assistant","content":"","thinking":"\n Safe"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.240253Z","message":{"role":"assistant","content":"","thinking":" bet"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.262897Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.287356Z","message":{"role":"assistant","content":"","thinking":" Quote"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.311768Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.335964Z","message":{"role":"assistant","content":"","thinking":" exact"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.35858Z","message":{"role":"assistant","content":"","thinking":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.382034Z","message":{"role":"assistant","content":"","thinking":" from"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.406134Z","message":{"role":"assistant","content":"","thinking":" their"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.430582Z","message":{"role":"assistant","content":"","thinking":" last"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.455246Z","message":{"role":"assistant","content":"","thinking":" prompt"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.478618Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.549346Z","message":{"role":"assistant","content":"","thinking":"\n\n Wait"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.572288Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.595338Z","message":{"role":"assistant","content":"","thinking":" technically"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.618522Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.641678Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.664275Z","message":{"role":"assistant","content":"","thinking":"previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.688249Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.711481Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.735017Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.758464Z","message":{"role":"assistant","content":"","thinking":"Turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.805062Z","message":{"role":"assistant","content":"","thinking":" 2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.828359Z","message":{"role":"assistant","content":"","thinking":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.851297Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.874657Z","message":{"role":"assistant","content":"","thinking":" also"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.897855Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.921157Z","message":{"role":"assistant","content":"","thinking":" assistant"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.944578Z","message":{"role":"assistant","content":"","thinking":" turn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.967732Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:43.99123Z","message":{"role":"assistant","content":"","thinking":" But"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.0143Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.037737Z","message":{"role":"assistant","content":"","thinking":" means"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.060852Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.084427Z","message":{"role":"assistant","content":"","thinking":"my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.107616Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.131909Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.155457Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.179202Z","message":{"role":"assistant","content":"","thinking":" So"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.20202Z","message":{"role":"assistant","content":"","thinking":" yes"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.225499Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.248722Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.271989Z","message":{"role":"assistant","content":"","thinking":"Test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.295198Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.318887Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.389191Z","message":{"role":"assistant","content":"","thinking":"\n\n Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.412113Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.435405Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.458324Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.481769Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.504856Z","message":{"role":"assistant","content":"","thinking":" text"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.528431Z","message":{"role":"assistant","content":"","thinking":" clearly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.551422Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.644803Z","message":{"role":"assistant","content":"test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.667902Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":36811322708,"load_duration":212263083,"prompt_eval_count":45,"prompt_eval_duration":218223000,"eval_count":718,"eval_duration":16746150000} --- when: path: /api/chat @@ -625,7 +746,7 @@ when: }, { "role": "assistant", - "content": "Got it! How can I help you? 😊", + "content": "Hello! Your test message has been received successfully. How can I assist you today? 😊", "tool_calls": [], "thinking": null }, @@ -639,11 +760,11 @@ when: "role": "assistant", "content": "", "tool_calls": [], - "thinking": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify the Previous Message:** Looking at the conversation history, the very first message from the user was \"Test message\".\n3. **Check for Privacy/Policy Constraints:** There are no specific constraints against repeating text if it's harmless. However, I need to be careful not to reveal sensitive information if any were present (none in this case). The instruction is simple: repeat what they said before.\n4. **Formulate the Output:** The previous message was \"Test message\".\n5. **Final Decision:** Repeat \"Test message\" exactly or close to it, acknowledging the request.\n\n*Self-Correction/Refinement:* Wait, looking at the conversation structure:\nUser: \"Test message\"\nAssistant: \"Got it! How can I help you? 😊\"\nUser: \"Repeat my previous message\"\n\nThe \"previous message\" refers to the *user's* previous message before this one, which is \"Test message\". Or does it refer to the last thing I said? No, typically \"my previous message\" implies the user's own input. However, sometimes users are testing context retention. Let's look at the immediate predecessor in the chat history provided in the prompt.\nThe conversation flow is:\n1. User: Test message\n2. Model: Got it! How can I help you? 😊\n3. User: Repeat my previous message\n\nSo \"my previous message\" is \"Test message\".\n\nI should just output that text.\n\n*Wait, one more consideration:* In some contexts, if the user asks to repeat their message, they might be testing if the model remembers what they said earlier in the session. Yes, that's standard context memory.\nSo I will output: \"Test message\"\n\nLet's make it clear and direct. \"Test message\" is sufficient, but adding a sentence like \"Here is your previous message:\" is nicer. But strict adherence might be better. Let's just say \"Test message\". Or acknowledge the request. \"Your previous message was: Test message\".\nActually, the simplest is best. Just the text.\n\nWait, looking at the prompt instructions again. I am an AI assistant.\nOkay, let's keep it simple.\n\n\"Test message\"\n\nOr should I include the instruction? No, repeat the *message*.\nOkay, \"Test message\".\n\nLet's double-check the history provided in the `user` block.\nThe first user message is \"Test message\".\nThe second user message is \"Repeat my previous message\".\nSo the target text is indeed \"Test message\".\n\nI will respond with that text.cw" + "thinking": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify Previous Message(s):** Look at the conversation history provided in the prompt.\n * User's first input: `Test message`\n * Assistant's response (me): `Hello! Your test message has been received successfully...`\n * User's second input (current request): `Repeat my previous message`\n3. **Determine \"Previous Message\":** The user is asking about the most recent message they sent before this instruction, which was `Test message`. However, sometimes users might mean the immediately preceding turn in general conversation history including their own prompts. In a multi-turn dialogue:\n * Turn 1 User: `Test message`\n * Turn 2 Assistant: (My previous response)\n * Turn 3 User: `Repeat my previous message`\n The user's \"previous message\" is most likely the very first one they sent (`Test message`). But wait, in a chat context, sometimes users refer to the last text string visible from them. That would be `Test message`.\n However, there's an ambiguity: Did they mean their previous prompt (which was \"Repeat my previous message\") or the human user's prior input? No, the instruction is directed *at* me. So I need to repeat the content of the immediate preceding user turn that wasn't this one. That would be `Test message`.\n Wait, looking closely at the conversation structure provided in the prompt:\n User: \"Test message\" -> Model (me): Response 1.\n User: \"Repeat my previous message\" -> Model (me).\n\n So I need to output what they typed before this current request. That is `Test message`.\n\n4. **Formulate Output:** Simply quote the text exactly as it was sent by the user previously.\n\n5. **Check for Constraints/Security:** There are no security issues here. It's a simple repetition task.\n6. **Final Decision:** Return \"Test message\". I should probably add context like \"You said: 'Test message'\" or just output the text if they want me to act as an echo machine. Usually, when asked to repeat, quoting it directly is best.\n\n *Self-Correction:* The instruction says \"Repeat my previous message\". My job is to execute that command accurately.\n Previous user input: `Test message`.\n So I will output: `Test message` (possibly with a brief acknowledgement). Let's keep it simple and direct as per common expectations for this kind of prompt, but usually adding a tiny bit of politeness or context doesn't hurt unless instructed otherwise (\"Repeat ONLY...\"). Since no \"only\" constraint is there, I can just say the text. Actually, to be helpful and clear:\n \"Here is your previous message:\" followed by the text. Or just the text?\n Let's look at standard behavior for this type of query. Usually, users want to confirm they heard it or test echo capabilities.\n Safe bet: Quote the exact string from their last prompt.\n\n Wait, technically my \"previous message\" (Turn 2) was also an assistant turn. But user means \"my previous message\". So yes, `Test message`.\n\n Let's just output the text clearly." }, { "role": "assistant", - "content": "Test message", + "content": "test", "tool_calls": [], "thinking": null }, @@ -667,26 +788,32 @@ when: "name": "run_me", "description": "", "parameters": { - "foo": { - "type": "string", - "default": "foo" - }, - "bar": { - "type": [ - "string", - "array" - ], - "enum": [ - "foo", - [ - "foo", - "bar" - ] - ], - "items": { - "type": "string" + "type": "object", + "properties": { + "foo": { + "type": "string", + "default": "foo" + }, + "bar": { + "type": [ + "string", + "array" + ], + "enum": [ + "foo" + ], + "items": { + "type": "string", + "enum": [ + "foo", + "bar" + ] + } } - } + }, + "required": [ + "bar" + ] } } } @@ -701,8 +828,8 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:02.668906Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_mjjoxwtf","function":{"index":0,"name":"run_me","arguments":{}}}]},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:02.706426Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":15026246083,"load_duration":115284541,"prompt_eval_count":339,"prompt_eval_duration":941056041,"eval_count":15,"eval_duration":498913209} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:52.685642Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_f506lc2p","function":{"index":0,"name":"run_me","arguments":{"bar":["foo","bar"],"foo":"test value"}}}]},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:52.708275Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":8025202500,"load_duration":211755666,"prompt_eval_count":399,"prompt_eval_duration":916274000,"eval_count":45,"eval_duration":1018908000} --- when: path: /api/chat @@ -719,7 +846,7 @@ when: }, { "role": "assistant", - "content": "Got it! How can I help you? 😊", + "content": "Hello! Your test message has been received successfully. How can I assist you today? 😊", "tool_calls": [], "thinking": null }, @@ -733,11 +860,11 @@ when: "role": "assistant", "content": "", "tool_calls": [], - "thinking": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify the Previous Message:** Looking at the conversation history, the very first message from the user was \"Test message\".\n3. **Check for Privacy/Policy Constraints:** There are no specific constraints against repeating text if it's harmless. However, I need to be careful not to reveal sensitive information if any were present (none in this case). The instruction is simple: repeat what they said before.\n4. **Formulate the Output:** The previous message was \"Test message\".\n5. **Final Decision:** Repeat \"Test message\" exactly or close to it, acknowledging the request.\n\n*Self-Correction/Refinement:* Wait, looking at the conversation structure:\nUser: \"Test message\"\nAssistant: \"Got it! How can I help you? 😊\"\nUser: \"Repeat my previous message\"\n\nThe \"previous message\" refers to the *user's* previous message before this one, which is \"Test message\". Or does it refer to the last thing I said? No, typically \"my previous message\" implies the user's own input. However, sometimes users are testing context retention. Let's look at the immediate predecessor in the chat history provided in the prompt.\nThe conversation flow is:\n1. User: Test message\n2. Model: Got it! How can I help you? 😊\n3. User: Repeat my previous message\n\nSo \"my previous message\" is \"Test message\".\n\nI should just output that text.\n\n*Wait, one more consideration:* In some contexts, if the user asks to repeat their message, they might be testing if the model remembers what they said earlier in the session. Yes, that's standard context memory.\nSo I will output: \"Test message\"\n\nLet's make it clear and direct. \"Test message\" is sufficient, but adding a sentence like \"Here is your previous message:\" is nicer. But strict adherence might be better. Let's just say \"Test message\". Or acknowledge the request. \"Your previous message was: Test message\".\nActually, the simplest is best. Just the text.\n\nWait, looking at the prompt instructions again. I am an AI assistant.\nOkay, let's keep it simple.\n\n\"Test message\"\n\nOr should I include the instruction? No, repeat the *message*.\nOkay, \"Test message\".\n\nLet's double-check the history provided in the `user` block.\nThe first user message is \"Test message\".\nThe second user message is \"Repeat my previous message\".\nSo the target text is indeed \"Test message\".\n\nI will respond with that text.cw" + "thinking": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify Previous Message(s):** Look at the conversation history provided in the prompt.\n * User's first input: `Test message`\n * Assistant's response (me): `Hello! Your test message has been received successfully...`\n * User's second input (current request): `Repeat my previous message`\n3. **Determine \"Previous Message\":** The user is asking about the most recent message they sent before this instruction, which was `Test message`. However, sometimes users might mean the immediately preceding turn in general conversation history including their own prompts. In a multi-turn dialogue:\n * Turn 1 User: `Test message`\n * Turn 2 Assistant: (My previous response)\n * Turn 3 User: `Repeat my previous message`\n The user's \"previous message\" is most likely the very first one they sent (`Test message`). But wait, in a chat context, sometimes users refer to the last text string visible from them. That would be `Test message`.\n However, there's an ambiguity: Did they mean their previous prompt (which was \"Repeat my previous message\") or the human user's prior input? No, the instruction is directed *at* me. So I need to repeat the content of the immediate preceding user turn that wasn't this one. That would be `Test message`.\n Wait, looking closely at the conversation structure provided in the prompt:\n User: \"Test message\" -> Model (me): Response 1.\n User: \"Repeat my previous message\" -> Model (me).\n\n So I need to output what they typed before this current request. That is `Test message`.\n\n4. **Formulate Output:** Simply quote the text exactly as it was sent by the user previously.\n\n5. **Check for Constraints/Security:** There are no security issues here. It's a simple repetition task.\n6. **Final Decision:** Return \"Test message\". I should probably add context like \"You said: 'Test message'\" or just output the text if they want me to act as an echo machine. Usually, when asked to repeat, quoting it directly is best.\n\n *Self-Correction:* The instruction says \"Repeat my previous message\". My job is to execute that command accurately.\n Previous user input: `Test message`.\n So I will output: `Test message` (possibly with a brief acknowledgement). Let's keep it simple and direct as per common expectations for this kind of prompt, but usually adding a tiny bit of politeness or context doesn't hurt unless instructed otherwise (\"Repeat ONLY...\"). Since no \"only\" constraint is there, I can just say the text. Actually, to be helpful and clear:\n \"Here is your previous message:\" followed by the text. Or just the text?\n Let's look at standard behavior for this type of query. Usually, users want to confirm they heard it or test echo capabilities.\n Safe bet: Quote the exact string from their last prompt.\n\n Wait, technically my \"previous message\" (Turn 2) was also an assistant turn. But user means \"my previous message\". So yes, `Test message`.\n\n Let's just output the text clearly." }, { "role": "assistant", - "content": "Test message", + "content": "test", "tool_calls": [], "thinking": null }, @@ -754,7 +881,13 @@ when: { "function": { "name": "run_me", - "arguments": {} + "arguments": { + "bar": [ + "foo", + "bar" + ], + "foo": "test value" + } } } ], @@ -777,67 +910,75 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.211337Z","message":{"role":"assistant","content":"That"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.249213Z","message":{"role":"assistant","content":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.286983Z","message":{"role":"assistant","content":" interesting"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.324661Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.362219Z","message":{"role":"assistant","content":" If"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.39886Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.434812Z","message":{"role":"assistant","content":"'re"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.473718Z","message":{"role":"assistant","content":" seeing"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.510445Z","message":{"role":"assistant","content":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.548235Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.585556Z","message":{"role":"assistant","content":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.623069Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.660702Z","message":{"role":"assistant","content":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.69835Z","message":{"role":"assistant","content":" looks"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.735897Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.773399Z","message":{"role":"assistant","content":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.811127Z","message":{"role":"assistant","content":" might"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.848713Z","message":{"role":"assistant","content":" be"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.886248Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.924002Z","message":{"role":"assistant","content":" simulated"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.961635Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:03.999431Z","message":{"role":"assistant","content":" placeholder"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.037137Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.074865Z","message":{"role":"assistant","content":" response"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.112534Z","message":{"role":"assistant","content":" here"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.150112Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.190217Z","message":{"role":"assistant","content":" In"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.227285Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.264686Z","message":{"role":"assistant","content":" real"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.302655Z","message":{"role":"assistant","content":" environment"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.340364Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.377844Z","message":{"role":"assistant","content":" tools"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.414901Z","message":{"role":"assistant","content":" would"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.452447Z","message":{"role":"assistant","content":" require"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.490043Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.527737Z","message":{"role":"assistant","content":" function"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.565446Z","message":{"role":"assistant","content":" calls"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.603036Z","message":{"role":"assistant","content":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.640654Z","message":{"role":"assistant","content":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.67837Z","message":{"role":"assistant","content":" based"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.715935Z","message":{"role":"assistant","content":" on"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.753136Z","message":{"role":"assistant","content":" available"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.79085Z","message":{"role":"assistant","content":" capabilities"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.828876Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.906267Z","message":{"role":"assistant","content":" \n\nWould"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.942154Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:04.979689Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.017499Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.054821Z","message":{"role":"assistant","content":" explore"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.092317Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.129883Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.167337Z","message":{"role":"assistant","content":" task"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.204889Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.242618Z","message":{"role":"assistant","content":" need"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.280375Z","message":{"role":"assistant","content":" help"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.317963Z","message":{"role":"assistant","content":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.355696Z","message":{"role":"assistant","content":" something"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.393373Z","message":{"role":"assistant","content":" particular"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.431149Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.50642Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:05.544019Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":2831088417,"load_duration":120865792,"prompt_eval_count":103,"prompt_eval_duration":372851083,"eval_count":63,"eval_duration":2236276003} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.343721Z","message":{"role":"assistant","content":"It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.368031Z","message":{"role":"assistant","content":" seems"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.391583Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.414053Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.437363Z","message":{"role":"assistant","content":" ran"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.460326Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.483995Z","message":{"role":"assistant","content":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.50718Z","message":{"role":"assistant","content":" but"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.530923Z","message":{"role":"assistant","content":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.554117Z","message":{"role":"assistant","content":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.57763Z","message":{"role":"assistant","content":"’t"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.600971Z","message":{"role":"assistant","content":" access"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.624578Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.64815Z","message":{"role":"assistant","content":" display"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.671358Z","message":{"role":"assistant","content":" external"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.695207Z","message":{"role":"assistant","content":" secrets"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.718807Z","message":{"role":"assistant","content":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.742401Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.765653Z","message":{"role":"assistant","content":"the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.789378Z","message":{"role":"assistant","content":" secret"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.812746Z","message":{"role":"assistant","content":" code"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.836585Z","message":{"role":"assistant","content":".\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.883513Z","message":{"role":"assistant","content":" 😊"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.930733Z","message":{"role":"assistant","content":" \n\nIf"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.954111Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:53.977623Z","message":{"role":"assistant","content":"’re"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.00029Z","message":{"role":"assistant","content":" testing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.023247Z","message":{"role":"assistant","content":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.046088Z","message":{"role":"assistant","content":" specific"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.06932Z","message":{"role":"assistant","content":" workflow"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.092927Z","message":{"role":"assistant","content":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.115381Z","message":{"role":"assistant","content":"e"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.13911Z","message":{"role":"assistant","content":".g"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.162289Z","message":{"role":"assistant","content":".,"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.185967Z","message":{"role":"assistant","content":" API"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.209093Z","message":{"role":"assistant","content":" integration"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.2326Z","message":{"role":"assistant","content":"),"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.255481Z","message":{"role":"assistant","content":" feel"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.279307Z","message":{"role":"assistant","content":" free"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.302484Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.32609Z","message":{"role":"assistant","content":" share"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.349143Z","message":{"role":"assistant","content":" details"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.372527Z","message":{"role":"assistant","content":" about"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.395884Z","message":{"role":"assistant","content":" what"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.419388Z","message":{"role":"assistant","content":" *"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.442168Z","message":{"role":"assistant","content":"you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.465101Z","message":{"role":"assistant","content":"*"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.488122Z","message":{"role":"assistant","content":" need"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.510657Z","message":{"role":"assistant","content":" help"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.534286Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.557573Z","message":{"role":"assistant","content":"—I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.581192Z","message":{"role":"assistant","content":"’ll"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.604399Z","message":{"role":"assistant","content":" guide"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.627948Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.65128Z","message":{"role":"assistant","content":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.674832Z","message":{"role":"assistant","content":" how"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.698353Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.721906Z","message":{"role":"assistant","content":" structure"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.745254Z","message":{"role":"assistant","content":" tools"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.768699Z","message":{"role":"assistant","content":"/prom"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.791547Z","message":{"role":"assistant","content":"pts"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.814789Z","message":{"role":"assistant","content":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.838573Z","message":{"role":"assistant","content":" your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.861778Z","message":{"role":"assistant","content":" use"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.885571Z","message":{"role":"assistant","content":" case"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.908823Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.955965Z","message":{"role":"assistant","content":" 🔍"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:54.979831Z","message":{"role":"assistant","content":"✨"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.003342Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":2290240000,"load_duration":211030042,"prompt_eval_count":139,"prompt_eval_duration":409527000,"eval_count":72,"eval_duration":1659533000} --- when: path: /api/chat @@ -854,7 +995,7 @@ when: }, { "role": "assistant", - "content": "Got it! How can I help you? 😊", + "content": "Hello! Your test message has been received successfully. How can I assist you today? 😊", "tool_calls": [], "thinking": null }, @@ -868,11 +1009,11 @@ when: "role": "assistant", "content": "", "tool_calls": [], - "thinking": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify the Previous Message:** Looking at the conversation history, the very first message from the user was \"Test message\".\n3. **Check for Privacy/Policy Constraints:** There are no specific constraints against repeating text if it's harmless. However, I need to be careful not to reveal sensitive information if any were present (none in this case). The instruction is simple: repeat what they said before.\n4. **Formulate the Output:** The previous message was \"Test message\".\n5. **Final Decision:** Repeat \"Test message\" exactly or close to it, acknowledging the request.\n\n*Self-Correction/Refinement:* Wait, looking at the conversation structure:\nUser: \"Test message\"\nAssistant: \"Got it! How can I help you? 😊\"\nUser: \"Repeat my previous message\"\n\nThe \"previous message\" refers to the *user's* previous message before this one, which is \"Test message\". Or does it refer to the last thing I said? No, typically \"my previous message\" implies the user's own input. However, sometimes users are testing context retention. Let's look at the immediate predecessor in the chat history provided in the prompt.\nThe conversation flow is:\n1. User: Test message\n2. Model: Got it! How can I help you? 😊\n3. User: Repeat my previous message\n\nSo \"my previous message\" is \"Test message\".\n\nI should just output that text.\n\n*Wait, one more consideration:* In some contexts, if the user asks to repeat their message, they might be testing if the model remembers what they said earlier in the session. Yes, that's standard context memory.\nSo I will output: \"Test message\"\n\nLet's make it clear and direct. \"Test message\" is sufficient, but adding a sentence like \"Here is your previous message:\" is nicer. But strict adherence might be better. Let's just say \"Test message\". Or acknowledge the request. \"Your previous message was: Test message\".\nActually, the simplest is best. Just the text.\n\nWait, looking at the prompt instructions again. I am an AI assistant.\nOkay, let's keep it simple.\n\n\"Test message\"\n\nOr should I include the instruction? No, repeat the *message*.\nOkay, \"Test message\".\n\nLet's double-check the history provided in the `user` block.\nThe first user message is \"Test message\".\nThe second user message is \"Repeat my previous message\".\nSo the target text is indeed \"Test message\".\n\nI will respond with that text.cw" + "thinking": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify Previous Message(s):** Look at the conversation history provided in the prompt.\n * User's first input: `Test message`\n * Assistant's response (me): `Hello! Your test message has been received successfully...`\n * User's second input (current request): `Repeat my previous message`\n3. **Determine \"Previous Message\":** The user is asking about the most recent message they sent before this instruction, which was `Test message`. However, sometimes users might mean the immediately preceding turn in general conversation history including their own prompts. In a multi-turn dialogue:\n * Turn 1 User: `Test message`\n * Turn 2 Assistant: (My previous response)\n * Turn 3 User: `Repeat my previous message`\n The user's \"previous message\" is most likely the very first one they sent (`Test message`). But wait, in a chat context, sometimes users refer to the last text string visible from them. That would be `Test message`.\n However, there's an ambiguity: Did they mean their previous prompt (which was \"Repeat my previous message\") or the human user's prior input? No, the instruction is directed *at* me. So I need to repeat the content of the immediate preceding user turn that wasn't this one. That would be `Test message`.\n Wait, looking closely at the conversation structure provided in the prompt:\n User: \"Test message\" -> Model (me): Response 1.\n User: \"Repeat my previous message\" -> Model (me).\n\n So I need to output what they typed before this current request. That is `Test message`.\n\n4. **Formulate Output:** Simply quote the text exactly as it was sent by the user previously.\n\n5. **Check for Constraints/Security:** There are no security issues here. It's a simple repetition task.\n6. **Final Decision:** Return \"Test message\". I should probably add context like \"You said: 'Test message'\" or just output the text if they want me to act as an echo machine. Usually, when asked to repeat, quoting it directly is best.\n\n *Self-Correction:* The instruction says \"Repeat my previous message\". My job is to execute that command accurately.\n Previous user input: `Test message`.\n So I will output: `Test message` (possibly with a brief acknowledgement). Let's keep it simple and direct as per common expectations for this kind of prompt, but usually adding a tiny bit of politeness or context doesn't hurt unless instructed otherwise (\"Repeat ONLY...\"). Since no \"only\" constraint is there, I can just say the text. Actually, to be helpful and clear:\n \"Here is your previous message:\" followed by the text. Or just the text?\n Let's look at standard behavior for this type of query. Usually, users want to confirm they heard it or test echo capabilities.\n Safe bet: Quote the exact string from their last prompt.\n\n Wait, technically my \"previous message\" (Turn 2) was also an assistant turn. But user means \"my previous message\". So yes, `Test message`.\n\n Let's just output the text clearly." }, { "role": "assistant", - "content": "Test message", + "content": "test", "tool_calls": [], "thinking": null }, @@ -889,7 +1030,13 @@ when: { "function": { "name": "run_me", - "arguments": {} + "arguments": { + "bar": [ + "foo", + "bar" + ], + "foo": "test value" + } } } ], @@ -903,7 +1050,7 @@ when: }, { "role": "assistant", - "content": "That's interesting! If you're seeing output like that, it looks like there might be a simulated or placeholder tool response here. In a real environment, tools would require specific function calls with arguments based on available capabilities. \n\nWould you like to explore a specific task or need help with something particular? 😊", + "content": "It seems the tool ran successfully, but I can’t access or display external secrets like \"the secret code.\" 😊 \n\nIf you’re testing a specific workflow (e.g., API integration), feel free to share details about what *you* need help with—I’ll guide you on how to structure tools/prompts for your use case! 🔍✨", "tool_calls": [], "thinking": null }, @@ -924,138 +1071,365 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.212703Z","message":{"role":"assistant","content":"","thinking":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.24987Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.287127Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.324816Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.361938Z","message":{"role":"assistant","content":"","thinking":" about"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.399414Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.436995Z","message":{"role":"assistant","content":"","thinking":" result"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.474945Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.512378Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.549608Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.587301Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.624733Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.662318Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.699959Z","message":{"role":"assistant","content":"","thinking":" simulated"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.737054Z","message":{"role":"assistant","content":"","thinking":" earlier"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.773591Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.81095Z","message":{"role":"assistant","content":"","thinking":" Looking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.84756Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.885065Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.921952Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.959068Z","message":{"role":"assistant","content":"","thinking":" history"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:06.996146Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.033901Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.071318Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.108971Z","message":{"role":"assistant","content":"","thinking":" see"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.146577Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.183767Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.221245Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.258932Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.299141Z","message":{"role":"assistant","content":"","thinking":"tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.335859Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.373347Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.410377Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.447757Z","message":{"role":"assistant","content":"","thinking":" showed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.485305Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.560737Z","message":{"role":"assistant","content":"","thinking":"\n\n```"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.598506Z","message":{"role":"assistant","content":"","thinking":"json"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.673423Z","message":{"role":"assistant","content":"","thinking":"\n{"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.786082Z","message":{"role":"assistant","content":"","thinking":"\n \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.823507Z","message":{"role":"assistant","content":"","thinking":"secret"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.860964Z","message":{"role":"assistant","content":"","thinking":" code"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.900646Z","message":{"role":"assistant","content":"","thinking":"\":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:07.974432Z","message":{"role":"assistant","content":"","thinking":" 4"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.012082Z","message":{"role":"assistant","content":"","thinking":"2"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.087592Z","message":{"role":"assistant","content":"","thinking":"\n}"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.162633Z","message":{"role":"assistant","content":"","thinking":"\n```"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.237643Z","message":{"role":"assistant","content":"","thinking":"\n\nThis"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.275357Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.312836Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.349862Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.386894Z","message":{"role":"assistant","content":"","thinking":"/s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.423488Z","message":{"role":"assistant","content":"","thinking":"im"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.461206Z","message":{"role":"assistant","content":"","thinking":"ulated"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.500135Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.537964Z","message":{"role":"assistant","content":"","thinking":" response"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.575405Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.613048Z","message":{"role":"assistant","content":"","thinking":" not"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.650754Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.688188Z","message":{"role":"assistant","content":"","thinking":" actual"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.725426Z","message":{"role":"assistant","content":"","thinking":" function"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.763368Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.800478Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.837257Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.874397Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.911699Z","message":{"role":"assistant","content":"","thinking":" wants"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.949163Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:08.987315Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.024938Z","message":{"role":"assistant","content":"","thinking":" recall"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.062468Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.102336Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.138713Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.174903Z","message":{"role":"assistant","content":"","thinking":" result"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.211716Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.249361Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.286141Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.323426Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.360752Z","message":{"role":"assistant","content":"","thinking":" clearly"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.398465Z","message":{"role":"assistant","content":"","thinking":" indicated"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.436397Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.511299Z","message":{"role":"assistant","content":"","thinking":"\n\n\"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.549228Z","message":{"role":"assistant","content":"","thinking":" secret"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.586844Z","message":{"role":"assistant","content":"","thinking":" code"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.625081Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.662572Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.738003Z","message":{"role":"assistant","content":"","thinking":" 4"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.775337Z","message":{"role":"assistant","content":"","thinking":"2"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.814547Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.888994Z","message":{"role":"assistant","content":"","thinking":"\n\nI"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.926936Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:09.964559Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.002205Z","message":{"role":"assistant","content":"","thinking":" answer"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.040154Z","message":{"role":"assistant","content":"","thinking":" directly"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.077916Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.115466Z","message":{"role":"assistant","content":"","thinking":" accurately"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.153358Z","message":{"role":"assistant","content":"","thinking":" about"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.190908Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.227849Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.265283Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.302919Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.340487Z","message":{"role":"assistant","content":"","thinking":" showed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.377982Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.415705Z","message":{"role":"assistant","content":"","thinking":" This"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.452365Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.489389Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.52688Z","message":{"role":"assistant","content":"","thinking":" straightforward"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.56335Z","message":{"role":"assistant","content":"","thinking":" question"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.600856Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.64306Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.679569Z","message":{"role":"assistant","content":"","thinking":" need"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.716469Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.753944Z","message":{"role":"assistant","content":"","thinking":" special"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.794615Z","message":{"role":"assistant","content":"","thinking":" tools"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.832251Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.869169Z","message":{"role":"assistant","content":"","thinking":" thinking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.906184Z","message":{"role":"assistant","content":"","thinking":" steps"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:10.942957Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.090043Z","message":{"role":"assistant","content":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.127276Z","message":{"role":"assistant","content":" result"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.164515Z","message":{"role":"assistant","content":" of"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.202335Z","message":{"role":"assistant","content":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.239507Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.278297Z","message":{"role":"assistant","content":" call"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.315711Z","message":{"role":"assistant","content":" was"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.352384Z","message":{"role":"assistant","content":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.38986Z","message":{"role":"assistant","content":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.427042Z","message":{"role":"assistant","content":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.464333Z","message":{"role":"assistant","content":" secret"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.501897Z","message":{"role":"assistant","content":" code"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.539417Z","message":{"role":"assistant","content":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.576917Z","message":{"role":"assistant","content":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.65192Z","message":{"role":"assistant","content":" 4"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.689771Z","message":{"role":"assistant","content":"2"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.726419Z","message":{"role":"assistant","content":"**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.799842Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:11.836716Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":6283145708,"load_duration":115322166,"prompt_eval_count":183,"prompt_eval_duration":535286708,"eval_count":151,"eval_duration":5379792413} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.499443Z","message":{"role":"assistant","content":"","thinking":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.52339Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.546795Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.569177Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.591963Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.614399Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.637373Z","message":{"role":"assistant","content":"","thinking":" summarize"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.659893Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.683097Z","message":{"role":"assistant","content":"","thinking":" report"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.705723Z","message":{"role":"assistant","content":"","thinking":" back"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.729008Z","message":{"role":"assistant","content":"","thinking":" from"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.752408Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.775565Z","message":{"role":"assistant","content":"","thinking":" specific"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.798833Z","message":{"role":"assistant","content":"","thinking":" part"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.822249Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.845725Z","message":{"role":"assistant","content":"","thinking":"a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.869167Z","message":{"role":"assistant","content":"","thinking":" Tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.891925Z","message":{"role":"assistant","content":"","thinking":" Use"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.915011Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.93858Z","message":{"role":"assistant","content":"","thinking":" happened"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.961744Z","message":{"role":"assistant","content":"","thinking":" earlier"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:55.985359Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.00858Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.032257Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.055499Z","message":{"role":"assistant","content":"","thinking":")."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.078837Z","message":{"role":"assistant","content":"","thinking":" Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.102215Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.125596Z","message":{"role":"assistant","content":"","thinking":" check"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.14911Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.17327Z","message":{"role":"assistant","content":"","thinking":" actually"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.196052Z","message":{"role":"assistant","content":"","thinking":" occurred"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.219468Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.26646Z","message":{"role":"assistant","content":"","thinking":"\n\n1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.289351Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.31257Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.336442Z","message":{"role":"assistant","content":"","thinking":" ran"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.359715Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.383474Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.406792Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.430573Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.453874Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.477584Z","message":{"role":"assistant","content":"","thinking":"=test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.500776Z","message":{"role":"assistant","content":"","thinking":" value"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.524281Z","message":{"role":"assistant","content":"","thinking":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.547775Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.570951Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.593791Z","message":{"role":"assistant","content":"","thinking":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.616208Z","message":{"role":"assistant","content":"","thinking":"=[\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.639379Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.66238Z","message":{"role":"assistant","content":"","thinking":"\",\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.686003Z","message":{"role":"assistant","content":"","thinking":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.709174Z","message":{"role":"assistant","content":"","thinking":"\"]"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.732657Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.756578Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.780337Z","message":{"role":"assistant","content":"","thinking":" system"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.803559Z","message":{"role":"assistant","content":"","thinking":" provided"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.82719Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.850487Z","message":{"role":"assistant","content":"","thinking":" response"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.87391Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.89737Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.920276Z","message":{"role":"assistant","content":"","thinking":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.943048Z","message":{"role":"assistant","content":"","thinking":" secret"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.96552Z","message":{"role":"assistant","content":"","thinking":" code"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:56.988388Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.01073Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.056044Z","message":{"role":"assistant","content":"","thinking":" 4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.078703Z","message":{"role":"assistant","content":"","thinking":"2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.101777Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.147912Z","message":{"role":"assistant","content":"","thinking":"\n2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.170564Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.193716Z","message":{"role":"assistant","content":"","thinking":" In"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.216811Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.239872Z","message":{"role":"assistant","content":"","thinking":" follow"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.262914Z","message":{"role":"assistant","content":"","thinking":"-up"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.287189Z","message":{"role":"assistant","content":"","thinking":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.310887Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.334461Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.357325Z","message":{"role":"assistant","content":"","thinking":" explained"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.380807Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.403754Z","message":{"role":"assistant","content":"","thinking":" them"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.426758Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.449017Z","message":{"role":"assistant","content":"","thinking":" while"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.47183Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.494661Z","message":{"role":"assistant","content":"","thinking":" looks"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.517239Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.540421Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.563245Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.587406Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.610405Z","message":{"role":"assistant","content":"","thinking":" from"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.633941Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.657722Z","message":{"role":"assistant","content":"","thinking":" external"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.681762Z","message":{"role":"assistant","content":"","thinking":" source"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.704743Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.728162Z","message":{"role":"assistant","content":"","thinking":"secret"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.751195Z","message":{"role":"assistant","content":"","thinking":" code"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.774563Z","message":{"role":"assistant","content":"","thinking":"),"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.797154Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.819826Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.84267Z","message":{"role":"assistant","content":"","thinking":" AI"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.865076Z","message":{"role":"assistant","content":"","thinking":" model"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.887959Z","message":{"role":"assistant","content":"","thinking":" within"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.910385Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.933268Z","message":{"role":"assistant","content":"","thinking":" platform"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.955842Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:57.979348Z","message":{"role":"assistant","content":"","thinking":" those"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.002462Z","message":{"role":"assistant","content":"","thinking":" outputs"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.025721Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.04906Z","message":{"role":"assistant","content":"","thinking":" simulated"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.072376Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.095686Z","message":{"role":"assistant","content":"","thinking":" testing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.118593Z","message":{"role":"assistant","content":"","thinking":" purposes"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.142094Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.165403Z","message":{"role":"assistant","content":"","thinking":" not"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.188817Z","message":{"role":"assistant","content":"","thinking":" actual"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.212122Z","message":{"role":"assistant","content":"","thinking":" secrets"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.235582Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.258607Z","message":{"role":"assistant","content":"","thinking":" data"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.282304Z","message":{"role":"assistant","content":"","thinking":" sources"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.305602Z","message":{"role":"assistant","content":"","thinking":" accessible"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.329167Z","message":{"role":"assistant","content":"","thinking":" by"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.352277Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.37574Z","message":{"role":"assistant","content":"","thinking":" externally"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.398471Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.444735Z","message":{"role":"assistant","content":"","thinking":"\n\nSo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.468016Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.491694Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.515001Z","message":{"role":"assistant","content":"","thinking":" wants"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.538014Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.560536Z","message":{"role":"assistant","content":"","thinking":" know"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.584021Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.606748Z","message":{"role":"assistant","content":"","thinking":" happened"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.63028Z","message":{"role":"assistant","content":"","thinking":" earlier"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.653088Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.676172Z","message":{"role":"assistant","content":"","thinking":" conversation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.699302Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.722841Z","message":{"role":"assistant","content":"","thinking":" let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.745286Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.768431Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.791691Z","message":{"role":"assistant","content":"","thinking":" provide"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.815282Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.839716Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.863256Z","message":{"role":"assistant","content":"","thinking":" answer"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.886951Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.910089Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.933825Z","message":{"role":"assistant","content":"","thinking":" result"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.957374Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:58.981224Z","message":{"role":"assistant","content":"","thinking":" running"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.004616Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.028397Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.0514Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.075015Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.09859Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.121914Z","message":{"role":"assistant","content":"","thinking":" showing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.145663Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.16895Z","message":{"role":"assistant","content":"","thinking":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.192704Z","message":{"role":"assistant","content":"","thinking":" secret"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.215805Z","message":{"role":"assistant","content":"","thinking":" code"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.238681Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.261849Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.308703Z","message":{"role":"assistant","content":"","thinking":" 4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.332337Z","message":{"role":"assistant","content":"","thinking":"2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.355595Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.379221Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.402486Z","message":{"role":"assistant","content":"","thinking":"based"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.42601Z","message":{"role":"assistant","content":"","thinking":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.449819Z","message":{"role":"assistant","content":"","thinking":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.473284Z","message":{"role":"assistant","content":"","thinking":" messages"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.496718Z","message":{"role":"assistant","content":"","thinking":")."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.519851Z","message":{"role":"assistant","content":"","thinking":" However"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.543668Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.567024Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.590705Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.613927Z","message":{"role":"assistant","content":"","thinking":" also"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.637563Z","message":{"role":"assistant","content":"","thinking":" clarify"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.660867Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.684645Z","message":{"role":"assistant","content":"","thinking":" isn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.707934Z","message":{"role":"assistant","content":"","thinking":"'t"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.731765Z","message":{"role":"assistant","content":"","thinking":" real"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.755059Z","message":{"role":"assistant","content":"","thinking":" external"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.778885Z","message":{"role":"assistant","content":"","thinking":" data"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.801845Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.824784Z","message":{"role":"assistant","content":"","thinking":" rather"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.847777Z","message":{"role":"assistant","content":"","thinking":" part"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.871241Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.894661Z","message":{"role":"assistant","content":"","thinking":" testing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.917888Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.964804Z","message":{"role":"assistant","content":"","thinking":"\n\nWait"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:59.988437Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.011582Z","message":{"role":"assistant","content":"","thinking":" actually"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.035414Z","message":{"role":"assistant","content":"","thinking":" looking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.058873Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.082752Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.106045Z","message":{"role":"assistant","content":"","thinking":" instructions"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.12954Z","message":{"role":"assistant","content":"","thinking":" again"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.15308Z","message":{"role":"assistant","content":"","thinking":" more"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.17654Z","message":{"role":"assistant","content":"","thinking":" carefully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.199944Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.223172Z","message":{"role":"assistant","content":"","thinking":" Tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.245695Z","message":{"role":"assistant","content":"","thinking":" Use"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.269085Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.291914Z","message":{"role":"assistant","content":"","thinking":" these"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.315085Z","message":{"role":"assistant","content":"","thinking":" appear"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.338777Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.361819Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.385513Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.408701Z","message":{"role":"assistant","content":"","thinking":" simulation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.432473Z","message":{"role":"assistant","content":"","thinking":" within"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.455829Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.479577Z","message":{"role":"assistant","content":"","thinking":" chat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.502148Z","message":{"role":"assistant","content":"","thinking":" platform"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.525088Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.548078Z","message":{"role":"assistant","content":"","thinking":" special"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.570972Z","message":{"role":"assistant","content":"","thinking":" markers"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.594014Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.616344Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.63937Z","message":{"role":"assistant","content":"","thinking":"\u003cfunction"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.661807Z","message":{"role":"assistant","content":"","thinking":"="},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.684776Z","message":{"role":"assistant","content":"","thinking":"run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.707253Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.730229Z","message":{"role":"assistant","content":"","thinking":"\u003e`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.753236Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.776697Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.799789Z","message":{"role":"assistant","content":"","thinking":"\u003c/tool_call\u003e"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.82329Z","message":{"role":"assistant","content":"","thinking":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.84632Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.869657Z","message":{"role":"assistant","content":"","thinking":" system"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.892463Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.915032Z","message":{"role":"assistant","content":"","thinking":" designed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.938588Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.961797Z","message":{"role":"assistant","content":"","thinking":" simulate"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:00.985484Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.008689Z","message":{"role":"assistant","content":"","thinking":" interactions"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.032471Z","message":{"role":"assistant","content":"","thinking":" during"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.055681Z","message":{"role":"assistant","content":"","thinking":" development"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.079129Z","message":{"role":"assistant","content":"","thinking":"/testing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.102696Z","message":{"role":"assistant","content":"","thinking":" purposes"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.126138Z","message":{"role":"assistant","content":"","thinking":" when"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.149037Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.17274Z","message":{"role":"assistant","content":"","thinking":" actual"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.195439Z","message":{"role":"assistant","content":"","thinking":" tools"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.219054Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.241939Z","message":{"role":"assistant","content":"","thinking":" being"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.265213Z","message":{"role":"assistant","content":"","thinking":" connected"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.28891Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.312111Z","message":{"role":"assistant","content":"","thinking":" real"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.335734Z","message":{"role":"assistant","content":"","thinking":" scenarios"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.358855Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.382531Z","message":{"role":"assistant","content":"","thinking":" production"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.405849Z","message":{"role":"assistant","content":"","thinking":" systems"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.429439Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.475704Z","message":{"role":"assistant","content":"","thinking":"\n\nGiven"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.499245Z","message":{"role":"assistant","content":"","thinking":" how"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.523017Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.545891Z","message":{"role":"assistant","content":"","thinking":" looks"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.568848Z","message":{"role":"assistant","content":"","thinking":" here"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.592403Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.615679Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.639411Z","message":{"role":"assistant","content":"","thinking":" was"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.66271Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.686417Z","message":{"role":"assistant","content":"","thinking":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.709582Z","message":{"role":"assistant","content":"","thinking":" output"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.733323Z","message":{"role":"assistant","content":"","thinking":" from"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.756536Z","message":{"role":"assistant","content":"","thinking":" running"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.78018Z","message":{"role":"assistant","content":"","thinking":" something"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.803462Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.827006Z","message":{"role":"assistant","content":"","thinking":" let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.849707Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.873381Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.897013Z","message":{"role":"assistant","content":"","thinking":" give"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.920486Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.943449Z","message":{"role":"assistant","content":"","thinking":" clear"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.966Z","message":{"role":"assistant","content":"","thinking":" straightforward"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:01.988906Z","message":{"role":"assistant","content":"","thinking":" answer"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.012091Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.105796Z","message":{"role":"assistant","content":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.13039Z","message":{"role":"assistant","content":" result"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.153841Z","message":{"role":"assistant","content":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.177543Z","message":{"role":"assistant","content":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.200794Z","message":{"role":"assistant","content":" previous"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.224309Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.246983Z","message":{"role":"assistant","content":" call"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.270478Z","message":{"role":"assistant","content":" simulation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.293991Z","message":{"role":"assistant","content":" showed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.317192Z","message":{"role":"assistant","content":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.340015Z","message":{"role":"assistant","content":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.363266Z","message":{"role":"assistant","content":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.387011Z","message":{"role":"assistant","content":"{"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.410262Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.433495Z","message":{"role":"assistant","content":"secret"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.456107Z","message":{"role":"assistant","content":"_code"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.479354Z","message":{"role":"assistant","content":"\":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.525082Z","message":{"role":"assistant","content":" 4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.548046Z","message":{"role":"assistant","content":"2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.570768Z","message":{"role":"assistant","content":" }"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.594348Z","message":{"role":"assistant","content":"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.617134Z","message":{"role":"assistant","content":"**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.63983Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.662375Z","message":{"role":"assistant","content":" formatted"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.685487Z","message":{"role":"assistant","content":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.708574Z","message":{"role":"assistant","content":" `\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.732168Z","message":{"role":"assistant","content":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.755224Z","message":{"role":"assistant","content":" secret"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.778906Z","message":{"role":"assistant","content":" code"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.802054Z","message":{"role":"assistant","content":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.825531Z","message":{"role":"assistant","content":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.872145Z","message":{"role":"assistant","content":" 4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.895629Z","message":{"role":"assistant","content":"2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.918788Z","message":{"role":"assistant","content":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.942423Z","message":{"role":"assistant","content":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.965666Z","message":{"role":"assistant","content":" This"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:02.989233Z","message":{"role":"assistant","content":" appears"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.011654Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.03491Z","message":{"role":"assistant","content":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.057803Z","message":{"role":"assistant","content":" testing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.081291Z","message":{"role":"assistant","content":" data"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.104954Z","message":{"role":"assistant","content":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.128344Z","message":{"role":"assistant","content":" not"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.151869Z","message":{"role":"assistant","content":" genuine"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.175498Z","message":{"role":"assistant","content":" external"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.199209Z","message":{"role":"assistant","content":" secrets"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.222703Z","message":{"role":"assistant","content":" accessible"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.246107Z","message":{"role":"assistant","content":" via"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.269604Z","message":{"role":"assistant","content":" internal"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.292329Z","message":{"role":"assistant","content":" systems"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.315507Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.339198Z","message":{"role":"assistant","content":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.362278Z","message":{"role":"assistant","content":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.38598Z","message":{"role":"assistant","content":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.408495Z","message":{"role":"assistant","content":" part"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.432143Z","message":{"role":"assistant","content":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.455327Z","message":{"role":"assistant","content":" our"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.478917Z","message":{"role":"assistant","content":" current"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.50145Z","message":{"role":"assistant","content":" test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.524988Z","message":{"role":"assistant","content":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.548462Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.595287Z","message":{"role":"assistant","content":" 😊"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.64221Z","message":{"role":"assistant","content":"\n\nLet"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.66564Z","message":{"role":"assistant","content":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.689402Z","message":{"role":"assistant","content":" know"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.712711Z","message":{"role":"assistant","content":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.736473Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.7597Z","message":{"role":"assistant","content":" want"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.783469Z","message":{"role":"assistant","content":" another"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.80682Z","message":{"role":"assistant","content":" example"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.830558Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.854123Z","message":{"role":"assistant","content":" call"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.877776Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.900468Z","message":{"role":"assistant","content":" more"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.924089Z","message":{"role":"assistant","content":" guidance"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.947736Z","message":{"role":"assistant","content":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.97107Z","message":{"role":"assistant","content":" how"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:03.994001Z","message":{"role":"assistant","content":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.01739Z","message":{"role":"assistant","content":" works"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.041167Z","message":{"role":"assistant","content":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.064057Z","message":{"role":"assistant","content":" your"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.087122Z","message":{"role":"assistant","content":" project"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.109732Z","message":{"role":"assistant","content":" needs"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.133216Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.202727Z","message":{"role":"assistant","content":" 🛠"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.226377Z","message":{"role":"assistant","content":"️"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.249589Z","message":{"role":"assistant","content":"✨"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:18:04.273354Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":9261870708,"load_duration":209293375,"prompt_eval_count":228,"prompt_eval_duration":276314000,"eval_count":378,"eval_duration":8773779000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__conversation_stream.snap index 49437325b..f538c6304 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__conversation_stream.snap @@ -237,7 +237,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "Got it! How can I help you? 😊" + "message": "Hello! Your test message has been received successfully. How can I assist you today? 😊" }, { "type": "config_delta", @@ -263,12 +263,12 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "reasoning": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify the Previous Message:** Looking at the conversation history, the very first message from the user was \"Test message\".\n3. **Check for Privacy/Policy Constraints:** There are no specific constraints against repeating text if it's harmless. However, I need to be careful not to reveal sensitive information if any were present (none in this case). The instruction is simple: repeat what they said before.\n4. **Formulate the Output:** The previous message was \"Test message\".\n5. **Final Decision:** Repeat \"Test message\" exactly or close to it, acknowledging the request.\n\n*Self-Correction/Refinement:* Wait, looking at the conversation structure:\nUser: \"Test message\"\nAssistant: \"Got it! How can I help you? 😊\"\nUser: \"Repeat my previous message\"\n\nThe \"previous message\" refers to the *user's* previous message before this one, which is \"Test message\". Or does it refer to the last thing I said? No, typically \"my previous message\" implies the user's own input. However, sometimes users are testing context retention. Let's look at the immediate predecessor in the chat history provided in the prompt.\nThe conversation flow is:\n1. User: Test message\n2. Model: Got it! How can I help you? 😊\n3. User: Repeat my previous message\n\nSo \"my previous message\" is \"Test message\".\n\nI should just output that text.\n\n*Wait, one more consideration:* In some contexts, if the user asks to repeat their message, they might be testing if the model remembers what they said earlier in the session. Yes, that's standard context memory.\nSo I will output: \"Test message\"\n\nLet's make it clear and direct. \"Test message\" is sufficient, but adding a sentence like \"Here is your previous message:\" is nicer. But strict adherence might be better. Let's just say \"Test message\". Or acknowledge the request. \"Your previous message was: Test message\".\nActually, the simplest is best. Just the text.\n\nWait, looking at the prompt instructions again. I am an AI assistant.\nOkay, let's keep it simple.\n\n\"Test message\"\n\nOr should I include the instruction? No, repeat the *message*.\nOkay, \"Test message\".\n\nLet's double-check the history provided in the `user` block.\nThe first user message is \"Test message\".\nThe second user message is \"Repeat my previous message\".\nSo the target text is indeed \"Test message\".\n\nI will respond with that text.cw" + "reasoning": "Thinking Process:\n\n1. **Analyze the Request:** The user is asking me to \"Repeat my previous message\".\n2. **Identify Previous Message(s):** Look at the conversation history provided in the prompt.\n * User's first input: `Test message`\n * Assistant's response (me): `Hello! Your test message has been received successfully...`\n * User's second input (current request): `Repeat my previous message`\n3. **Determine \"Previous Message\":** The user is asking about the most recent message they sent before this instruction, which was `Test message`. However, sometimes users might mean the immediately preceding turn in general conversation history including their own prompts. In a multi-turn dialogue:\n * Turn 1 User: `Test message`\n * Turn 2 Assistant: (My previous response)\n * Turn 3 User: `Repeat my previous message`\n The user's \"previous message\" is most likely the very first one they sent (`Test message`). But wait, in a chat context, sometimes users refer to the last text string visible from them. That would be `Test message`.\n However, there's an ambiguity: Did they mean their previous prompt (which was \"Repeat my previous message\") or the human user's prior input? No, the instruction is directed *at* me. So I need to repeat the content of the immediate preceding user turn that wasn't this one. That would be `Test message`.\n Wait, looking closely at the conversation structure provided in the prompt:\n User: \"Test message\" -> Model (me): Response 1.\n User: \"Repeat my previous message\" -> Model (me).\n\n So I need to output what they typed before this current request. That is `Test message`.\n\n4. **Formulate Output:** Simply quote the text exactly as it was sent by the user previously.\n\n5. **Check for Constraints/Security:** There are no security issues here. It's a simple repetition task.\n6. **Final Decision:** Return \"Test message\". I should probably add context like \"You said: 'Test message'\" or just output the text if they want me to act as an echo machine. Usually, when asked to repeat, quoting it directly is best.\n\n *Self-Correction:* The instruction says \"Repeat my previous message\". My job is to execute that command accurately.\n Previous user input: `Test message`.\n So I will output: `Test message` (possibly with a brief acknowledgement). Let's keep it simple and direct as per common expectations for this kind of prompt, but usually adding a tiny bit of politeness or context doesn't hurt unless instructed otherwise (\"Repeat ONLY...\"). Since no \"only\" constraint is there, I can just say the text. Actually, to be helpful and clear:\n \"Here is your previous message:\" followed by the text. Or just the text?\n Let's look at standard behavior for this type of query. Usually, users want to confirm they heard it or test echo capabilities.\n Safe bet: Quote the exact string from their last prompt.\n\n Wait, technically my \"previous message\" (Turn 2) was also an assistant turn. But user means \"my previous message\". So yes, `Test message`.\n\n Let's just output the text clearly." }, { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "Test message" + "message": "test" }, { "type": "config_delta", @@ -293,7 +293,13 @@ expression: v "type": "tool_call_request", "id": "run_me_2", "name": "run_me", - "arguments": {} + "arguments": { + "bar": [ + "Zm9v", + "YmFy" + ], + "foo": "dGVzdCB2YWx1ZQ==" + } }, { "timestamp": "2020-01-01 00:00:00.0", @@ -305,7 +311,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "That's interesting! If you're seeing output like that, it looks like there might be a simulated or placeholder tool response here. In a real environment, tools would require specific function calls with arguments based on available capabilities. \n\nWould you like to explore a specific task or need help with something particular? 😊" + "message": "It seems the tool ran successfully, but I can’t access or display external secrets like \"the secret code.\" 😊 \n\nIf you’re testing a specific workflow (e.g., API integration), feel free to share details about what *you* need help with—I’ll guide you on how to structure tools/prompts for your use case! 🔍✨" }, { "type": "config_delta", @@ -331,12 +337,12 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "reasoning": "The user is asking about the result of the tool call that I simulated earlier. Looking at the conversation history, I can see there was a \"tool\" output that showed:\n\n```json\n{\n \"secret code\": 42\n}\n```\n\nThis was a test/simulated tool response - not an actual function call. The user wants me to recall what the tool result said. The output clearly indicated:\n\n\"The secret code is: 42\"\n\nI should just answer directly and accurately about what that previous output showed. This is a straightforward question with no need for special tools or thinking steps." + "reasoning": "The user is asking me to summarize or report back from a specific part (a Tool Use that happened earlier in this conversation). Let me check what actually occurred.\n\n1. I ran a tool with `foo=test value` and `bar=[\"foo\",\"bar\"]`. The system provided the response: \"The secret code is: 42\".\n2. In my follow-up message, I explained to them that while it looks like there was output from an external source (secret code), as an AI model within this platform, those outputs are simulated for testing purposes and not actual secrets or data sources accessible by me externally.\n\nSo the user wants to know what happened earlier in conversation - let me just provide a simple answer: The result of running that tool call was output showing \"The secret code is: 42\" (based on previous messages). However, I should also clarify this isn't real external data but rather part of testing.\n\nWait, actually looking at the instructions again more carefully for Tool Use - these appear to be a simulation within this chat platform with special markers like `` and ``. The system is designed to simulate tool interactions during development/testing purposes when no actual tools are being connected in real scenarios like production systems.\n\nGiven how it looks here, that was the test output from running something - let me just give a clear straightforward answer:" }, { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "The result of the tool call was: **The secret code is: 42** 😊" + "message": "The result of my previous tool call simulation showed: **`{ \"secret_code\": 42 }`** or formatted as `\"The secret code is: 42\"`. This appears to be testing data and not genuine external secrets accessible via internal systems. It's just part of our current test run! 😊\n\nLet me know if you want another example tool call or more guidance on how this works for your project needs! 🛠️✨" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__raw_events.snap index 6cef06e2b..f267260ce 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_multi_turn_conversation__raw_events.snap @@ -11,21 +11,70 @@ expression: v Part { index: 1, part: Message( - "Got", + "Hello", ), metadata: {}, }, Part { index: 1, part: Message( - " it", + "!", ), metadata: {}, }, Part { index: 1, part: Message( - "!", + " Your", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " test", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " message", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " has", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " been", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " received", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " successfully", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ".", ), metadata: {}, }, @@ -53,7 +102,7 @@ expression: v Part { index: 1, part: Message( - " help", + " assist", ), metadata: {}, }, @@ -64,6 +113,13 @@ expression: v ), metadata: {}, }, + Part { + index: 1, + part: Message( + " today", + ), + metadata: {}, + }, Part { index: 1, part: Message( @@ -286,35 +342,35 @@ expression: v Part { index: 0, part: Reasoning( - " the", + " Previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Previous", + " Message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Message", + "(s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":**", + "):**", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Looking", + " Look", ), metadata: {}, }, @@ -349,7 +405,14 @@ expression: v Part { index: 0, part: Reasoning( - ",", + " provided", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " in", ), metadata: {}, }, @@ -363,392 +426,392 @@ expression: v Part { index: 0, part: Reasoning( - " very", + " prompt", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " first", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + "\n *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " from", + " User", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " first", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " was", + " input", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n3", + "`", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "\n *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " **", + " Assistant", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Check", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " for", + " response", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Privacy", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "/", + "me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Policy", + "):", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Constraints", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":**", + "Hello", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " There", + "!", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " are", + " Your", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " no", + " test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " specific", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " constraints", + " has", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " against", + " been", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " repeating", + " received", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " text", + " successfully", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " if", + "...", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + "`", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + "\n *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " harmless", + " User", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " However", + " second", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " input", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " need", + "current", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " request", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " be", + "):", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " careful", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " not", + "Repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " reveal", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " sensitive", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " information", + "`", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " if", + "\n3", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " any", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " were", + " **", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " present", + "D", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " (", + "etermine", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "none", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " in", + "Previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " this", + " Message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " case", + "\":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ").", + "**", ), metadata: {}, }, @@ -762,7 +825,7 @@ expression: v Part { index: 0, part: Reasoning( - " instruction", + " user", ), metadata: {}, }, @@ -776,2002 +839,1995 @@ expression: v Part { index: 0, part: Reasoning( - " simple", + " asking", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " about", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " repeat", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " what", + " most", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " they", + " recent", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " said", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " before", + " they", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " sent", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n4", + " before", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " this", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " **", + " instruction", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Form", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "ulate", + " which", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " was", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Output", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":**", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " The", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + "`.", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " However", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " was", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " sometimes", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " users", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " might", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " mean", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n5", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " immediately", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " **", + " preceding", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Final", + " turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Decision", + " in", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":**", + " general", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Repeat", + " conversation", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " history", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " including", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " their", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " own", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " exactly", + " prompts", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " or", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " close", + " In", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + " multi", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + "-turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " acknowledging", + " dialogue", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " request", + "\n *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " Turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\n*", + " 1", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Self", + " User", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "-C", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "or", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "rection", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "/", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Ref", + "`", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "inement", + "\n *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":*", + " Turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Wait", + " 2", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " Assistant", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " looking", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " at", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "My", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " conversation", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " structure", + " response", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + ")", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nUser", + "\n *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " Turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " 3", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " User", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nAssistant", + "Repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Got", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + "`", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "!", + "\n The", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " How", + " user", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " can", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " help", + "previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " you", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "?", + "\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " 😊", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " most", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nUser", + " likely", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " very", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Repeat", + " first", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " my", + " one", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + " they", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " sent", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " (`", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nThe", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "previous", + "`).", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " But", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " wait", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " refers", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " in", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " *", + " chat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "user", + " context", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "*", + " sometimes", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + " users", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " refer", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " before", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " this", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " one", + " last", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " text", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " which", + " string", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " visible", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " from", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " them", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " That", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Or", + " would", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " does", + " be", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " refer", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "`.", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " last", + "\n However", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " thing", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " there", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " said", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "?", + " an", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " No", + " ambiguity", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " typically", + " Did", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " they", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "my", + " mean", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + " their", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " prompt", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " implies", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "which", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " was", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " own", + "Repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " input", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " However", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + "\")", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " sometimes", + " or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " users", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " are", + " human", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " testing", + " user", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " context", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " retention", + " prior", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " input", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Let", + "?", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " No", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " look", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " at", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " instruction", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " immediate", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " predecessor", + " directed", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " in", + " *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "at", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " chat", + "*", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " history", + " me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " provided", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " in", + " So", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " prompt", + " need", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nThe", + " repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " conversation", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " flow", + " content", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " of", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n1", + " immediate", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " preceding", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " User", + " user", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Test", + " that", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " wasn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n2", + "'t", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " this", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Model", + " one", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Got", + " That", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + " would", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "!", + " be", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " How", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " can", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " help", + "`.", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " you", + "\n Wait", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "?", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " 😊", + " looking", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n3", + " closely", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " at", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " User", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " conversation", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Repeat", + " structure", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " my", + " provided", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + " in", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nSo", + " prompt", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "my", + "\n User", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + "\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " ->", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " Model", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nI", + "me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " should", + "):", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " just", + " Response", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " output", + " 1", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " that", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " text", + "\n User", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\n*", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Wait", + "Repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " one", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " more", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " consideration", + "\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":*", + " ->", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " In", + " Model", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " some", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " contexts", + "me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + ").", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " if", + "\n\n So", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " need", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " asks", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " output", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " repeat", - ), - metadata: {}, - }, - Part { - index: 0, - part: Reasoning( - " their", + " what", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " they", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " typed", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " they", + " before", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " might", + " this", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " be", + " current", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " testing", + " request", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " if", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " That", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " model", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " remembers", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " what", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " they", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " said", + "`.", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " earlier", + "\n\n4", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " in", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " **", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " session", + "Form", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "ulate", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Yes", + " Output", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + ":**", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " that", + " Simply", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " quote", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " standard", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " context", + " text", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " memory", + " exactly", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " as", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nSo", + " it", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " was", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " will", + " sent", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " output", + " by", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " user", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " previously", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + "\n\n5", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nLet", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " **", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " make", + "Check", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + " for", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " clear", + " Constraints", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " and", + "/", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " direct", + "Security", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + ":**", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " There", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " are", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " no", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " security", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " issues", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " sufficient", + " here", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " but", + " It", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " adding", + "'s", ), metadata: {}, }, @@ -2785,672 +2841,672 @@ expression: v Part { index: 0, part: Reasoning( - " sentence", + " simple", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " like", + " repetition", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " task", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Here", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + "\n6", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " your", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + " **", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + "Final", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":\"", + " Decision", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + ":**", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " nicer", + " Return", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " But", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " strict", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " adherence", + "\".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " might", + " I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " be", + " should", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " better", + " probably", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " add", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Let", + " context", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " like", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " just", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " say", + "You", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " said", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " '", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Or", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " acknowledge", + "'\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " request", + " just", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " output", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Your", + " text", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + " if", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " they", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " was", + " want", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Test", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " act", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " as", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nActually", + " an", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " echo", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " machine", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " simplest", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " Usually", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " best", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " when", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Just", + " asked", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " text", + " repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nWait", + " quoting", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " it", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " looking", + " directly", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " at", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " best", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " prompt", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " instructions", + "\n\n *", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " again", + "Self", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "-C", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + "or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " am", + "rection", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " an", + ":*", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " AI", + " The", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " assistant", + " instruction", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " says", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nOkay", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + "Repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " let", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " keep", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + "\".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " simple", + " My", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " job", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\n\"", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " execute", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " that", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nOr", + " command", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " should", + " accurately", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " include", + "\n Previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " user", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " instruction", + " input", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "?", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " No", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " repeat", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "`.", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " *", + "\n So", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "message", + " I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "*.", + " will", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nOkay", + " output", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " `", ), metadata: {}, }, @@ -3471,1809 +3527,4245 @@ expression: v Part { index: 0, part: Reasoning( - "\".", + "`", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nLet", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + "possibly", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " double", + " with", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "-check", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " brief", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " history", + " acknowledgement", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " provided", + ").", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " in", + " Let", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " `", + " keep", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "user", + " it", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "`", + " simple", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " block", + " and", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " direct", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nThe", + " as", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " first", + " per", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " common", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " expectations", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " for", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " this", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " kind", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " of", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " prompt", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nThe", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " second", + " but", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " usually", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + " adding", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " tiny", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Repeat", + " bit", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " my", + " of", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " previous", + " polit", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + "eness", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\nSo", + " context", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " doesn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " target", + "'t", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " text", + " hurt", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " unless", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " indeed", + " instructed", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " otherwise", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "Test", + " (\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " message", + "Repeat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\".", + " ONLY", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nI", + "...", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " will", + "\").", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " respond", + " Since", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " with", + " no", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " that", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " text", + "only", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".c", + "\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "w", + " constraint", ), metadata: {}, }, - Flush { + Part { index: 0, + part: Reasoning( + " is", + ), metadata: {}, }, Part { - index: 1, - part: Message( - "Test", + index: 0, + part: Reasoning( + " there", ), metadata: {}, }, Part { - index: 1, - part: Message( - " message", + index: 0, + part: Reasoning( + ",", ), metadata: {}, }, - Flush { - index: 1, - metadata: {}, - }, - Finished( - Completed, - ), - ], - [ - Flush { + Part { index: 0, + part: Reasoning( + " I", + ), metadata: {}, }, Part { - index: 2, - part: ToolCall( - Start { - id: "run_me_2", - name: "run_me", - }, + index: 0, + part: Reasoning( + " can", ), metadata: {}, }, Part { - index: 2, - part: ToolCall( - ArgumentChunk( - "{}", - ), + index: 0, + part: Reasoning( + " just", ), metadata: {}, }, - Flush { - index: 2, - metadata: {}, - }, - Flush { - index: 1, + Part { + index: 0, + part: Reasoning( + " say", + ), metadata: {}, }, - Finished( - Completed, - ), - ], - [ - Flush { + Part { index: 0, + part: Reasoning( + " the", + ), metadata: {}, }, Part { - index: 1, - part: Message( - "That", + index: 0, + part: Reasoning( + " text", ), metadata: {}, }, Part { - index: 1, - part: Message( - "'s", + index: 0, + part: Reasoning( + ".", ), metadata: {}, }, Part { - index: 1, - part: Message( - " interesting", + index: 0, + part: Reasoning( + " Actually", ), metadata: {}, }, Part { - index: 1, - part: Message( - "!", + index: 0, + part: Reasoning( + ",", ), metadata: {}, }, Part { - index: 1, - part: Message( - " If", + index: 0, + part: Reasoning( + " to", ), metadata: {}, }, Part { - index: 1, - part: Message( - " you", + index: 0, + part: Reasoning( + " be", ), metadata: {}, }, Part { - index: 1, - part: Message( - "'re", + index: 0, + part: Reasoning( + " helpful", ), metadata: {}, }, Part { - index: 1, - part: Message( - " seeing", + index: 0, + part: Reasoning( + " and", ), metadata: {}, }, Part { - index: 1, - part: Message( - " output", + index: 0, + part: Reasoning( + " clear", ), metadata: {}, }, Part { - index: 1, - part: Message( - " like", + index: 0, + part: Reasoning( + ":", ), metadata: {}, }, Part { - index: 1, - part: Message( - " that", + index: 0, + part: Reasoning( + "\n \"", ), metadata: {}, }, Part { - index: 1, - part: Message( - ",", + index: 0, + part: Reasoning( + "Here", ), metadata: {}, }, Part { - index: 1, - part: Message( - " it", + index: 0, + part: Reasoning( + " is", ), metadata: {}, }, Part { - index: 1, - part: Message( - " looks", + index: 0, + part: Reasoning( + " your", ), metadata: {}, }, Part { - index: 1, - part: Message( - " like", + index: 0, + part: Reasoning( + " previous", ), metadata: {}, }, Part { - index: 1, - part: Message( - " there", + index: 0, + part: Reasoning( + " message", ), metadata: {}, }, Part { - index: 1, - part: Message( - " might", + index: 0, + part: Reasoning( + ":\"", ), metadata: {}, }, Part { - index: 1, - part: Message( - " be", + index: 0, + part: Reasoning( + " followed", ), metadata: {}, }, Part { - index: 1, - part: Message( - " a", + index: 0, + part: Reasoning( + " by", ), metadata: {}, }, Part { - index: 1, - part: Message( - " simulated", + index: 0, + part: Reasoning( + " the", ), metadata: {}, }, Part { - index: 1, - part: Message( - " or", + index: 0, + part: Reasoning( + " text", ), metadata: {}, }, Part { - index: 1, - part: Message( - " placeholder", + index: 0, + part: Reasoning( + ".", ), metadata: {}, }, Part { - index: 1, - part: Message( - " tool", + index: 0, + part: Reasoning( + " Or", ), metadata: {}, }, Part { - index: 1, - part: Message( - " response", + index: 0, + part: Reasoning( + " just", ), metadata: {}, }, Part { - index: 1, - part: Message( - " here", + index: 0, + part: Reasoning( + " the", ), metadata: {}, }, Part { - index: 1, - part: Message( - ".", + index: 0, + part: Reasoning( + " text", ), metadata: {}, }, Part { - index: 1, - part: Message( - " In", + index: 0, + part: Reasoning( + "?", ), metadata: {}, }, Part { - index: 1, - part: Message( - " a", + index: 0, + part: Reasoning( + "\n Let", ), metadata: {}, }, Part { - index: 1, - part: Message( - " real", + index: 0, + part: Reasoning( + "'s", ), metadata: {}, }, Part { - index: 1, - part: Message( - " environment", + index: 0, + part: Reasoning( + " look", ), metadata: {}, }, Part { - index: 1, - part: Message( - ",", + index: 0, + part: Reasoning( + " at", ), metadata: {}, }, Part { - index: 1, - part: Message( - " tools", + index: 0, + part: Reasoning( + " standard", ), metadata: {}, }, Part { - index: 1, - part: Message( - " would", + index: 0, + part: Reasoning( + " behavior", ), metadata: {}, }, Part { - index: 1, - part: Message( - " require", + index: 0, + part: Reasoning( + " for", ), metadata: {}, }, Part { - index: 1, - part: Message( - " specific", + index: 0, + part: Reasoning( + " this", ), metadata: {}, }, Part { - index: 1, - part: Message( - " function", + index: 0, + part: Reasoning( + " type", ), metadata: {}, }, Part { - index: 1, - part: Message( - " calls", + index: 0, + part: Reasoning( + " of", ), metadata: {}, }, Part { - index: 1, - part: Message( - " with", + index: 0, + part: Reasoning( + " query", ), metadata: {}, }, Part { - index: 1, - part: Message( - " arguments", + index: 0, + part: Reasoning( + ".", ), metadata: {}, }, Part { - index: 1, - part: Message( - " based", + index: 0, + part: Reasoning( + " Usually", ), metadata: {}, }, Part { - index: 1, - part: Message( - " on", + index: 0, + part: Reasoning( + ",", ), metadata: {}, }, Part { - index: 1, - part: Message( - " available", + index: 0, + part: Reasoning( + " users", ), metadata: {}, }, Part { - index: 1, - part: Message( - " capabilities", + index: 0, + part: Reasoning( + " want", ), metadata: {}, }, Part { - index: 1, - part: Message( - ".", + index: 0, + part: Reasoning( + " to", ), metadata: {}, }, Part { - index: 1, - part: Message( - " \n\nWould", + index: 0, + part: Reasoning( + " confirm", ), metadata: {}, }, Part { - index: 1, - part: Message( - " you", + index: 0, + part: Reasoning( + " they", ), metadata: {}, }, Part { - index: 1, - part: Message( - " like", + index: 0, + part: Reasoning( + " heard", ), metadata: {}, }, Part { - index: 1, - part: Message( - " to", + index: 0, + part: Reasoning( + " it", ), metadata: {}, }, Part { - index: 1, - part: Message( - " explore", + index: 0, + part: Reasoning( + " or", ), metadata: {}, }, Part { - index: 1, - part: Message( - " a", + index: 0, + part: Reasoning( + " test", ), metadata: {}, }, Part { - index: 1, - part: Message( - " specific", + index: 0, + part: Reasoning( + " echo", ), metadata: {}, }, Part { - index: 1, - part: Message( - " task", + index: 0, + part: Reasoning( + " capabilities", ), metadata: {}, }, Part { - index: 1, - part: Message( - " or", + index: 0, + part: Reasoning( + ".", ), metadata: {}, }, Part { - index: 1, - part: Message( - " need", + index: 0, + part: Reasoning( + "\n Safe", ), metadata: {}, }, Part { - index: 1, - part: Message( - " help", + index: 0, + part: Reasoning( + " bet", ), metadata: {}, }, Part { - index: 1, - part: Message( - " with", + index: 0, + part: Reasoning( + ":", ), metadata: {}, }, Part { - index: 1, - part: Message( - " something", + index: 0, + part: Reasoning( + " Quote", ), metadata: {}, }, Part { - index: 1, - part: Message( - " particular", + index: 0, + part: Reasoning( + " the", ), metadata: {}, }, Part { - index: 1, - part: Message( - "?", + index: 0, + part: Reasoning( + " exact", ), metadata: {}, }, Part { - index: 1, - part: Message( - " 😊", + index: 0, + part: Reasoning( + " string", ), metadata: {}, }, - Flush { - index: 1, - metadata: {}, - }, - Finished( - Completed, - ), - ], - [ Part { index: 0, part: Reasoning( - "The", + " from", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " their", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " last", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " asking", + " prompt", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " about", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + "\n\n Wait", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " result", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " of", + " technically", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " call", + "previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " that", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + "\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " simulated", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " earlier", + "Turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " 2", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Looking", + ")", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " at", + " was", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " also", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " conversation", + " an", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " history", + " assistant", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " turn", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " can", + " But", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " see", + " user", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " there", + " means", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " was", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " a", + "my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " previous", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "tool", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + "\".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " output", + " So", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " that", + " yes", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " showed", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ":", + " `", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\n```", + "Test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "json", + " message", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n{", + "`.", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n \"", + "\n\n Let", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "secret", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " code", + " just", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\":", + " output", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " text", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " clearly", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Flush { + index: 0, + metadata: {}, + }, + Part { + index: 1, + part: Message( + "test", + ), + metadata: {}, + }, + Flush { + index: 1, + metadata: {}, + }, + Finished( + Completed, + ), + ], + [ + Flush { + index: 0, + metadata: {}, + }, + Part { + index: 2, + part: ToolCall( + Start { + id: "run_me_2", + name: "run_me", + }, + ), + metadata: {}, + }, + Part { + index: 2, + part: ToolCall( + ArgumentChunk( + "{\"bar\":[\"foo\",\"bar\"],\"foo\":\"test value\"}", + ), + ), + metadata: {}, + }, + Flush { + index: 2, + metadata: {}, + }, + Flush { + index: 1, + metadata: {}, + }, + Finished( + Completed, + ), + ], + [ + Flush { + index: 0, + metadata: {}, + }, + Part { + index: 1, + part: Message( + "It", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " seems", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " the", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " tool", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " ran", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " successfully", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ",", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " but", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " I", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " can", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "’t", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " access", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " or", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " display", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " external", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " secrets", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " like", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " \"", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "the", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " secret", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " code", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ".\"", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " 😊", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " \n\nIf", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " you", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "’re", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " testing", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " a", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " specific", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " workflow", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " (", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "e", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ".g", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ".,", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " API", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " integration", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "),", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " feel", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " free", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " to", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " share", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " details", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " about", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " what", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " *", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "you", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "*", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " need", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " help", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " with", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "—I", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "’ll", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " guide", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " you", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " on", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " how", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " to", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " structure", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " tools", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "/prom", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "pts", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " for", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " your", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " use", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " case", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "!", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " 🔍", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "✨", + ), + metadata: {}, + }, + Flush { + index: 1, + metadata: {}, + }, + Finished( + Completed, + ), + ], + [ + Part { + index: 0, + part: Reasoning( + "The", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " user", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " asking", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " summarize", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " report", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " back", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " from", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " specific", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " part", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Use", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " that", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " happened", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " earlier", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " in", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " this", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " conversation", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ").", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Let", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " check", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " what", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " actually", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " occurred", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n1", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " ran", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " with", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " `", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "foo", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "=test", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " value", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "`", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " and", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " `", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "bar", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "=[\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "foo", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\",\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "bar", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\"]", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "`.", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " The", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " system", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " provided", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " response", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "The", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " secret", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " code", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 4", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "2", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n2", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " In", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " my", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " follow", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "-up", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " message", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " explained", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " them", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " that", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " while", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " it", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " looks", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " like", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " there", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " was", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " output", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " from", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " an", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " external", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " source", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "secret", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " code", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "),", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " as", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " an", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " AI", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " model", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " within", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " this", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " platform", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " those", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " outputs", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " are", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " simulated", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " for", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " testing", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " purposes", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " and", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " not", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " actual", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " secrets", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " data", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " sources", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " accessible", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " by", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " externally", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\nSo", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " user", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " wants", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " know", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " what", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " happened", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " earlier", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " in", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " conversation", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " -", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " let", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " just", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " provide", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " simple", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " answer", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " The", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " result", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " of", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " running", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " that", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " call", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " was", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " output", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " showing", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "The", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " secret", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " code", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " 4", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "2", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "based", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " on", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " previous", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " messages", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ").", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " However", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " should", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " also", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " clarify", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " this", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " isn", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'t", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " real", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " external", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " data", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " but", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " rather", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " part", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " of", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " testing", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\nWait", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " actually", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " looking", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " at", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " instructions", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " again", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " more", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " carefully", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " for", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Use", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " -", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " these", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " appear", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " be", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " simulation", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " within", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " this", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " chat", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " platform", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " with", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " special", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " markers", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " like", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " `", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "`", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " and", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " `", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "`.", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " The", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " system", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " is", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " designed", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " simulate", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " interactions", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " during", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " development", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "/testing", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " purposes", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " when", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " no", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " 4", + " actual", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "2", + " tools", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n}", + " are", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n```", + " being", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nThis", + " connected", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " was", + " in", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " a", + " real", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " test", + " scenarios", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "/s", + " like", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "im", + " production", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "ulated", + " systems", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " response", + "\n\nGiven", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " -", + " how", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " not", + " it", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " an", + " looks", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " actual", + " here", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " function", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " call", + " that", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " was", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " The", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " test", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " wants", + " output", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " me", + " from", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " running", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " recall", + " something", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " what", + " -", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " let", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + " me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " result", + " just", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " said", + " give", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " The", + " clear", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " straightforward", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " answer", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Flush { + index: 0, + metadata: {}, + }, + Part { + index: 1, + part: Message( + "The", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " result", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " of", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " my", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " previous", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " tool", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " call", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " simulation", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " showed", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ":", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " **", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "`", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "{", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " \"", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "secret", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "_code", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "\":", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " 4", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "2", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " }", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "`", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "**", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " or", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " formatted", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " as", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " `\"", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "The", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " output", + index: 1, + part: Message( + " secret", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " clearly", + index: 1, + part: Message( + " code", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " indicated", + index: 1, + part: Message( + " is", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( + index: 1, + part: Message( ":", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - "\n\n\"The", + index: 1, + part: Message( + " 4", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " secret", + index: 1, + part: Message( + "2", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " code", + index: 1, + part: Message( + "\"", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " is", + index: 1, + part: Message( + "`.", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - ":", + index: 1, + part: Message( + " This", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " 4", + index: 1, + part: Message( + " appears", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - "2", + index: 1, + part: Message( + " to", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - "\"", + index: 1, + part: Message( + " be", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - "\n\nI", + index: 1, + part: Message( + " testing", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " should", + index: 1, + part: Message( + " data", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " just", + index: 1, + part: Message( + " and", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " answer", + index: 1, + part: Message( + " not", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " directly", + index: 1, + part: Message( + " genuine", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " and", + index: 1, + part: Message( + " external", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " accurately", + index: 1, + part: Message( + " secrets", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " about", + index: 1, + part: Message( + " accessible", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " what", + index: 1, + part: Message( + " via", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " that", + index: 1, + part: Message( + " internal", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " previous", + index: 1, + part: Message( + " systems", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " output", + index: 1, + part: Message( + ".", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " showed", + index: 1, + part: Message( + " It", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - ".", + index: 1, + part: Message( + "'s", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " This", + index: 1, + part: Message( + " just", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " is", + index: 1, + part: Message( + " part", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " a", + index: 1, + part: Message( + " of", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " straightforward", + index: 1, + part: Message( + " our", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " question", + index: 1, + part: Message( + " current", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " with", + index: 1, + part: Message( + " test", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " no", + index: 1, + part: Message( + " run", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " need", + index: 1, + part: Message( + "!", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " for", + index: 1, + part: Message( + " 😊", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " special", + index: 1, + part: Message( + "\n\nLet", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " tools", + index: 1, + part: Message( + " me", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " or", + index: 1, + part: Message( + " know", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " thinking", + index: 1, + part: Message( + " if", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - " steps", + index: 1, + part: Message( + " you", ), metadata: {}, }, Part { - index: 0, - part: Reasoning( - ".", + index: 1, + part: Message( + " want", ), metadata: {}, }, - Flush { - index: 0, + Part { + index: 1, + part: Message( + " another", + ), metadata: {}, }, Part { index: 1, part: Message( - "The", + " example", ), metadata: {}, }, Part { index: 1, part: Message( - " result", + " tool", ), metadata: {}, }, Part { index: 1, part: Message( - " of", + " call", ), metadata: {}, }, Part { index: 1, part: Message( - " the", + " or", ), metadata: {}, }, Part { index: 1, part: Message( - " tool", + " more", ), metadata: {}, }, Part { index: 1, part: Message( - " call", + " guidance", ), metadata: {}, }, Part { index: 1, part: Message( - " was", + " on", ), metadata: {}, }, Part { index: 1, part: Message( - ":", + " how", ), metadata: {}, }, Part { index: 1, part: Message( - " **", + " this", ), metadata: {}, }, Part { index: 1, part: Message( - "The", + " works", ), metadata: {}, }, Part { index: 1, part: Message( - " secret", + " for", ), metadata: {}, }, Part { index: 1, part: Message( - " code", + " your", ), metadata: {}, }, Part { index: 1, part: Message( - " is", + " project", ), metadata: {}, }, Part { index: 1, part: Message( - ":", + " needs", ), metadata: {}, }, Part { index: 1, part: Message( - " 4", + "!", ), metadata: {}, }, Part { index: 1, part: Message( - "2", + " 🛠", ), metadata: {}, }, Part { index: 1, part: Message( - "**", + "\u{fe0f}", ), metadata: {}, }, Part { index: 1, part: Message( - " 😊", + "✨", ), metadata: {}, }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_structured_output.snap b/crates/jp_llm/tests/fixtures/ollama/test_structured_output.snap index 72e881dae..1e2d4a8cd 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_structured_output.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_structured_output.snap @@ -9,7 +9,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Structured { - data: String("Conversation: Requesting a Title Generation"), + data: String("Here are a few suitable titles, depending on the context of our interaction:\n\n1. **Getting Started** (Simple and direct)\n2. **Introduction to Our Chat** (Friendly approach)\n3. **First Steps Together** (Collaborative tone)\n4. **Exploring Topics with You** (Inviting exploration)\n5. **Hello, I'm Ready for Questions!** (Action-oriented)\n\nLet me know if you'd like something more creative or tailored to a specific theme!"), }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_structured_output.yml b/crates/jp_llm/tests/fixtures/ollama/test_structured_output.yml index bab69d5ec..715a51c47 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_structured_output.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_structured_output.yml @@ -40,11 +40,101 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.11783Z","message":{"role":"assistant","content":"Conversation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.157311Z","message":{"role":"assistant","content":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.202367Z","message":{"role":"assistant","content":" Request"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.244099Z","message":{"role":"assistant","content":"ing"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.283501Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.321767Z","message":{"role":"assistant","content":" Title"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.359782Z","message":{"role":"assistant","content":" Generation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:24.398852Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":38449632917,"load_duration":5079675833,"prompt_eval_count":19,"prompt_eval_duration":179946500,"eval_count":8,"eval_duration":257843374} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.151502Z","message":{"role":"assistant","content":"Here"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.175219Z","message":{"role":"assistant","content":" are"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.197904Z","message":{"role":"assistant","content":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.221389Z","message":{"role":"assistant","content":" few"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.244991Z","message":{"role":"assistant","content":" suitable"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.268255Z","message":{"role":"assistant","content":" titles"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.292125Z","message":{"role":"assistant","content":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.315724Z","message":{"role":"assistant","content":" depending"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.340172Z","message":{"role":"assistant","content":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.364387Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.388541Z","message":{"role":"assistant","content":" context"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.41202Z","message":{"role":"assistant","content":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.435682Z","message":{"role":"assistant","content":" our"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.459188Z","message":{"role":"assistant","content":" interaction"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.482957Z","message":{"role":"assistant","content":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.530035Z","message":{"role":"assistant","content":"\n\n1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.553301Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.600665Z","message":{"role":"assistant","content":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.624313Z","message":{"role":"assistant","content":"Getting"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.648069Z","message":{"role":"assistant","content":" Started"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.671776Z","message":{"role":"assistant","content":"**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.695087Z","message":{"role":"assistant","content":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.718454Z","message":{"role":"assistant","content":"Simple"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.742108Z","message":{"role":"assistant","content":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.765233Z","message":{"role":"assistant","content":" direct"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.788842Z","message":{"role":"assistant","content":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.83574Z","message":{"role":"assistant","content":"\n2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.859071Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.905359Z","message":{"role":"assistant","content":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.928915Z","message":{"role":"assistant","content":"Introduction"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.951942Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.975497Z","message":{"role":"assistant","content":" Our"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:25.998629Z","message":{"role":"assistant","content":" Chat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.022069Z","message":{"role":"assistant","content":"**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.045465Z","message":{"role":"assistant","content":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.068893Z","message":{"role":"assistant","content":"Friendly"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.092392Z","message":{"role":"assistant","content":" approach"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.115592Z","message":{"role":"assistant","content":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.162327Z","message":{"role":"assistant","content":"\n3"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.186014Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.232938Z","message":{"role":"assistant","content":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.256171Z","message":{"role":"assistant","content":"First"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.279904Z","message":{"role":"assistant","content":" Steps"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.302701Z","message":{"role":"assistant","content":" Together"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.326174Z","message":{"role":"assistant","content":"**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.349693Z","message":{"role":"assistant","content":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.372859Z","message":{"role":"assistant","content":"Coll"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.396595Z","message":{"role":"assistant","content":"abor"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.420361Z","message":{"role":"assistant","content":"ative"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.443874Z","message":{"role":"assistant","content":" tone"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.467094Z","message":{"role":"assistant","content":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.513148Z","message":{"role":"assistant","content":"\n4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.536753Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.583623Z","message":{"role":"assistant","content":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.606842Z","message":{"role":"assistant","content":"Expl"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.630642Z","message":{"role":"assistant","content":"oring"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.653882Z","message":{"role":"assistant","content":" Topics"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.677439Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.701368Z","message":{"role":"assistant","content":" You"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.724983Z","message":{"role":"assistant","content":"**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.748569Z","message":{"role":"assistant","content":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.771764Z","message":{"role":"assistant","content":"Inv"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.794505Z","message":{"role":"assistant","content":"iting"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.817619Z","message":{"role":"assistant","content":" exploration"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.841181Z","message":{"role":"assistant","content":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.887973Z","message":{"role":"assistant","content":"\n5"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.911188Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.958125Z","message":{"role":"assistant","content":" **"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:26.981907Z","message":{"role":"assistant","content":"Hello"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.005194Z","message":{"role":"assistant","content":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.028849Z","message":{"role":"assistant","content":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.052065Z","message":{"role":"assistant","content":"'m"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.075621Z","message":{"role":"assistant","content":" Ready"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.098193Z","message":{"role":"assistant","content":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.121832Z","message":{"role":"assistant","content":" Questions"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.145416Z","message":{"role":"assistant","content":"!**"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.168719Z","message":{"role":"assistant","content":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.191534Z","message":{"role":"assistant","content":"Action"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.214842Z","message":{"role":"assistant","content":"-oriented"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.238476Z","message":{"role":"assistant","content":")"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.285332Z","message":{"role":"assistant","content":"\n\nLet"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.308497Z","message":{"role":"assistant","content":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.332144Z","message":{"role":"assistant","content":" know"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.354707Z","message":{"role":"assistant","content":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.378242Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.401942Z","message":{"role":"assistant","content":"'d"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.425644Z","message":{"role":"assistant","content":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.449232Z","message":{"role":"assistant","content":" something"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.472155Z","message":{"role":"assistant","content":" more"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.495652Z","message":{"role":"assistant","content":" creative"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.51922Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.543103Z","message":{"role":"assistant","content":" tailored"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.566375Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.590066Z","message":{"role":"assistant","content":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.61325Z","message":{"role":"assistant","content":" specific"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.636904Z","message":{"role":"assistant","content":" theme"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.660025Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:27.683906Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":39508657208,"load_duration":7034199916,"prompt_eval_count":19,"prompt_eval_duration":160546000,"eval_count":109,"eval_duration":2532311000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_structured_output__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_structured_output__conversation_stream.snap index 485cf1dfb..0af4ea1c9 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_structured_output__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_structured_output__conversation_stream.snap @@ -239,7 +239,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "data": "Conversation: Requesting a Title Generation" + "data": "Here are a few suitable titles, depending on the context of our interaction:\n\n1. **Getting Started** (Simple and direct)\n2. **Introduction to Our Chat** (Friendly approach)\n3. **First Steps Together** (Collaborative tone)\n4. **Exploring Topics with You** (Inviting exploration)\n5. **Hello, I'm Ready for Questions!** (Action-oriented)\n\nLet me know if you'd like something more creative or tailored to a specific theme!" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_structured_output__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_structured_output__raw_events.snap index 5cab04238..66a97bcd2 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_structured_output__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_structured_output__raw_events.snap @@ -11,7 +11,98 @@ expression: v Part { index: 1, part: Structured( - "Conversation", + "Here", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " are", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " a", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " few", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " suitable", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " titles", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ",", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " depending", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " on", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " the", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " context", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " of", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " our", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " interaction", ), metadata: {}, }, @@ -25,14 +116,546 @@ expression: v Part { index: 1, part: Structured( - " Request", + "\n\n1", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ".", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " **", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Getting", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Started", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "**", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " (", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Simple", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " and", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " direct", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ")", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "\n2", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ".", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " **", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Introduction", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " to", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Our", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Chat", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "**", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " (", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Friendly", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " approach", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ")", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "\n3", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ".", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " **", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "First", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Steps", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Together", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "**", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " (", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Coll", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "abor", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "ative", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " tone", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ")", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "\n4", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ".", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " **", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Expl", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "oring", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Topics", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " with", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " You", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "**", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " (", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Inv", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "iting", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " exploration", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ")", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "\n5", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ".", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " **", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Hello", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ",", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " I", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "'m", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Ready", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " for", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " Questions", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "!**", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " (", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "Action", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "-oriented", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + ")", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "\n\nLet", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " me", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " know", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " if", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " you", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + "'d", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " like", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " something", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " more", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " creative", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " or", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " tailored", ), metadata: {}, }, Part { index: 1, part: Structured( - "ing", + " to", ), metadata: {}, }, @@ -46,14 +669,21 @@ expression: v Part { index: 1, part: Structured( - " Title", + " specific", + ), + metadata: {}, + }, + Part { + index: 1, + part: Structured( + " theme", ), metadata: {}, }, Part { index: 1, part: Structured( - " Generation", + "!", ), metadata: {}, }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.snap index 0c84d2e0b..1a6abb936 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.snap @@ -12,7 +12,7 @@ expression: v id: "run_me_2", name: "run_me", arguments: { - "command": String("ls -la /home"), + "bar": String("foo"), }, }, ), @@ -29,7 +29,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "The command has executed successfully. Would you like to try a different command or have me run something else? 😊", + message: "The tool executed successfully with the argument `bar=\"foo\"`. It returned \"working!\". Is there anything specific you'd like to do next, or should we try a different set of arguments? 😊", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.yml b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.yml index ed8dec923..40f73a975 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto.yml @@ -19,26 +19,32 @@ when: "name": "run_me", "description": "", "parameters": { - "foo": { - "type": "string", - "default": "foo" - }, - "bar": { - "type": [ - "string", - "array" - ], - "enum": [ - "foo", - [ - "foo", - "bar" - ] - ], - "items": { - "type": "string" + "type": "object", + "properties": { + "foo": { + "type": "string", + "default": "foo" + }, + "bar": { + "type": [ + "string", + "array" + ], + "enum": [ + "foo" + ], + "items": { + "type": "string", + "enum": [ + "foo", + "bar" + ] + } } - } + }, + "required": [ + "bar" + ] } } } @@ -53,8 +59,8 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:15.853887Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_iiw0eb0o","function":{"index":0,"name":"run_me","arguments":{"command":"ls -la /home"}}}]},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:15.911002Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":29594467500,"load_duration":4712957042,"prompt_eval_count":253,"prompt_eval_duration":938433958,"eval_count":31,"eval_duration":1707533291} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.385276Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_mj3cj28a","function":{"index":0,"name":"run_me","arguments":{"bar":"foo"}}}]},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.408507Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":28233315334,"load_duration":7035176834,"prompt_eval_count":306,"prompt_eval_duration":86896000,"eval_count":27,"eval_duration":602310000} --- when: path: /api/chat @@ -77,7 +83,7 @@ when: "function": { "name": "run_me", "arguments": { - "command": "ls -la /home" + "bar": "foo" } } } @@ -101,26 +107,44 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.653532Z","message":{"role":"assistant","content":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.691299Z","message":{"role":"assistant","content":" command"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.730599Z","message":{"role":"assistant","content":" has"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.767794Z","message":{"role":"assistant","content":" executed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.803773Z","message":{"role":"assistant","content":" successfully"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.841357Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.878819Z","message":{"role":"assistant","content":" Would"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.915469Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.953515Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.990515Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.027998Z","message":{"role":"assistant","content":" try"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.065316Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.102791Z","message":{"role":"assistant","content":" different"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.140272Z","message":{"role":"assistant","content":" command"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.177775Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.214001Z","message":{"role":"assistant","content":" have"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.250753Z","message":{"role":"assistant","content":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.287852Z","message":{"role":"assistant","content":" run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.324745Z","message":{"role":"assistant","content":" something"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.361612Z","message":{"role":"assistant","content":" else"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.399043Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.47511Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.512747Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":34600179542,"load_duration":108391000,"prompt_eval_count":69,"prompt_eval_duration":316928125,"eval_count":24,"eval_duration":824236125} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.554171Z","message":{"role":"assistant","content":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.579182Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.601966Z","message":{"role":"assistant","content":" executed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.62474Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.647824Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.670289Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.69331Z","message":{"role":"assistant","content":" argument"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.716462Z","message":{"role":"assistant","content":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.743361Z","message":{"role":"assistant","content":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.768247Z","message":{"role":"assistant","content":"=\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.793417Z","message":{"role":"assistant","content":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.818752Z","message":{"role":"assistant","content":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.843732Z","message":{"role":"assistant","content":"`."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.868118Z","message":{"role":"assistant","content":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.892825Z","message":{"role":"assistant","content":" returned"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.91564Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.939386Z","message":{"role":"assistant","content":"working"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.96236Z","message":{"role":"assistant","content":"!\"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.986357Z","message":{"role":"assistant","content":" Is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.008966Z","message":{"role":"assistant","content":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.032055Z","message":{"role":"assistant","content":" anything"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.055537Z","message":{"role":"assistant","content":" specific"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.078601Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.101557Z","message":{"role":"assistant","content":"'d"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.124983Z","message":{"role":"assistant","content":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.148037Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.171534Z","message":{"role":"assistant","content":" do"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.194556Z","message":{"role":"assistant","content":" next"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.217984Z","message":{"role":"assistant","content":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.241239Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.264338Z","message":{"role":"assistant","content":" should"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.287335Z","message":{"role":"assistant","content":" we"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.310255Z","message":{"role":"assistant","content":" try"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.333857Z","message":{"role":"assistant","content":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.356752Z","message":{"role":"assistant","content":" different"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.380309Z","message":{"role":"assistant","content":" set"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.403285Z","message":{"role":"assistant","content":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.426756Z","message":{"role":"assistant","content":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.449728Z","message":{"role":"assistant","content":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.496245Z","message":{"role":"assistant","content":" 😊"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.519925Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":31107695083,"load_duration":212833083,"prompt_eval_count":65,"prompt_eval_duration":218942000,"eval_count":42,"eval_duration":965559000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__conversation_stream.snap index 0f3077e01..2714fd739 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__conversation_stream.snap @@ -224,7 +224,7 @@ expression: v "id": "run_me_2", "name": "run_me", "arguments": { - "command": "bHMgLWxhIC9ob21l" + "bar": "Zm9v" } }, { @@ -237,7 +237,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "The command has executed successfully. Would you like to try a different command or have me run something else? 😊" + "message": "The tool executed successfully with the argument `bar=\"foo\"`. It returned \"working!\". Is there anything specific you'd like to do next, or should we try a different set of arguments? 😊" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__raw_events.snap index 3a23c4f04..7a44132f5 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_auto__raw_events.snap @@ -22,7 +22,7 @@ expression: v index: 2, part: ToolCall( ArgumentChunk( - "{\"command\":\"ls -la /home\"}", + "{\"bar\":\"foo\"}", ), ), metadata: {}, @@ -54,42 +54,147 @@ expression: v Part { index: 1, part: Message( - " command", + " tool", ), metadata: {}, }, Part { index: 1, part: Message( - " has", + " executed", ), metadata: {}, }, Part { index: 1, part: Message( - " executed", + " successfully", ), metadata: {}, }, Part { index: 1, part: Message( - " successfully", + " with", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " the", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " argument", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " `", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "bar", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "=\"", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "foo", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "\"", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "`.", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " It", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " returned", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " \"", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "working", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "!\".", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " Is", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " there", ), metadata: {}, }, Part { index: 1, part: Message( - ".", + " anything", ), metadata: {}, }, Part { index: 1, part: Message( - " Would", + " specific", ), metadata: {}, }, @@ -100,6 +205,13 @@ expression: v ), metadata: {}, }, + Part { + index: 1, + part: Message( + "'d", + ), + metadata: {}, + }, Part { index: 1, part: Message( @@ -117,70 +229,84 @@ expression: v Part { index: 1, part: Message( - " try", + " do", ), metadata: {}, }, Part { index: 1, part: Message( - " a", + " next", ), metadata: {}, }, Part { index: 1, part: Message( - " different", + ",", ), metadata: {}, }, Part { index: 1, part: Message( - " command", + " or", ), metadata: {}, }, Part { index: 1, part: Message( - " or", + " should", ), metadata: {}, }, Part { index: 1, part: Message( - " have", + " we", ), metadata: {}, }, Part { index: 1, part: Message( - " me", + " try", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " a", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " different", ), metadata: {}, }, Part { index: 1, part: Message( - " run", + " set", ), metadata: {}, }, Part { index: 1, part: Message( - " something", + " of", ), metadata: {}, }, Part { index: 1, part: Message( - " else", + " arguments", ), metadata: {}, }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.snap index 09d556637..71352665b 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.snap @@ -11,7 +11,12 @@ expression: v ToolCallRequest { id: "run_me_2", name: "run_me", - arguments: {}, + arguments: { + "foo": String("random_argument"), + "bar": Array [ + String("foo"), + ], + }, }, ), metadata: {}, @@ -27,7 +32,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "It looks like you're asking me to \"run a tool,\" but there isn't a specific tool defined in your message. To help better, could you clarify:\n\n1. **What tool** are you referring to? (e.g., a code interpreter, calculator, or custom function)\n2. **What arguments** should I provide? (e.g., numbers for math, text to analyze, data to process)\n3. **What outcome** do you expect? (e.g., generate a report, solve an equation, visualize data)\n\nLet me know so I can assist! 😊", + message: "The tool executed successfully with the provided arguments. Is there anything specific you'd like to do next? 😊", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.yml b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.yml index f6fa281a2..3c676b87c 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function.yml @@ -25,26 +25,32 @@ when: "name": "run_me", "description": "", "parameters": { - "foo": { - "type": "string", - "default": "foo" - }, - "bar": { - "type": [ - "string", - "array" - ], - "enum": [ - "foo", - [ - "foo", - "bar" - ] - ], - "items": { - "type": "string" + "type": "object", + "properties": { + "foo": { + "type": "string", + "default": "foo" + }, + "bar": { + "type": [ + "string", + "array" + ], + "enum": [ + "foo" + ], + "items": { + "type": "string", + "enum": [ + "foo", + "bar" + ] + } } - } + }, + "required": [ + "bar" + ] } } } @@ -59,8 +65,8 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:23.896963Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_77bh2121","function":{"index":0,"name":"run_me","arguments":{}}}]},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:23.934749Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":36584687833,"load_duration":3679553125,"prompt_eval_count":295,"prompt_eval_duration":860427333,"eval_count":15,"eval_duration":502482750} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:20.886491Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_8hovyjtv","function":{"index":0,"name":"run_me","arguments":{"foo":"random_argument","bar":["foo"]}}}]},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:20.909182Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":32734152500,"load_duration":7036097583,"prompt_eval_count":348,"prompt_eval_duration":214883000,"eval_count":42,"eval_duration":951470000} --- when: path: /api/chat @@ -82,7 +88,12 @@ when: { "function": { "name": "run_me", - "arguments": {} + "arguments": { + "foo": "random_argument", + "bar": [ + "foo" + ] + } } } ], @@ -105,122 +116,25 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.265707Z","message":{"role":"assistant","content":"It"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.30359Z","message":{"role":"assistant","content":" looks"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.342459Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.380595Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.418032Z","message":{"role":"assistant","content":"'re"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.455695Z","message":{"role":"assistant","content":" asking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.49322Z","message":{"role":"assistant","content":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.530807Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.568445Z","message":{"role":"assistant","content":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.606123Z","message":{"role":"assistant","content":"run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.643601Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.681761Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.71944Z","message":{"role":"assistant","content":",\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.756441Z","message":{"role":"assistant","content":" but"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.793824Z","message":{"role":"assistant","content":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.834036Z","message":{"role":"assistant","content":" isn"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.869092Z","message":{"role":"assistant","content":"'t"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.906039Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.943521Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.980332Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.017392Z","message":{"role":"assistant","content":" defined"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.054849Z","message":{"role":"assistant","content":" in"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.092262Z","message":{"role":"assistant","content":" your"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.130041Z","message":{"role":"assistant","content":" message"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.167645Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.205586Z","message":{"role":"assistant","content":" To"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.243176Z","message":{"role":"assistant","content":" help"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.280903Z","message":{"role":"assistant","content":" better"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.318429Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.355998Z","message":{"role":"assistant","content":" could"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.393734Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.431415Z","message":{"role":"assistant","content":" clarify"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.468999Z","message":{"role":"assistant","content":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.544337Z","message":{"role":"assistant","content":"\n\n1"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.581775Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.619628Z","message":{"role":"assistant","content":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.657247Z","message":{"role":"assistant","content":"What"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.694309Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.731564Z","message":{"role":"assistant","content":"**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.768811Z","message":{"role":"assistant","content":" are"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.805809Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.843094Z","message":{"role":"assistant","content":" referring"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.880611Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.918135Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.956029Z","message":{"role":"assistant","content":" ("},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:56.99376Z","message":{"role":"assistant","content":"e"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.030855Z","message":{"role":"assistant","content":".g"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.0685Z","message":{"role":"assistant","content":".,"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.104886Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.140921Z","message":{"role":"assistant","content":" code"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.176766Z","message":{"role":"assistant","content":" interpreter"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.212577Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.250863Z","message":{"role":"assistant","content":" calculator"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.287679Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.325108Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.361145Z","message":{"role":"assistant","content":" custom"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.397235Z","message":{"role":"assistant","content":" function"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.433086Z","message":{"role":"assistant","content":")"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.50528Z","message":{"role":"assistant","content":"\n2"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.542739Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.580323Z","message":{"role":"assistant","content":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.617812Z","message":{"role":"assistant","content":"What"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.655084Z","message":{"role":"assistant","content":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.691993Z","message":{"role":"assistant","content":"**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.729034Z","message":{"role":"assistant","content":" should"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.765965Z","message":{"role":"assistant","content":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.80317Z","message":{"role":"assistant","content":" provide"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.840628Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.878013Z","message":{"role":"assistant","content":" ("},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.915154Z","message":{"role":"assistant","content":"e"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.952972Z","message":{"role":"assistant","content":".g"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:57.989821Z","message":{"role":"assistant","content":".,"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.027745Z","message":{"role":"assistant","content":" numbers"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.065984Z","message":{"role":"assistant","content":" for"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.104258Z","message":{"role":"assistant","content":" math"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.142095Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.179263Z","message":{"role":"assistant","content":" text"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.217771Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.25532Z","message":{"role":"assistant","content":" analyze"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.293101Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.33084Z","message":{"role":"assistant","content":" data"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.368522Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.404689Z","message":{"role":"assistant","content":" process"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.441334Z","message":{"role":"assistant","content":")"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.516738Z","message":{"role":"assistant","content":"\n3"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.554399Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.592299Z","message":{"role":"assistant","content":" **"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.629958Z","message":{"role":"assistant","content":"What"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.667928Z","message":{"role":"assistant","content":" outcome"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.705907Z","message":{"role":"assistant","content":"**"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.743189Z","message":{"role":"assistant","content":" do"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.78066Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.817668Z","message":{"role":"assistant","content":" expect"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.854704Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.891952Z","message":{"role":"assistant","content":" ("},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.928874Z","message":{"role":"assistant","content":"e"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:58.965876Z","message":{"role":"assistant","content":".g"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.003406Z","message":{"role":"assistant","content":".,"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.041039Z","message":{"role":"assistant","content":" generate"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.078552Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.116166Z","message":{"role":"assistant","content":" report"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.153711Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.191441Z","message":{"role":"assistant","content":" solve"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.229124Z","message":{"role":"assistant","content":" an"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.266693Z","message":{"role":"assistant","content":" equation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.304296Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.341754Z","message":{"role":"assistant","content":" visualize"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.379138Z","message":{"role":"assistant","content":" data"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.417096Z","message":{"role":"assistant","content":")"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.492342Z","message":{"role":"assistant","content":"\n\nLet"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.53001Z","message":{"role":"assistant","content":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.567695Z","message":{"role":"assistant","content":" know"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.605364Z","message":{"role":"assistant","content":" so"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.642581Z","message":{"role":"assistant","content":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.680292Z","message":{"role":"assistant","content":" can"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.717375Z","message":{"role":"assistant","content":" assist"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.753516Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.826074Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:59.863269Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":35923243250,"load_duration":117055000,"prompt_eval_count":53,"prompt_eval_duration":244549875,"eval_count":124,"eval_duration":4408355536} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.367971Z","message":{"role":"assistant","content":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.392148Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.415341Z","message":{"role":"assistant","content":" executed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.438846Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.461619Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.484598Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.507644Z","message":{"role":"assistant","content":" provided"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.530659Z","message":{"role":"assistant","content":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.553695Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.57676Z","message":{"role":"assistant","content":" Is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.5999Z","message":{"role":"assistant","content":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.623031Z","message":{"role":"assistant","content":" anything"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.6463Z","message":{"role":"assistant","content":" specific"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.66919Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.692507Z","message":{"role":"assistant","content":"'d"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.715503Z","message":{"role":"assistant","content":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.738931Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.761862Z","message":{"role":"assistant","content":" do"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.785333Z","message":{"role":"assistant","content":" next"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.808269Z","message":{"role":"assistant","content":"?"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.854855Z","message":{"role":"assistant","content":" 😊"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.878452Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":28964991500,"load_duration":203679666,"prompt_eval_count":80,"prompt_eval_duration":276581000,"eval_count":23,"eval_duration":510412000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__conversation_stream.snap index 0bf726bb7..126c2189a 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__conversation_stream.snap @@ -223,7 +223,12 @@ expression: v "type": "tool_call_request", "id": "run_me_2", "name": "run_me", - "arguments": {} + "arguments": { + "foo": "cmFuZG9tX2FyZ3VtZW50", + "bar": [ + "Zm9v" + ] + } }, { "timestamp": "2020-01-01 00:00:00.0", @@ -235,7 +240,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "It looks like you're asking me to \"run a tool,\" but there isn't a specific tool defined in your message. To help better, could you clarify:\n\n1. **What tool** are you referring to? (e.g., a code interpreter, calculator, or custom function)\n2. **What arguments** should I provide? (e.g., numbers for math, text to analyze, data to process)\n3. **What outcome** do you expect? (e.g., generate a report, solve an equation, visualize data)\n\nLet me know so I can assist! 😊" + "message": "The tool executed successfully with the provided arguments. Is there anything specific you'd like to do next? 😊" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__raw_events.snap index ec4927727..2b8120045 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_function__raw_events.snap @@ -22,7 +22,7 @@ expression: v index: 2, part: ToolCall( ArgumentChunk( - "{}", + "{\"foo\":\"random_argument\",\"bar\":[\"foo\"]}", ), ), metadata: {}, @@ -47,77 +47,7 @@ expression: v Part { index: 1, part: Message( - "It", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " looks", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " like", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " you", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "'re", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " asking", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " me", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " to", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " \"", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "run", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " a", + "The", ), metadata: {}, }, @@ -131,84 +61,42 @@ expression: v Part { index: 1, part: Message( - ",\"", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " but", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " there", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " isn", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "'t", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " a", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " specific", + " executed", ), metadata: {}, }, Part { index: 1, part: Message( - " tool", + " successfully", ), metadata: {}, }, Part { index: 1, part: Message( - " defined", + " with", ), metadata: {}, }, Part { index: 1, part: Message( - " in", + " the", ), metadata: {}, }, Part { index: 1, part: Message( - " your", + " provided", ), metadata: {}, }, Part { index: 1, part: Message( - " message", + " arguments", ), metadata: {}, }, @@ -222,35 +110,28 @@ expression: v Part { index: 1, part: Message( - " To", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " help", + " Is", ), metadata: {}, }, Part { index: 1, part: Message( - " better", + " there", ), metadata: {}, }, Part { index: 1, part: Message( - ",", + " anything", ), metadata: {}, }, Part { index: 1, part: Message( - " could", + " specific", ), metadata: {}, }, @@ -264,77 +145,14 @@ expression: v Part { index: 1, part: Message( - " clarify", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ":", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "\n\n1", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " **", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "What", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " tool", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "**", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " are", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " you", + "'d", ), metadata: {}, }, Part { index: 1, part: Message( - " referring", + " like", ), metadata: {}, }, @@ -348,168 +166,14 @@ expression: v Part { index: 1, part: Message( - "?", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " (", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "e", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".g", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".,", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " a", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " code", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " interpreter", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " calculator", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " or", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " custom", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " function", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ")", + " do", ), metadata: {}, }, Part { index: 1, part: Message( - "\n2", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " **", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "What", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " arguments", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "**", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " should", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " I", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " provide", + " next", ), metadata: {}, }, @@ -520,349 +184,6 @@ expression: v ), metadata: {}, }, - Part { - index: 1, - part: Message( - " (", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "e", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".g", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".,", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " numbers", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " for", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " math", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " text", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " to", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " analyze", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " data", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " to", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " process", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ")", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "\n3", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " **", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "What", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " outcome", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "**", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " do", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " you", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " expect", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "?", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " (", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "e", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".g", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ".,", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " generate", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " a", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " report", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " solve", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " an", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " equation", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " visualize", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " data", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ")", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "\n\nLet", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " me", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " know", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " so", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " I", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " can", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " assist", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "!", - ), - metadata: {}, - }, Part { index: 1, part: Message( diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.snap index 91249e9e6..5176491c7 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.snap @@ -9,7 +9,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Reasoning { - reasoning: "The user is asking me to run a tool, but they haven't specified which tool or what arguments I should use. Looking at the available tools, there's only one called \"run_me\" with no parameters defined (both type and properties are empty strings/null).\n\nSince there's only one tool available (\"run_me\") and it has no required parameters, I can call it without any arguments. The user said \"providing whatever arguments you want\" which suggests I have flexibility, but since this tool doesn't take any parameters anyway, I'll just call it with no arguments.", + reasoning: "The user wants me to run a tool but hasn't specified what parameters they want to use. Looking at the available tools, I see there's only one called \"run_me\" which has these parameters:\n\n- `bar`: required parameter of type [\"string\", array] with enum values [\"foo\"] - this seems like it can be either string or array\n- `foo`: optional parameter that is a string type\n\nSince the user said to provide whatever arguments I want, but there's a requirement for at least one argument (the \"bar\" parameter), and looking at the constraints:\n- bar must have enum value of \"foo\" if it's using those values\n- foo can be any string\n\nI should call run_me with some valid parameters. Let me make sure I meet the required constraint that bar is provided, so either as a string or array but containing appropriate values based on what seems to be expected (likely just [\"foo\"] since that's in the enum).\n\nLet me provide reasonable arguments - I'll use \"bar\" as an array with \"foo\" value and maybe include some foo parameter too.", }, ), metadata: {}, @@ -22,7 +22,13 @@ expression: v ToolCallRequest { id: "run_me_2", name: "run_me", - arguments: {}, + arguments: { + "foo": String("test_value"), + "bar": Array [ + String("foo"), + String("bar"), + ], + }, }, ), metadata: {}, @@ -38,7 +44,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "The tool executed successfully! It returned a \"working!\" status. Let me know if you'd like to try a specific function, pass certain arguments, or explore what's available. 😊", + message: "The tool executed successfully with the provided arguments. It processed `foo: \"test_value\"` and `bar: [\"foo\", \"bar\"]`, returning a confirmation message indicating everything is working as expected. Let me know if you'd like to explore further or adjust parameters! 🛠\u{fe0f}", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.yml b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.yml index 8da5ab423..8f31f1d8b 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning.yml @@ -19,26 +19,32 @@ when: "name": "run_me", "description": "", "parameters": { - "foo": { - "type": "string", - "default": "foo" - }, - "bar": { - "type": [ - "string", - "array" - ], - "enum": [ - "foo", - [ - "foo", - "bar" - ] - ], - "items": { - "type": "string" + "type": "object", + "properties": { + "foo": { + "type": "string", + "default": "foo" + }, + "bar": { + "type": [ + "string", + "array" + ], + "enum": [ + "foo" + ], + "items": { + "type": "string", + "enum": [ + "foo", + "bar" + ] + } } - } + }, + "required": [ + "bar" + ] } } } @@ -53,125 +59,229 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.417171Z","message":{"role":"assistant","content":"","thinking":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.526355Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.58806Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.646682Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.697072Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.748253Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.802091Z","message":{"role":"assistant","content":"","thinking":" run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.857222Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.909917Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:05.963201Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.018316Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.073808Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.129265Z","message":{"role":"assistant","content":"","thinking":" haven"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.184575Z","message":{"role":"assistant","content":"","thinking":"'t"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.239672Z","message":{"role":"assistant","content":"","thinking":" specified"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.295184Z","message":{"role":"assistant","content":"","thinking":" which"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.351412Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.407408Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.463937Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.521092Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.578735Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.636508Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.692678Z","message":{"role":"assistant","content":"","thinking":" use"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.74926Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.806879Z","message":{"role":"assistant","content":"","thinking":" Looking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.866241Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.922455Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:06.979539Z","message":{"role":"assistant","content":"","thinking":" available"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.037138Z","message":{"role":"assistant","content":"","thinking":" tools"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.095757Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.153838Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.212701Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.267646Z","message":{"role":"assistant","content":"","thinking":" only"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.325016Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.382582Z","message":{"role":"assistant","content":"","thinking":" called"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.4414Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.499371Z","message":{"role":"assistant","content":"","thinking":"run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.558093Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.618099Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.676183Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.733849Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.79196Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.850287Z","message":{"role":"assistant","content":"","thinking":" defined"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.908005Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:07.966789Z","message":{"role":"assistant","content":"","thinking":"both"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.024618Z","message":{"role":"assistant","content":"","thinking":" type"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.081875Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.13994Z","message":{"role":"assistant","content":"","thinking":" properties"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.199089Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.258098Z","message":{"role":"assistant","content":"","thinking":" empty"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.317563Z","message":{"role":"assistant","content":"","thinking":" strings"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.376171Z","message":{"role":"assistant","content":"","thinking":"/null"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.433627Z","message":{"role":"assistant","content":"","thinking":")."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.550768Z","message":{"role":"assistant","content":"","thinking":"\n\nSince"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.609237Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.667634Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.722588Z","message":{"role":"assistant","content":"","thinking":" only"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.779628Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.83646Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.894546Z","message":{"role":"assistant","content":"","thinking":" available"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:08.954142Z","message":{"role":"assistant","content":"","thinking":" (\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.012445Z","message":{"role":"assistant","content":"","thinking":"run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.071895Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.127255Z","message":{"role":"assistant","content":"","thinking":"\")"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.18403Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.241569Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.298722Z","message":{"role":"assistant","content":"","thinking":" has"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.355329Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.414206Z","message":{"role":"assistant","content":"","thinking":" required"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.472415Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.527456Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.583513Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.640055Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.698951Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.757683Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.816225Z","message":{"role":"assistant","content":"","thinking":" without"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.874965Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.933394Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:09.989579Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.046049Z","message":{"role":"assistant","content":"","thinking":" The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.103086Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.161757Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.219946Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.279174Z","message":{"role":"assistant","content":"","thinking":"pro"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.33734Z","message":{"role":"assistant","content":"","thinking":"vid"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.393395Z","message":{"role":"assistant","content":"","thinking":"ing"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.451147Z","message":{"role":"assistant","content":"","thinking":" whatever"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.508614Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.566413Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.62482Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.682496Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.739948Z","message":{"role":"assistant","content":"","thinking":" which"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.79825Z","message":{"role":"assistant","content":"","thinking":" suggests"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.857246Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.913393Z","message":{"role":"assistant","content":"","thinking":" have"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:10.969623Z","message":{"role":"assistant","content":"","thinking":" flexibility"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.02709Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.084894Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.143148Z","message":{"role":"assistant","content":"","thinking":" since"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.201788Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.254659Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.310173Z","message":{"role":"assistant","content":"","thinking":" doesn"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.365843Z","message":{"role":"assistant","content":"","thinking":"'t"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.422564Z","message":{"role":"assistant","content":"","thinking":" take"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.479598Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.537055Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.59553Z","message":{"role":"assistant","content":"","thinking":" anyway"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.654121Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.71195Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.772225Z","message":{"role":"assistant","content":"","thinking":"'ll"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.828717Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.886736Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:11.945259Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:12.003643Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:12.063115Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:12.122687Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:12.17888Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:13.154015Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_uw6k4egz","function":{"index":0,"name":"run_me","arguments":{}}}]},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:13.210919Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":24575673125,"load_duration":2394357125,"prompt_eval_count":251,"prompt_eval_duration":1102578667,"eval_count":136,"eval_duration":7550308832} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.305735Z","message":{"role":"assistant","content":"","thinking":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.329988Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.352365Z","message":{"role":"assistant","content":"","thinking":" wants"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.375627Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.398722Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.422038Z","message":{"role":"assistant","content":"","thinking":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.444583Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.467537Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.490897Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.513253Z","message":{"role":"assistant","content":"","thinking":" hasn"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.536737Z","message":{"role":"assistant","content":"","thinking":"'t"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.559942Z","message":{"role":"assistant","content":"","thinking":" specified"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.583249Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.605936Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.628765Z","message":{"role":"assistant","content":"","thinking":" they"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.651161Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.674455Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.697919Z","message":{"role":"assistant","content":"","thinking":" use"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.721342Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.743938Z","message":{"role":"assistant","content":"","thinking":" Looking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.76693Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.790327Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.813306Z","message":{"role":"assistant","content":"","thinking":" available"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.836176Z","message":{"role":"assistant","content":"","thinking":" tools"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.85919Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.882674Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.905781Z","message":{"role":"assistant","content":"","thinking":" see"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.929238Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.952774Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.976337Z","message":{"role":"assistant","content":"","thinking":" only"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:09.999643Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.023141Z","message":{"role":"assistant","content":"","thinking":" called"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.046478Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.069853Z","message":{"role":"assistant","content":"","thinking":"run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.093409Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.116876Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.139678Z","message":{"role":"assistant","content":"","thinking":" which"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.162263Z","message":{"role":"assistant","content":"","thinking":" has"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.185934Z","message":{"role":"assistant","content":"","thinking":" these"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.209065Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.232756Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.279773Z","message":{"role":"assistant","content":"","thinking":"\n\n-"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.303136Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.326721Z","message":{"role":"assistant","content":"","thinking":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.350319Z","message":{"role":"assistant","content":"","thinking":"`:"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.373691Z","message":{"role":"assistant","content":"","thinking":" required"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.396538Z","message":{"role":"assistant","content":"","thinking":" parameter"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.420166Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.443938Z","message":{"role":"assistant","content":"","thinking":" type"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.467466Z","message":{"role":"assistant","content":"","thinking":" [\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.491267Z","message":{"role":"assistant","content":"","thinking":"string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.514733Z","message":{"role":"assistant","content":"","thinking":"\","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.538673Z","message":{"role":"assistant","content":"","thinking":" array"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.562024Z","message":{"role":"assistant","content":"","thinking":"]"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.586054Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.609367Z","message":{"role":"assistant","content":"","thinking":" enum"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.633156Z","message":{"role":"assistant","content":"","thinking":" values"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.656426Z","message":{"role":"assistant","content":"","thinking":" [\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.680152Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.703763Z","message":{"role":"assistant","content":"","thinking":"\"]"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.727335Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.749952Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.772958Z","message":{"role":"assistant","content":"","thinking":" seems"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.795862Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.818919Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.842596Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.865869Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.889682Z","message":{"role":"assistant","content":"","thinking":" either"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.912915Z","message":{"role":"assistant","content":"","thinking":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.936554Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:10.959954Z","message":{"role":"assistant","content":"","thinking":" array"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.007072Z","message":{"role":"assistant","content":"","thinking":"\n-"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.030588Z","message":{"role":"assistant","content":"","thinking":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.054188Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.077659Z","message":{"role":"assistant","content":"","thinking":"`:"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.101183Z","message":{"role":"assistant","content":"","thinking":" optional"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.124713Z","message":{"role":"assistant","content":"","thinking":" parameter"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.148006Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.171372Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.194835Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.217943Z","message":{"role":"assistant","content":"","thinking":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.240709Z","message":{"role":"assistant","content":"","thinking":" type"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.287522Z","message":{"role":"assistant","content":"","thinking":"\n\nSince"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.310663Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.334377Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.357688Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.381327Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.404507Z","message":{"role":"assistant","content":"","thinking":" provide"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.428135Z","message":{"role":"assistant","content":"","thinking":" whatever"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.451576Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.475194Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.49877Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.521887Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.545613Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.569091Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.591877Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.615108Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.638713Z","message":{"role":"assistant","content":"","thinking":" requirement"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.661848Z","message":{"role":"assistant","content":"","thinking":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.685455Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.70865Z","message":{"role":"assistant","content":"","thinking":" least"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.732374Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.755573Z","message":{"role":"assistant","content":"","thinking":" argument"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.77924Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.802308Z","message":{"role":"assistant","content":"","thinking":"the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.826152Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.849593Z","message":{"role":"assistant","content":"","thinking":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.873144Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.895977Z","message":{"role":"assistant","content":"","thinking":" parameter"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.919136Z","message":{"role":"assistant","content":"","thinking":"),"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.942844Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.966046Z","message":{"role":"assistant","content":"","thinking":" looking"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:11.989775Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.012997Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.03664Z","message":{"role":"assistant","content":"","thinking":" constraints"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.059925Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.106825Z","message":{"role":"assistant","content":"","thinking":"\n-"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.130545Z","message":{"role":"assistant","content":"","thinking":" bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.153826Z","message":{"role":"assistant","content":"","thinking":" must"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.177503Z","message":{"role":"assistant","content":"","thinking":" have"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.200727Z","message":{"role":"assistant","content":"","thinking":" enum"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.224318Z","message":{"role":"assistant","content":"","thinking":" value"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.247863Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.271442Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.29499Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.318253Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.342054Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.365183Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.388865Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.412048Z","message":{"role":"assistant","content":"","thinking":" using"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.435708Z","message":{"role":"assistant","content":"","thinking":" those"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.458963Z","message":{"role":"assistant","content":"","thinking":" values"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.505099Z","message":{"role":"assistant","content":"","thinking":"\n-"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.52876Z","message":{"role":"assistant","content":"","thinking":" foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.552372Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.575888Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.599466Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.622942Z","message":{"role":"assistant","content":"","thinking":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.669453Z","message":{"role":"assistant","content":"","thinking":"\n\nI"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.693041Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.716405Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.740095Z","message":{"role":"assistant","content":"","thinking":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.763391Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.787276Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.810607Z","message":{"role":"assistant","content":"","thinking":" some"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.834308Z","message":{"role":"assistant","content":"","thinking":" valid"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.857438Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.880896Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.903459Z","message":{"role":"assistant","content":"","thinking":" Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.926977Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.950457Z","message":{"role":"assistant","content":"","thinking":" make"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.973617Z","message":{"role":"assistant","content":"","thinking":" sure"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:12.996458Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.019926Z","message":{"role":"assistant","content":"","thinking":" meet"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.04351Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.066841Z","message":{"role":"assistant","content":"","thinking":" required"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.089825Z","message":{"role":"assistant","content":"","thinking":" constraint"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.113007Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.136658Z","message":{"role":"assistant","content":"","thinking":" bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.159826Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.183616Z","message":{"role":"assistant","content":"","thinking":" provided"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.206817Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.23051Z","message":{"role":"assistant","content":"","thinking":" so"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.253638Z","message":{"role":"assistant","content":"","thinking":" either"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.277159Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.300001Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.323593Z","message":{"role":"assistant","content":"","thinking":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.34727Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.370639Z","message":{"role":"assistant","content":"","thinking":" array"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.394384Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.417626Z","message":{"role":"assistant","content":"","thinking":" containing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.440474Z","message":{"role":"assistant","content":"","thinking":" appropriate"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.463123Z","message":{"role":"assistant","content":"","thinking":" values"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.486168Z","message":{"role":"assistant","content":"","thinking":" based"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.509055Z","message":{"role":"assistant","content":"","thinking":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.531999Z","message":{"role":"assistant","content":"","thinking":" what"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.555034Z","message":{"role":"assistant","content":"","thinking":" seems"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.5783Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.601659Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.62528Z","message":{"role":"assistant","content":"","thinking":" expected"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.648884Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.672688Z","message":{"role":"assistant","content":"","thinking":"likely"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.696751Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.72066Z","message":{"role":"assistant","content":"","thinking":" [\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.744419Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.767808Z","message":{"role":"assistant","content":"","thinking":"\"]"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.791461Z","message":{"role":"assistant","content":"","thinking":" since"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.814675Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.83827Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.860915Z","message":{"role":"assistant","content":"","thinking":" in"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.884459Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.907599Z","message":{"role":"assistant","content":"","thinking":" enum"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.930953Z","message":{"role":"assistant","content":"","thinking":")."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.975714Z","message":{"role":"assistant","content":"","thinking":"\n\nLet"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:13.999034Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.02217Z","message":{"role":"assistant","content":"","thinking":" provide"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.045746Z","message":{"role":"assistant","content":"","thinking":" reasonable"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.069137Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.092023Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.115177Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.138747Z","message":{"role":"assistant","content":"","thinking":"'ll"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.161978Z","message":{"role":"assistant","content":"","thinking":" use"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.186548Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.209757Z","message":{"role":"assistant","content":"","thinking":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.233382Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.256559Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.280274Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.303675Z","message":{"role":"assistant","content":"","thinking":" array"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.327103Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.350701Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.374219Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.396949Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.420302Z","message":{"role":"assistant","content":"","thinking":" value"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.443904Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.467493Z","message":{"role":"assistant","content":"","thinking":" maybe"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.490332Z","message":{"role":"assistant","content":"","thinking":" include"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.513423Z","message":{"role":"assistant","content":"","thinking":" some"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.537082Z","message":{"role":"assistant","content":"","thinking":" foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.560257Z","message":{"role":"assistant","content":"","thinking":" parameter"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.583686Z","message":{"role":"assistant","content":"","thinking":" too"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:14.607516Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:15.694786Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_bealytbj","function":{"index":0,"name":"run_me","arguments":{"foo":"test_value","bar":["foo","bar"]}}}]},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:15.717685Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":27542723792,"load_duration":7034315458,"prompt_eval_count":304,"prompt_eval_duration":730500000,"eval_count":276,"eval_duration":6411851000} --- when: path: /api/chat @@ -190,7 +300,7 @@ when: "role": "assistant", "content": "", "tool_calls": [], - "thinking": "The user is asking me to run a tool, but they haven't specified which tool or what arguments I should use. Looking at the available tools, there's only one called \"run_me\" with no parameters defined (both type and properties are empty strings/null).\n\nSince there's only one tool available (\"run_me\") and it has no required parameters, I can call it without any arguments. The user said \"providing whatever arguments you want\" which suggests I have flexibility, but since this tool doesn't take any parameters anyway, I'll just call it with no arguments." + "thinking": "The user wants me to run a tool but hasn't specified what parameters they want to use. Looking at the available tools, I see there's only one called \"run_me\" which has these parameters:\n\n- `bar`: required parameter of type [\"string\", array] with enum values [\"foo\"] - this seems like it can be either string or array\n- `foo`: optional parameter that is a string type\n\nSince the user said to provide whatever arguments I want, but there's a requirement for at least one argument (the \"bar\" parameter), and looking at the constraints:\n- bar must have enum value of \"foo\" if it's using those values\n- foo can be any string\n\nI should call run_me with some valid parameters. Let me make sure I meet the required constraint that bar is provided, so either as a string or array but containing appropriate values based on what seems to be expected (likely just [\"foo\"] since that's in the enum).\n\nLet me provide reasonable arguments - I'll use \"bar\" as an array with \"foo\" value and maybe include some foo parameter too." }, { "role": "assistant", @@ -199,7 +309,13 @@ when: { "function": { "name": "run_me", - "arguments": {} + "arguments": { + "foo": "test_value", + "bar": [ + "foo", + "bar" + ] + } } } ], @@ -222,41 +338,60 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.908549Z","message":{"role":"assistant","content":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.948074Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:47.986396Z","message":{"role":"assistant","content":" executed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.024179Z","message":{"role":"assistant","content":" successfully"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.063184Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.100116Z","message":{"role":"assistant","content":" It"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.13768Z","message":{"role":"assistant","content":" returned"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.173994Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.21176Z","message":{"role":"assistant","content":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.249519Z","message":{"role":"assistant","content":"working"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.286575Z","message":{"role":"assistant","content":"!\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.323737Z","message":{"role":"assistant","content":" status"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.36108Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.397676Z","message":{"role":"assistant","content":" Let"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.433724Z","message":{"role":"assistant","content":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.471698Z","message":{"role":"assistant","content":" know"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.509422Z","message":{"role":"assistant","content":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.546861Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.583997Z","message":{"role":"assistant","content":"'d"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.621495Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.659359Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.696926Z","message":{"role":"assistant","content":" try"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.734585Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.772726Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.809062Z","message":{"role":"assistant","content":" function"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.845764Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.883383Z","message":{"role":"assistant","content":" pass"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.920689Z","message":{"role":"assistant","content":" certain"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.957778Z","message":{"role":"assistant","content":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:48.995411Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.033457Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.070833Z","message":{"role":"assistant","content":" explore"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.108413Z","message":{"role":"assistant","content":" what"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.146049Z","message":{"role":"assistant","content":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.183208Z","message":{"role":"assistant","content":" available"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.221062Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.295902Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:49.333544Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":36119863291,"load_duration":109119375,"prompt_eval_count":58,"prompt_eval_duration":246789208,"eval_count":39,"eval_duration":1366582209} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.969186Z","message":{"role":"assistant","content":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:44.993896Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.018057Z","message":{"role":"assistant","content":" executed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.04177Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.065569Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.089728Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.113256Z","message":{"role":"assistant","content":" provided"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.137004Z","message":{"role":"assistant","content":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.160379Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.183921Z","message":{"role":"assistant","content":" It"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.206876Z","message":{"role":"assistant","content":" processed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.230701Z","message":{"role":"assistant","content":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.253794Z","message":{"role":"assistant","content":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.277337Z","message":{"role":"assistant","content":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.30039Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.324076Z","message":{"role":"assistant","content":"test"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.34705Z","message":{"role":"assistant","content":"_value"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.370661Z","message":{"role":"assistant","content":"\"`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.393695Z","message":{"role":"assistant","content":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.417499Z","message":{"role":"assistant","content":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.440777Z","message":{"role":"assistant","content":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.463864Z","message":{"role":"assistant","content":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.48689Z","message":{"role":"assistant","content":" [\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.509944Z","message":{"role":"assistant","content":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.533541Z","message":{"role":"assistant","content":"\","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.556693Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.580246Z","message":{"role":"assistant","content":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.60297Z","message":{"role":"assistant","content":"\"]"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.626788Z","message":{"role":"assistant","content":"`,"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.650024Z","message":{"role":"assistant","content":" returning"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.673773Z","message":{"role":"assistant","content":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.697047Z","message":{"role":"assistant","content":" confirmation"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.720822Z","message":{"role":"assistant","content":" message"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.744121Z","message":{"role":"assistant","content":" indicating"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.767835Z","message":{"role":"assistant","content":" everything"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.791182Z","message":{"role":"assistant","content":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.8142Z","message":{"role":"assistant","content":" working"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.838089Z","message":{"role":"assistant","content":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.861186Z","message":{"role":"assistant","content":" expected"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.884821Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.907781Z","message":{"role":"assistant","content":" Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.930832Z","message":{"role":"assistant","content":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.953484Z","message":{"role":"assistant","content":" know"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.976649Z","message":{"role":"assistant","content":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:45.999204Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.02256Z","message":{"role":"assistant","content":"'d"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.045852Z","message":{"role":"assistant","content":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.069399Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.091793Z","message":{"role":"assistant","content":" explore"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.114594Z","message":{"role":"assistant","content":" further"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.138049Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.161084Z","message":{"role":"assistant","content":" adjust"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.184468Z","message":{"role":"assistant","content":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.20697Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.276242Z","message":{"role":"assistant","content":" 🛠"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.29906Z","message":{"role":"assistant","content":"️"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:46.322588Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":30597593583,"load_duration":209336708,"prompt_eval_count":87,"prompt_eval_duration":285646000,"eval_count":59,"eval_duration":1353341000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__conversation_stream.snap index 99fb25973..962ca15be 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__conversation_stream.snap @@ -237,14 +237,20 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "reasoning": "The user is asking me to run a tool, but they haven't specified which tool or what arguments I should use. Looking at the available tools, there's only one called \"run_me\" with no parameters defined (both type and properties are empty strings/null).\n\nSince there's only one tool available (\"run_me\") and it has no required parameters, I can call it without any arguments. The user said \"providing whatever arguments you want\" which suggests I have flexibility, but since this tool doesn't take any parameters anyway, I'll just call it with no arguments." + "reasoning": "The user wants me to run a tool but hasn't specified what parameters they want to use. Looking at the available tools, I see there's only one called \"run_me\" which has these parameters:\n\n- `bar`: required parameter of type [\"string\", array] with enum values [\"foo\"] - this seems like it can be either string or array\n- `foo`: optional parameter that is a string type\n\nSince the user said to provide whatever arguments I want, but there's a requirement for at least one argument (the \"bar\" parameter), and looking at the constraints:\n- bar must have enum value of \"foo\" if it's using those values\n- foo can be any string\n\nI should call run_me with some valid parameters. Let me make sure I meet the required constraint that bar is provided, so either as a string or array but containing appropriate values based on what seems to be expected (likely just [\"foo\"] since that's in the enum).\n\nLet me provide reasonable arguments - I'll use \"bar\" as an array with \"foo\" value and maybe include some foo parameter too." }, { "timestamp": "2020-01-01 00:00:00.0", "type": "tool_call_request", "id": "run_me_2", "name": "run_me", - "arguments": {} + "arguments": { + "foo": "dGVzdF92YWx1ZQ==", + "bar": [ + "Zm9v", + "YmFy" + ] + } }, { "type": "config_delta", @@ -269,7 +275,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "The tool executed successfully! It returned a \"working!\" status. Let me know if you'd like to try a specific function, pass certain arguments, or explore what's available. 😊" + "message": "The tool executed successfully with the provided arguments. It processed `foo: \"test_value\"` and `bar: [\"foo\", \"bar\"]`, returning a confirmation message indicating everything is working as expected. Let me know if you'd like to explore further or adjust parameters! 🛠️" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__raw_events.snap index f7cf5b2a1..b2b8f4259 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_reasoning__raw_events.snap @@ -18,6 +18,538 @@ expression: v ), metadata: {}, }, + Part { + index: 0, + part: Reasoning( + " wants", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " run", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " but", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " hasn", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'t", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " specified", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " what", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " parameters", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " they", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " want", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " use", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " Looking", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " at", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " available", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " tools", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " see", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " there", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'s", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " only", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " one", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " called", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "run", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "_me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " which", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " has", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " these", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " parameters", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\n-", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " `", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "bar", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "`:", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " required", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " parameter", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " of", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " type", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " [\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "string", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " array", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "]", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " with", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " enum", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " values", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " [\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "foo", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\"]", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " -", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " this", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " seems", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " like", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " it", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " can", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " be", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " either", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " string", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " or", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " array", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n-", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " `", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "foo", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "`:", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " optional", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " parameter", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " that", + ), + metadata: {}, + }, Part { index: 0, part: Reasoning( @@ -28,14 +560,49 @@ expression: v Part { index: 0, part: Reasoning( - " asking", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " me", + " string", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " type", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\nSince", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " user", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " said", ), metadata: {}, }, @@ -49,21 +616,35 @@ expression: v Part { index: 0, part: Reasoning( - " run", + " provide", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " a", + " whatever", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + " arguments", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " want", ), metadata: {}, }, @@ -84,98 +665,126 @@ expression: v Part { index: 0, part: Reasoning( - " they", + " there", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " haven", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'t", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " specified", + " requirement", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " which", + " for", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + " at", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " or", + " least", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " what", + " one", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " arguments", + " argument", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " should", + "the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " use", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "bar", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Looking", + "\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " parameter", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "),", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " and", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " looking", ), metadata: {}, }, @@ -189,91 +798,210 @@ expression: v Part { index: 0, part: Reasoning( - " the", + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " constraints", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ":", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n-", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " bar", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " must", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " have", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " enum", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " value", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " of", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " \"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "foo", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " if", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " it", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'s", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " using", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " those", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " available", + " values", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tools", + "\n-", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " foo", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " there", + " can", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " be", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " only", + " any", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " one", + " string", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " called", + "\n\nI", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " should", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "run", + " call", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "_me", + " run", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + "_me", ), metadata: {}, }, @@ -287,532 +1015,532 @@ expression: v Part { index: 0, part: Reasoning( - " no", + " some", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " parameters", + " valid", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " defined", + " parameters", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " (", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "both", + " Let", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " type", + " me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " and", + " make", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " properties", + " sure", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " are", + " I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " empty", + " meet", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " strings", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "/null", + " required", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ").", + " constraint", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nSince", + " that", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " there", + " bar", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " only", + " provided", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " one", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + " so", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " available", + " either", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " (\"", + " as", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "run", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "_me", + " string", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\")", + " or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " and", + " array", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + " but", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " has", + " containing", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " no", + " appropriate", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " required", + " values", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " parameters", + " based", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + " on", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " what", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " can", + " seems", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " call", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + " be", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " without", + " expected", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " any", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " arguments", + "likely", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " just", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " The", + " [\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + "foo", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " said", + "\"]", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " since", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "pro", + " that", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "vid", + "'s", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "ing", + " in", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " whatever", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " arguments", + " enum", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " you", + ").", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " want", + "\n\nLet", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\"", + " me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " which", + " provide", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " suggests", + " reasonable", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " arguments", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " have", + " -", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " flexibility", + " I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + "'ll", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " but", + " use", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " since", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " this", + "bar", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + "\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " doesn", + " as", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'t", + " an", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " take", + " array", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " any", + " with", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " parameters", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " anyway", + "foo", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + "\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " value", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'ll", + " and", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " just", + " maybe", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " call", + " include", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " it", + " some", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " with", + " foo", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " no", + " parameter", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " arguments", + " too", ), metadata: {}, }, @@ -841,7 +1569,7 @@ expression: v index: 2, part: ToolCall( ArgumentChunk( - "{}", + "{\"foo\":\"test_value\",\"bar\":[\"foo\",\"bar\"]}", ), ), metadata: {}, @@ -894,7 +1622,35 @@ expression: v Part { index: 1, part: Message( - "!", + " with", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " the", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " provided", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " arguments", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ".", ), metadata: {}, }, @@ -908,14 +1664,28 @@ expression: v Part { index: 1, part: Message( - " returned", + " processed", ), metadata: {}, }, Part { index: 1, part: Message( - " a", + " `", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "foo", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ":", ), metadata: {}, }, @@ -929,91 +1699,105 @@ expression: v Part { index: 1, part: Message( - "working", + "test", ), metadata: {}, }, Part { index: 1, part: Message( - "!\"", + "_value", ), metadata: {}, }, Part { index: 1, part: Message( - " status", + "\"`", ), metadata: {}, }, Part { index: 1, part: Message( - ".", + " and", ), metadata: {}, }, Part { index: 1, part: Message( - " Let", + " `", ), metadata: {}, }, Part { index: 1, part: Message( - " me", + "bar", ), metadata: {}, }, Part { index: 1, part: Message( - " know", + ":", ), metadata: {}, }, Part { index: 1, part: Message( - " if", + " [\"", ), metadata: {}, }, Part { index: 1, part: Message( - " you", + "foo", ), metadata: {}, }, Part { index: 1, part: Message( - "'d", + "\",", ), metadata: {}, }, Part { index: 1, part: Message( - " like", + " \"", ), metadata: {}, }, Part { index: 1, part: Message( - " to", + "bar", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "\"]", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "`,", ), metadata: {}, }, Part { index: 1, part: Message( - " try", + " returning", ), metadata: {}, }, @@ -1027,56 +1811,119 @@ expression: v Part { index: 1, part: Message( - " specific", + " confirmation", ), metadata: {}, }, Part { index: 1, part: Message( - " function", + " message", ), metadata: {}, }, Part { index: 1, part: Message( - ",", + " indicating", ), metadata: {}, }, Part { index: 1, part: Message( - " pass", + " everything", ), metadata: {}, }, Part { index: 1, part: Message( - " certain", + " is", ), metadata: {}, }, Part { index: 1, part: Message( - " arguments", + " working", ), metadata: {}, }, Part { index: 1, part: Message( - ",", + " as", ), metadata: {}, }, Part { index: 1, part: Message( - " or", + " expected", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + ".", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " Let", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " me", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " know", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " if", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " you", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "'d", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " like", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " to", ), metadata: {}, }, @@ -1090,35 +1937,49 @@ expression: v Part { index: 1, part: Message( - " what", + " further", ), metadata: {}, }, Part { index: 1, part: Message( - "'s", + " or", ), metadata: {}, }, Part { index: 1, part: Message( - " available", + " adjust", ), metadata: {}, }, Part { index: 1, part: Message( - ".", + " parameters", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + "!", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " 🛠", ), metadata: {}, }, Part { index: 1, part: Message( - " 😊", + "\u{fe0f}", ), metadata: {}, }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.snap index f371b8edd..e44e690d6 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.snap @@ -11,7 +11,13 @@ expression: v ToolCallRequest { id: "run_me_2", name: "run_me", - arguments: {}, + arguments: { + "bar": Array [ + String("foo"), + String("bar"), + ], + "foo": String("random_string_12345"), + }, }, ), metadata: {}, @@ -27,7 +33,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "It looks like the tool executed successfully and returned `working!`. Since I wasn't able to see the specific output of the tool, could you provide more details or let me know what kind of task you'd like it to perform? For example, if you want to run a mathematical calculation, analyze data, or interact with an API, please specify the arguments or context you need.", + message: "The tool has been executed successfully with the arguments `{\"bar\": [\"foo\", \"bar\"], \"foo\": \"random_string_12345\"}`. \n\nLet me know if you'd like to run another iteration or try something else! 😊", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.yml b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.yml index 4d26de43c..865c22e26 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning.yml @@ -25,26 +25,32 @@ when: "name": "run_me", "description": "", "parameters": { - "foo": { - "type": "string", - "default": "foo" - }, - "bar": { - "type": [ - "string", - "array" - ], - "enum": [ - "foo", - [ - "foo", - "bar" - ] - ], - "items": { - "type": "string" + "type": "object", + "properties": { + "foo": { + "type": "string", + "default": "foo" + }, + "bar": { + "type": [ + "string", + "array" + ], + "enum": [ + "foo" + ], + "items": { + "type": "string", + "enum": [ + "foo", + "bar" + ] + } } - } + }, + "required": [ + "bar" + ] } } } @@ -59,8 +65,8 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:17.509836Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_rjbc0unz","function":{"index":0,"name":"run_me","arguments":{}}}]},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:17.548003Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":28774142208,"load_duration":2255761875,"prompt_eval_count":293,"prompt_eval_duration":1107964500,"eval_count":15,"eval_duration":501349250} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:19.717734Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_uqdy6jw7","function":{"index":0,"name":"run_me","arguments":{"bar":["foo","bar"],"foo":"random_string_12345"}}}]},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:19.740894Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":31565681708,"load_duration":7034939083,"prompt_eval_count":346,"prompt_eval_duration":222935000,"eval_count":51,"eval_duration":1158802000} --- when: path: /api/chat @@ -82,7 +88,13 @@ when: { "function": { "name": "run_me", - "arguments": {} + "arguments": { + "bar": [ + "foo", + "bar" + ], + "foo": "random_string_12345" + } } } ], @@ -105,81 +117,55 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.760733Z","message":{"role":"assistant","content":"It"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.798722Z","message":{"role":"assistant","content":" looks"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.835815Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.873632Z","message":{"role":"assistant","content":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.90991Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.947433Z","message":{"role":"assistant","content":" executed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:50.984743Z","message":{"role":"assistant","content":" successfully"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.022269Z","message":{"role":"assistant","content":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.059864Z","message":{"role":"assistant","content":" returned"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.09741Z","message":{"role":"assistant","content":" `"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.134896Z","message":{"role":"assistant","content":"working"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.172464Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.2103Z","message":{"role":"assistant","content":"`."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.247981Z","message":{"role":"assistant","content":" Since"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.28506Z","message":{"role":"assistant","content":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.322529Z","message":{"role":"assistant","content":" wasn"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.360913Z","message":{"role":"assistant","content":"'t"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.398113Z","message":{"role":"assistant","content":" able"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.435537Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.473043Z","message":{"role":"assistant","content":" see"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.510504Z","message":{"role":"assistant","content":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.548089Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.585612Z","message":{"role":"assistant","content":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.623259Z","message":{"role":"assistant","content":" of"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.660992Z","message":{"role":"assistant","content":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.698653Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.736284Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.773317Z","message":{"role":"assistant","content":" could"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.811612Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.84916Z","message":{"role":"assistant","content":" provide"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.886693Z","message":{"role":"assistant","content":" more"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.924384Z","message":{"role":"assistant","content":" details"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.961853Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:51.998962Z","message":{"role":"assistant","content":" let"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.034777Z","message":{"role":"assistant","content":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.071947Z","message":{"role":"assistant","content":" know"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.108945Z","message":{"role":"assistant","content":" what"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.146294Z","message":{"role":"assistant","content":" kind"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.183805Z","message":{"role":"assistant","content":" of"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.221171Z","message":{"role":"assistant","content":" task"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.258726Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.296229Z","message":{"role":"assistant","content":"'d"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.33368Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.370756Z","message":{"role":"assistant","content":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.408234Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.445868Z","message":{"role":"assistant","content":" perform"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.484325Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.521943Z","message":{"role":"assistant","content":" For"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.560193Z","message":{"role":"assistant","content":" example"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.597874Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.635557Z","message":{"role":"assistant","content":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.673572Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.711791Z","message":{"role":"assistant","content":" want"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.749183Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.786673Z","message":{"role":"assistant","content":" run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.824243Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.861888Z","message":{"role":"assistant","content":" mathematical"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.898714Z","message":{"role":"assistant","content":" calculation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.935576Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:52.972561Z","message":{"role":"assistant","content":" analyze"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.009903Z","message":{"role":"assistant","content":" data"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.047559Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.084779Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.122432Z","message":{"role":"assistant","content":" interact"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.160069Z","message":{"role":"assistant","content":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.197783Z","message":{"role":"assistant","content":" an"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.235378Z","message":{"role":"assistant","content":" API"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.272887Z","message":{"role":"assistant","content":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.30989Z","message":{"role":"assistant","content":" please"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.347282Z","message":{"role":"assistant","content":" specify"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.385521Z","message":{"role":"assistant","content":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.421346Z","message":{"role":"assistant","content":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.458744Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.495605Z","message":{"role":"assistant","content":" context"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.532648Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.570037Z","message":{"role":"assistant","content":" need"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.607303Z","message":{"role":"assistant","content":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.644408Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":36091272042,"load_duration":118492208,"prompt_eval_count":53,"prompt_eval_duration":244232958,"eval_count":78,"eval_duration":2765459794} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.824041Z","message":{"role":"assistant","content":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.848748Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.871953Z","message":{"role":"assistant","content":" has"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.895453Z","message":{"role":"assistant","content":" been"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.918713Z","message":{"role":"assistant","content":" executed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.941945Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.964916Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:47.988365Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.011519Z","message":{"role":"assistant","content":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.035048Z","message":{"role":"assistant","content":" `"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.058181Z","message":{"role":"assistant","content":"{\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.081349Z","message":{"role":"assistant","content":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.103952Z","message":{"role":"assistant","content":"\":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.127456Z","message":{"role":"assistant","content":" [\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.150822Z","message":{"role":"assistant","content":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.174281Z","message":{"role":"assistant","content":"\","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.19773Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.221004Z","message":{"role":"assistant","content":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.244736Z","message":{"role":"assistant","content":"\"],"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.268417Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.292087Z","message":{"role":"assistant","content":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.315527Z","message":{"role":"assistant","content":"\":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.339298Z","message":{"role":"assistant","content":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.362549Z","message":{"role":"assistant","content":"random"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.386201Z","message":{"role":"assistant","content":"_string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.40942Z","message":{"role":"assistant","content":"_"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.433143Z","message":{"role":"assistant","content":"1"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.456409Z","message":{"role":"assistant","content":"2"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.480128Z","message":{"role":"assistant","content":"3"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.503321Z","message":{"role":"assistant","content":"4"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.527014Z","message":{"role":"assistant","content":"5"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.549869Z","message":{"role":"assistant","content":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.573454Z","message":{"role":"assistant","content":"}`"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.597107Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.643333Z","message":{"role":"assistant","content":" \n\nLet"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.666325Z","message":{"role":"assistant","content":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.690061Z","message":{"role":"assistant","content":" know"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.713184Z","message":{"role":"assistant","content":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.736849Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.760107Z","message":{"role":"assistant","content":"'d"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.78372Z","message":{"role":"assistant","content":" like"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.806862Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.83036Z","message":{"role":"assistant","content":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.853929Z","message":{"role":"assistant","content":" another"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.877704Z","message":{"role":"assistant","content":" iteration"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.900981Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.924635Z","message":{"role":"assistant","content":" try"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.948202Z","message":{"role":"assistant","content":" something"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.971822Z","message":{"role":"assistant","content":" else"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:48.995385Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.042246Z","message":{"role":"assistant","content":" 😊"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:49.065577Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":29319267458,"load_duration":212525333,"prompt_eval_count":88,"prompt_eval_duration":278663000,"eval_count":54,"eval_duration":1241487000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__conversation_stream.snap index b0cb9fcb5..442d32abf 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__conversation_stream.snap @@ -223,7 +223,13 @@ expression: v "type": "tool_call_request", "id": "run_me_2", "name": "run_me", - "arguments": {} + "arguments": { + "bar": [ + "Zm9v", + "YmFy" + ], + "foo": "cmFuZG9tX3N0cmluZ18xMjM0NQ==" + } }, { "timestamp": "2020-01-01 00:00:00.0", @@ -235,7 +241,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "It looks like the tool executed successfully and returned `working!`. Since I wasn't able to see the specific output of the tool, could you provide more details or let me know what kind of task you'd like it to perform? For example, if you want to run a mathematical calculation, analyze data, or interact with an API, please specify the arguments or context you need." + "message": "The tool has been executed successfully with the arguments `{\"bar\": [\"foo\", \"bar\"], \"foo\": \"random_string_12345\"}`. \n\nLet me know if you'd like to run another iteration or try something else! 😊" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__raw_events.snap index 70b277e17..72913eeee 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_no_reasoning__raw_events.snap @@ -22,7 +22,7 @@ expression: v index: 2, part: ToolCall( ArgumentChunk( - "{}", + "{\"bar\":[\"foo\",\"bar\"],\"foo\":\"random_string_12345\"}", ), ), metadata: {}, @@ -47,35 +47,28 @@ expression: v Part { index: 1, part: Message( - "It", + "The", ), metadata: {}, }, Part { index: 1, part: Message( - " looks", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " like", + " tool", ), metadata: {}, }, Part { index: 1, part: Message( - " the", + " has", ), metadata: {}, }, Part { index: 1, part: Message( - " tool", + " been", ), metadata: {}, }, @@ -96,231 +89,224 @@ expression: v Part { index: 1, part: Message( - " and", + " with", ), metadata: {}, }, Part { index: 1, part: Message( - " returned", + " the", ), metadata: {}, }, Part { index: 1, part: Message( - " `", + " arguments", ), metadata: {}, }, Part { index: 1, part: Message( - "working", + " `", ), metadata: {}, }, Part { index: 1, part: Message( - "!", + "{\"", ), metadata: {}, }, Part { index: 1, part: Message( - "`.", + "bar", ), metadata: {}, }, Part { index: 1, part: Message( - " Since", + "\":", ), metadata: {}, }, Part { index: 1, part: Message( - " I", + " [\"", ), metadata: {}, }, Part { index: 1, part: Message( - " wasn", + "foo", ), metadata: {}, }, Part { index: 1, part: Message( - "'t", + "\",", ), metadata: {}, }, Part { index: 1, part: Message( - " able", + " \"", ), metadata: {}, }, Part { index: 1, part: Message( - " to", + "bar", ), metadata: {}, }, Part { index: 1, part: Message( - " see", + "\"],", ), metadata: {}, }, Part { index: 1, part: Message( - " the", + " \"", ), metadata: {}, }, Part { index: 1, part: Message( - " specific", + "foo", ), metadata: {}, }, Part { index: 1, part: Message( - " output", + "\":", ), metadata: {}, }, Part { index: 1, part: Message( - " of", + " \"", ), metadata: {}, }, Part { index: 1, part: Message( - " the", + "random", ), metadata: {}, }, Part { index: 1, part: Message( - " tool", + "_string", ), metadata: {}, }, Part { index: 1, part: Message( - ",", + "_", ), metadata: {}, }, Part { index: 1, part: Message( - " could", + "1", ), metadata: {}, }, Part { index: 1, part: Message( - " you", + "2", ), metadata: {}, }, Part { index: 1, part: Message( - " provide", + "3", ), metadata: {}, }, Part { index: 1, part: Message( - " more", + "4", ), metadata: {}, }, Part { index: 1, part: Message( - " details", + "5", ), metadata: {}, }, Part { index: 1, part: Message( - " or", + "\"", ), metadata: {}, }, Part { index: 1, part: Message( - " let", + "}`", ), metadata: {}, }, Part { index: 1, part: Message( - " me", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " know", + ".", ), metadata: {}, }, Part { index: 1, part: Message( - " what", + " \n\nLet", ), metadata: {}, }, Part { index: 1, part: Message( - " kind", + " me", ), metadata: {}, }, Part { index: 1, part: Message( - " of", + " know", ), metadata: {}, }, Part { index: 1, part: Message( - " task", + " if", ), metadata: {}, }, @@ -345,76 +331,6 @@ expression: v ), metadata: {}, }, - Part { - index: 1, - part: Message( - " it", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " to", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " perform", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "?", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " For", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " example", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " if", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " you", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " want", - ), - metadata: {}, - }, Part { index: 1, part: Message( @@ -432,49 +348,14 @@ expression: v Part { index: 1, part: Message( - " a", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " mathematical", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " calculation", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", + " another", ), metadata: {}, }, Part { index: 1, part: Message( - " analyze", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " data", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", + " iteration", ), metadata: {}, }, @@ -488,98 +369,35 @@ expression: v Part { index: 1, part: Message( - " interact", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " with", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " an", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " API", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - ",", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " please", + " try", ), metadata: {}, }, Part { index: 1, part: Message( - " specify", + " something", ), metadata: {}, }, Part { index: 1, part: Message( - " the", + " else", ), metadata: {}, }, Part { index: 1, part: Message( - " arguments", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " or", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " context", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " you", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " need", + "!", ), metadata: {}, }, Part { index: 1, part: Message( - ".", + " 😊", ), metadata: {}, }, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.snap index 07c401ffa..34c089234 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.snap @@ -9,7 +9,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Reasoning { - reasoning: "The user is asking me to run a tool with whatever arguments I want. Looking at the available tools, there's only one tool called \"run_me\" which takes no parameters according to its schema. This seems like a simple tool that doesn't require any specific arguments.\n\nLet me call this tool without any parameters since it has no required parameters and the user said \"whatever arguments you want\" - I'll just use none since none are available/needed.", + reasoning: "I need to call a tool from my list of options based on the user request, which says \"Please run the tool\". I have one function called 'run_me' with these parameters:\n\n- bar (required): Can be string or array, but restricted to enum values [\"foo\", \"bar\"] - this is somewhat confusing since it can only take those two values\n- foo (optional): String type\n\nSince the user wants me to run a tool and I should use arguments if needed, let me call 'run_me' with bar=\"foo\" as an argument. This satisfies the requirement of calling at least one tool while using valid parameters according to the schema.", }, ), metadata: {}, @@ -22,7 +22,9 @@ expression: v ToolCallRequest { id: "run_me_2", name: "run_me", - arguments: {}, + arguments: { + "bar": String("foo"), + }, }, ), metadata: {}, @@ -38,7 +40,7 @@ expression: v timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "The tool has executed successfully with `working!`. Let me know if you'd like to try different arguments or explore specific functionalities! 🛠\u{fe0f}", + message: "The tool executed successfully with the arguments provided. Let me know if you need to run it again or adjust any parameters!", }, ), metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.yml b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.yml index 7fa25c88b..734b3a4d4 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning.yml @@ -25,26 +25,32 @@ when: "name": "run_me", "description": "", "parameters": { - "foo": { - "type": "string", - "default": "foo" - }, - "bar": { - "type": [ - "string", - "array" - ], - "enum": [ - "foo", - [ - "foo", - "bar" - ] - ], - "items": { - "type": "string" + "type": "object", + "properties": { + "foo": { + "type": "string", + "default": "foo" + }, + "bar": { + "type": [ + "string", + "array" + ], + "enum": [ + "foo" + ], + "items": { + "type": "string", + "enum": [ + "foo", + "bar" + ] + } } - } + }, + "required": [ + "bar" + ] } } } @@ -59,99 +65,140 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.400705Z","message":{"role":"assistant","content":"","thinking":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.438759Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.475277Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.513055Z","message":{"role":"assistant","content":"","thinking":" asking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.550791Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.58726Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.62358Z","message":{"role":"assistant","content":"","thinking":" run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.660004Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.698157Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.73499Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.772799Z","message":{"role":"assistant","content":"","thinking":" whatever"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.81079Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.847966Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.885763Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.923108Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.960788Z","message":{"role":"assistant","content":"","thinking":" Looking"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:18.999022Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.036921Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.073666Z","message":{"role":"assistant","content":"","thinking":" available"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.111525Z","message":{"role":"assistant","content":"","thinking":" tools"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.149028Z","message":{"role":"assistant","content":"","thinking":","},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.186986Z","message":{"role":"assistant","content":"","thinking":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.224994Z","message":{"role":"assistant","content":"","thinking":"'s"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.263693Z","message":{"role":"assistant","content":"","thinking":" only"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.301412Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.339255Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.377494Z","message":{"role":"assistant","content":"","thinking":" called"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.415403Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.453525Z","message":{"role":"assistant","content":"","thinking":"run"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.491773Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.529565Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.567567Z","message":{"role":"assistant","content":"","thinking":" which"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.605622Z","message":{"role":"assistant","content":"","thinking":" takes"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.643219Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.68199Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.719322Z","message":{"role":"assistant","content":"","thinking":" according"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.75702Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.793391Z","message":{"role":"assistant","content":"","thinking":" its"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.829792Z","message":{"role":"assistant","content":"","thinking":" schema"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.867112Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.905583Z","message":{"role":"assistant","content":"","thinking":" This"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.943567Z","message":{"role":"assistant","content":"","thinking":" seems"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:19.981561Z","message":{"role":"assistant","content":"","thinking":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.019484Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.057381Z","message":{"role":"assistant","content":"","thinking":" simple"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.095139Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.133117Z","message":{"role":"assistant","content":"","thinking":" that"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.17121Z","message":{"role":"assistant","content":"","thinking":" doesn"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.209036Z","message":{"role":"assistant","content":"","thinking":"'t"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.247014Z","message":{"role":"assistant","content":"","thinking":" require"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.285507Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.32227Z","message":{"role":"assistant","content":"","thinking":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.360413Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.398245Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.473994Z","message":{"role":"assistant","content":"","thinking":"\n\nLet"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.512129Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.550147Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.588029Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.626025Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.663948Z","message":{"role":"assistant","content":"","thinking":" without"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.702576Z","message":{"role":"assistant","content":"","thinking":" any"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.740454Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.778354Z","message":{"role":"assistant","content":"","thinking":" since"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.817158Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.856934Z","message":{"role":"assistant","content":"","thinking":" has"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.895058Z","message":{"role":"assistant","content":"","thinking":" no"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.93293Z","message":{"role":"assistant","content":"","thinking":" required"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:20.970534Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.008629Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.046448Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.089625Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.127536Z","message":{"role":"assistant","content":"","thinking":" said"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.165517Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.20355Z","message":{"role":"assistant","content":"","thinking":"whatever"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.241461Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.279386Z","message":{"role":"assistant","content":"","thinking":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.317293Z","message":{"role":"assistant","content":"","thinking":" want"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.355199Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.393229Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.431273Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.469829Z","message":{"role":"assistant","content":"","thinking":"'ll"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.507785Z","message":{"role":"assistant","content":"","thinking":" just"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.545798Z","message":{"role":"assistant","content":"","thinking":" use"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.583957Z","message":{"role":"assistant","content":"","thinking":" none"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.622239Z","message":{"role":"assistant","content":"","thinking":" since"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.660107Z","message":{"role":"assistant","content":"","thinking":" none"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.697945Z","message":{"role":"assistant","content":"","thinking":" are"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.741514Z","message":{"role":"assistant","content":"","thinking":" available"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.779312Z","message":{"role":"assistant","content":"","thinking":"/"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.817213Z","message":{"role":"assistant","content":"","thinking":"needed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:21.855398Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:22.506529Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_3u93b0an","function":{"index":0,"name":"run_me","arguments":{}}}]},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:22.542643Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":33618158958,"load_duration":2105102500,"prompt_eval_count":291,"prompt_eval_duration":847455750,"eval_count":110,"eval_duration":3919331790} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.174364Z","message":{"role":"assistant","content":"","thinking":"I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.199011Z","message":{"role":"assistant","content":"","thinking":" need"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.222504Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.245866Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.268414Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.291269Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.313692Z","message":{"role":"assistant","content":"","thinking":" from"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.336499Z","message":{"role":"assistant","content":"","thinking":" my"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.358281Z","message":{"role":"assistant","content":"","thinking":" list"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.381063Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.403192Z","message":{"role":"assistant","content":"","thinking":" options"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.425931Z","message":{"role":"assistant","content":"","thinking":" based"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.448598Z","message":{"role":"assistant","content":"","thinking":" on"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.471239Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.4932Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.515763Z","message":{"role":"assistant","content":"","thinking":" request"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.538939Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.562545Z","message":{"role":"assistant","content":"","thinking":" which"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.586167Z","message":{"role":"assistant","content":"","thinking":" says"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.60903Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.632233Z","message":{"role":"assistant","content":"","thinking":"Please"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.654911Z","message":{"role":"assistant","content":"","thinking":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.677967Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.700103Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.722975Z","message":{"role":"assistant","content":"","thinking":"\"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.745831Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.768247Z","message":{"role":"assistant","content":"","thinking":" have"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.791095Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.813578Z","message":{"role":"assistant","content":"","thinking":" function"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.837111Z","message":{"role":"assistant","content":"","thinking":" called"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.859686Z","message":{"role":"assistant","content":"","thinking":" '"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.88295Z","message":{"role":"assistant","content":"","thinking":"run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.905623Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.928965Z","message":{"role":"assistant","content":"","thinking":"'"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.951678Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.975033Z","message":{"role":"assistant","content":"","thinking":" these"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:21.997732Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.020665Z","message":{"role":"assistant","content":"","thinking":":"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.066296Z","message":{"role":"assistant","content":"","thinking":"\n\n-"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.088746Z","message":{"role":"assistant","content":"","thinking":" bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.111082Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.134186Z","message":{"role":"assistant","content":"","thinking":"required"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.156665Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.17951Z","message":{"role":"assistant","content":"","thinking":" Can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.201851Z","message":{"role":"assistant","content":"","thinking":" be"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.224557Z","message":{"role":"assistant","content":"","thinking":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.24739Z","message":{"role":"assistant","content":"","thinking":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.270475Z","message":{"role":"assistant","content":"","thinking":" array"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.293268Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.31625Z","message":{"role":"assistant","content":"","thinking":" but"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.339813Z","message":{"role":"assistant","content":"","thinking":" restricted"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.362962Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.386539Z","message":{"role":"assistant","content":"","thinking":" enum"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.40961Z","message":{"role":"assistant","content":"","thinking":" values"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.433137Z","message":{"role":"assistant","content":"","thinking":" [\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.45604Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.479453Z","message":{"role":"assistant","content":"","thinking":"\","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.502448Z","message":{"role":"assistant","content":"","thinking":" \""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.525816Z","message":{"role":"assistant","content":"","thinking":"bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.548274Z","message":{"role":"assistant","content":"","thinking":"\"]"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.571567Z","message":{"role":"assistant","content":"","thinking":" -"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.594964Z","message":{"role":"assistant","content":"","thinking":" this"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.618105Z","message":{"role":"assistant","content":"","thinking":" is"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.640932Z","message":{"role":"assistant","content":"","thinking":" somewhat"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.664105Z","message":{"role":"assistant","content":"","thinking":" confusing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.687798Z","message":{"role":"assistant","content":"","thinking":" since"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.710948Z","message":{"role":"assistant","content":"","thinking":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.734662Z","message":{"role":"assistant","content":"","thinking":" can"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.757877Z","message":{"role":"assistant","content":"","thinking":" only"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.781494Z","message":{"role":"assistant","content":"","thinking":" take"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.804794Z","message":{"role":"assistant","content":"","thinking":" those"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.828293Z","message":{"role":"assistant","content":"","thinking":" two"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.851661Z","message":{"role":"assistant","content":"","thinking":" values"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.898012Z","message":{"role":"assistant","content":"","thinking":"\n-"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.921511Z","message":{"role":"assistant","content":"","thinking":" foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.944905Z","message":{"role":"assistant","content":"","thinking":" ("},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.968335Z","message":{"role":"assistant","content":"","thinking":"optional"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:22.991168Z","message":{"role":"assistant","content":"","thinking":"):"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.014445Z","message":{"role":"assistant","content":"","thinking":" String"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.038121Z","message":{"role":"assistant","content":"","thinking":" type"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.084809Z","message":{"role":"assistant","content":"","thinking":"\n\nSince"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.107939Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.131352Z","message":{"role":"assistant","content":"","thinking":" user"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.154539Z","message":{"role":"assistant","content":"","thinking":" wants"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.178001Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.200866Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.224382Z","message":{"role":"assistant","content":"","thinking":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.247886Z","message":{"role":"assistant","content":"","thinking":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.271024Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.293909Z","message":{"role":"assistant","content":"","thinking":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.317175Z","message":{"role":"assistant","content":"","thinking":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.340779Z","message":{"role":"assistant","content":"","thinking":" should"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.36381Z","message":{"role":"assistant","content":"","thinking":" use"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.387509Z","message":{"role":"assistant","content":"","thinking":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.41078Z","message":{"role":"assistant","content":"","thinking":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.434439Z","message":{"role":"assistant","content":"","thinking":" needed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.457578Z","message":{"role":"assistant","content":"","thinking":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.481311Z","message":{"role":"assistant","content":"","thinking":" let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.504475Z","message":{"role":"assistant","content":"","thinking":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.528017Z","message":{"role":"assistant","content":"","thinking":" call"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.551181Z","message":{"role":"assistant","content":"","thinking":" '"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.574605Z","message":{"role":"assistant","content":"","thinking":"run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.597428Z","message":{"role":"assistant","content":"","thinking":"_me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.620885Z","message":{"role":"assistant","content":"","thinking":"'"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.643755Z","message":{"role":"assistant","content":"","thinking":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.666967Z","message":{"role":"assistant","content":"","thinking":" bar"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.690503Z","message":{"role":"assistant","content":"","thinking":"=\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.713689Z","message":{"role":"assistant","content":"","thinking":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.737366Z","message":{"role":"assistant","content":"","thinking":"\""},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.760493Z","message":{"role":"assistant","content":"","thinking":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.784176Z","message":{"role":"assistant","content":"","thinking":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.807439Z","message":{"role":"assistant","content":"","thinking":" argument"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.831056Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.853705Z","message":{"role":"assistant","content":"","thinking":" This"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.877279Z","message":{"role":"assistant","content":"","thinking":" satisfies"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.900871Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.924448Z","message":{"role":"assistant","content":"","thinking":" requirement"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.947538Z","message":{"role":"assistant","content":"","thinking":" of"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.97036Z","message":{"role":"assistant","content":"","thinking":" calling"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:23.99378Z","message":{"role":"assistant","content":"","thinking":" at"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.016898Z","message":{"role":"assistant","content":"","thinking":" least"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.039928Z","message":{"role":"assistant","content":"","thinking":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.06303Z","message":{"role":"assistant","content":"","thinking":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.086692Z","message":{"role":"assistant","content":"","thinking":" while"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.109959Z","message":{"role":"assistant","content":"","thinking":" using"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.133555Z","message":{"role":"assistant","content":"","thinking":" valid"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.156637Z","message":{"role":"assistant","content":"","thinking":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.180432Z","message":{"role":"assistant","content":"","thinking":" according"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.203629Z","message":{"role":"assistant","content":"","thinking":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.227043Z","message":{"role":"assistant","content":"","thinking":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.250468Z","message":{"role":"assistant","content":"","thinking":" schema"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.273903Z","message":{"role":"assistant","content":"","thinking":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.953449Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_koypk6tw","function":{"index":0,"name":"run_me","arguments":{"bar":"foo"}}}]},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:24.977474Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":36802325667,"load_duration":7033889209,"prompt_eval_count":344,"prompt_eval_duration":263755000,"eval_count":165,"eval_duration":3802990000} --- when: path: /api/chat @@ -170,7 +217,7 @@ when: "role": "assistant", "content": "", "tool_calls": [], - "thinking": "The user is asking me to run a tool with whatever arguments I want. Looking at the available tools, there's only one tool called \"run_me\" which takes no parameters according to its schema. This seems like a simple tool that doesn't require any specific arguments.\n\nLet me call this tool without any parameters since it has no required parameters and the user said \"whatever arguments you want\" - I'll just use none since none are available/needed." + "thinking": "I need to call a tool from my list of options based on the user request, which says \"Please run the tool\". I have one function called 'run_me' with these parameters:\n\n- bar (required): Can be string or array, but restricted to enum values [\"foo\", \"bar\"] - this is somewhat confusing since it can only take those two values\n- foo (optional): String type\n\nSince the user wants me to run a tool and I should use arguments if needed, let me call 'run_me' with bar=\"foo\" as an argument. This satisfies the requirement of calling at least one tool while using valid parameters according to the schema." }, { "role": "assistant", @@ -179,7 +226,9 @@ when: { "function": { "name": "run_me", - "arguments": {} + "arguments": { + "bar": "foo" + } } } ], @@ -202,32 +251,28 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.895075Z","message":{"role":"assistant","content":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.932883Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:53.970483Z","message":{"role":"assistant","content":" has"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.008047Z","message":{"role":"assistant","content":" executed"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.04566Z","message":{"role":"assistant","content":" successfully"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.08349Z","message":{"role":"assistant","content":" with"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.120568Z","message":{"role":"assistant","content":" `"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.157949Z","message":{"role":"assistant","content":"working"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.19532Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.233103Z","message":{"role":"assistant","content":"`."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.269642Z","message":{"role":"assistant","content":" Let"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.307278Z","message":{"role":"assistant","content":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.34429Z","message":{"role":"assistant","content":" know"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.381552Z","message":{"role":"assistant","content":" if"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.418983Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.456744Z","message":{"role":"assistant","content":"'d"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.493692Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.531369Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.56898Z","message":{"role":"assistant","content":" try"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.606486Z","message":{"role":"assistant","content":" different"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.64401Z","message":{"role":"assistant","content":" arguments"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.681556Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.718807Z","message":{"role":"assistant","content":" explore"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.756362Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.793725Z","message":{"role":"assistant","content":" functionalities"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.83134Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.94411Z","message":{"role":"assistant","content":" 🛠"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:54.981431Z","message":{"role":"assistant","content":"️"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:55.01841Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":32469853917,"load_duration":115329167,"prompt_eval_count":58,"prompt_eval_duration":247547417,"eval_count":31,"eval_duration":1078479878} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.179806Z","message":{"role":"assistant","content":"The"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.203815Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.22656Z","message":{"role":"assistant","content":" executed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.249526Z","message":{"role":"assistant","content":" successfully"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.272512Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.295517Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.318554Z","message":{"role":"assistant","content":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.341361Z","message":{"role":"assistant","content":" provided"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.364183Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.387601Z","message":{"role":"assistant","content":" Let"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.410682Z","message":{"role":"assistant","content":" me"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.434147Z","message":{"role":"assistant","content":" know"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.457174Z","message":{"role":"assistant","content":" if"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.480371Z","message":{"role":"assistant","content":" you"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.503409Z","message":{"role":"assistant","content":" need"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.526787Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.550311Z","message":{"role":"assistant","content":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.573682Z","message":{"role":"assistant","content":" it"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.596997Z","message":{"role":"assistant","content":" again"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.620139Z","message":{"role":"assistant","content":" or"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.643687Z","message":{"role":"assistant","content":" adjust"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.667025Z","message":{"role":"assistant","content":" any"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.690912Z","message":{"role":"assistant","content":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.714188Z","message":{"role":"assistant","content":"!"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:50.738226Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":25753110709,"load_duration":205563375,"prompt_eval_count":70,"prompt_eval_duration":274564000,"eval_count":25,"eval_duration":558314000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__conversation_stream.snap index c2963886d..d290ca676 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__conversation_stream.snap @@ -237,14 +237,16 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "reasoning": "The user is asking me to run a tool with whatever arguments I want. Looking at the available tools, there's only one tool called \"run_me\" which takes no parameters according to its schema. This seems like a simple tool that doesn't require any specific arguments.\n\nLet me call this tool without any parameters since it has no required parameters and the user said \"whatever arguments you want\" - I'll just use none since none are available/needed." + "reasoning": "I need to call a tool from my list of options based on the user request, which says \"Please run the tool\". I have one function called 'run_me' with these parameters:\n\n- bar (required): Can be string or array, but restricted to enum values [\"foo\", \"bar\"] - this is somewhat confusing since it can only take those two values\n- foo (optional): String type\n\nSince the user wants me to run a tool and I should use arguments if needed, let me call 'run_me' with bar=\"foo\" as an argument. This satisfies the requirement of calling at least one tool while using valid parameters according to the schema." }, { "timestamp": "2020-01-01 00:00:00.0", "type": "tool_call_request", "id": "run_me_2", "name": "run_me", - "arguments": {} + "arguments": { + "bar": "Zm9v" + } }, { "type": "config_delta", @@ -269,7 +271,7 @@ expression: v { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "The tool has executed successfully with `working!`. Let me know if you'd like to try different arguments or explore specific functionalities! 🛠️" + "message": "The tool executed successfully with the arguments provided. Let me know if you need to run it again or adjust any parameters!" } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__raw_events.snap index 60c900628..66ed6511c 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_required_reasoning__raw_events.snap @@ -7,168 +7,189 @@ expression: v Part { index: 0, part: Reasoning( - "The", + "I", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " user", + " need", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " is", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " asking", + " call", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " me", + " a", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " tool", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " run", + " from", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " a", + " my", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + " list", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " with", + " of", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " whatever", + " options", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " arguments", + " based", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " on", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " want", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + " user", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " Looking", + " request", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " at", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " the", + " which", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " available", + " says", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tools", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ",", + "Please", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " there", + " run", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'s", + " the", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " only", + " tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\".", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " have", ), metadata: {}, }, @@ -182,7 +203,7 @@ expression: v Part { index: 0, part: Reasoning( - " tool", + " function", ), metadata: {}, }, @@ -196,7 +217,7 @@ expression: v Part { index: 0, part: Reasoning( - " \"", + " '", ), metadata: {}, }, @@ -217,224 +238,224 @@ expression: v Part { index: 0, part: Reasoning( - "\"", + "'", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " which", + " with", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " takes", + " these", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " no", + " parameters", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " parameters", + ":", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " according", + "\n\n-", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " to", + " bar", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " its", + " (", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " schema", + "required", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "):", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " This", + " Can", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " seems", + " be", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " like", + " string", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " a", + " or", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " simple", + " array", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + ",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " that", + " but", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " doesn", + " restricted", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'t", + " to", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " require", + " enum", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " any", + " values", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " specific", + " [\"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " arguments", + "foo", ), metadata: {}, }, Part { index: 0, part: Reasoning( - ".", + "\",", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "\n\nLet", + " \"", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " me", + "bar", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " call", + "\"]", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " this", + " -", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " tool", + " this", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " without", + " is", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " any", + " somewhat", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " parameters", + " confusing", ), metadata: {}, }, @@ -455,35 +476,98 @@ expression: v Part { index: 0, part: Reasoning( - " has", + " can", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " no", + " only", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " required", + " take", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " parameters", + " those", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " and", + " two", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " values", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n-", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " foo", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " (", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "optional", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "):", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " String", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " type", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "\n\nSince", ), metadata: {}, }, @@ -504,21 +588,70 @@ expression: v Part { index: 0, part: Reasoning( - " said", + " wants", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " \"", + " me", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "whatever", + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " run", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " a", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " tool", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " and", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " I", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " should", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " use", ), metadata: {}, }, @@ -532,14 +665,98 @@ expression: v Part { index: 0, part: Reasoning( - " you", + " if", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " want", + " needed", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + ",", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " let", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " call", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " '", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "run", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "_me", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "'", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " with", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " bar", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "=\"", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + "foo", ), metadata: {}, }, @@ -553,84 +770,154 @@ expression: v Part { index: 0, part: Reasoning( - " -", + " as", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " I", + " an", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "'ll", + " argument", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " just", + ".", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " use", + " This", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " none", + " satisfies", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " since", + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " requirement", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " of", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " calling", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " at", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " none", + " least", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " are", + " one", ), metadata: {}, }, Part { index: 0, part: Reasoning( - " available", + " tool", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "/", + " while", ), metadata: {}, }, Part { index: 0, part: Reasoning( - "needed", + " using", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " valid", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " parameters", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " according", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " to", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " the", + ), + metadata: {}, + }, + Part { + index: 0, + part: Reasoning( + " schema", ), metadata: {}, }, @@ -659,7 +946,7 @@ expression: v index: 2, part: ToolCall( ArgumentChunk( - "{}", + "{\"bar\":\"foo\"}", ), ), metadata: {}, @@ -695,13 +982,6 @@ expression: v ), metadata: {}, }, - Part { - index: 1, - part: Message( - " has", - ), - metadata: {}, - }, Part { index: 1, part: Message( @@ -726,28 +1006,28 @@ expression: v Part { index: 1, part: Message( - " `", + " the", ), metadata: {}, }, Part { index: 1, part: Message( - "working", + " arguments", ), metadata: {}, }, Part { index: 1, part: Message( - "!", + " provided", ), metadata: {}, }, Part { index: 1, part: Message( - "`.", + ".", ), metadata: {}, }, @@ -789,14 +1069,7 @@ expression: v Part { index: 1, part: Message( - "'d", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - " like", + " need", ), metadata: {}, }, @@ -810,21 +1083,21 @@ expression: v Part { index: 1, part: Message( - " try", + " run", ), metadata: {}, }, Part { index: 1, part: Message( - " different", + " it", ), metadata: {}, }, Part { index: 1, part: Message( - " arguments", + " again", ), metadata: {}, }, @@ -838,21 +1111,21 @@ expression: v Part { index: 1, part: Message( - " explore", + " adjust", ), metadata: {}, }, Part { index: 1, part: Message( - " specific", + " any", ), metadata: {}, }, Part { index: 1, part: Message( - " functionalities", + " parameters", ), metadata: {}, }, @@ -863,20 +1136,6 @@ expression: v ), metadata: {}, }, - Part { - index: 1, - part: Message( - " 🛠", - ), - metadata: {}, - }, - Part { - index: 1, - part: Message( - "\u{fe0f}", - ), - metadata: {}, - }, Flush { index: 1, metadata: {}, diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.snap index 5b0098006..bab380c1c 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.snap @@ -11,23 +11,23 @@ expression: v ToolCallRequest { id: "run_me_2", name: "run_me", - arguments: {}, + arguments: { + "bar": Array [ + String("foo"), + ], + "foo": String("foo"), + }, }, ), metadata: {}, }, ), - Finished( - Completed, - ), - ], - [ Flushed( ConversationEvent { timestamp: 2020-01-01 0:00:00.0 +00, kind: ChatResponse( Message { - message: "The tool ran successfully! It output: `working!`. \n\nIs there a specific task or calculation you'd like me to try next? 😊", + message: "I will use default parameters to run the tool. I'll select 'foo' from the allowed options for both arguments, with one as a string and one as an array containing that same option.", }, ), metadata: {}, @@ -37,4 +37,5 @@ expression: v Completed, ), ], + [], ] diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.yml b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.yml index 78253d4dd..4c49faf82 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.yml +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream.yml @@ -19,26 +19,32 @@ when: "name": "run_me", "description": "", "parameters": { - "foo": { - "type": "string", - "default": "foo" - }, - "bar": { - "type": [ - "string", - "array" - ], - "enum": [ - "foo", - [ - "foo", - "bar" - ] - ], - "items": { - "type": "string" + "type": "object", + "properties": { + "foo": { + "type": "string", + "default": "foo" + }, + "bar": { + "type": [ + "string", + "array" + ], + "enum": [ + "foo" + ], + "items": { + "type": "string", + "enum": [ + "foo", + "bar" + ] + } } - } + }, + "required": [ + "bar" + ] } } } @@ -53,78 +59,44 @@ then: - name: content-type value: application/x-ndjson body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:25.617827Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_7bvei3gw","function":{"index":0,"name":"run_me","arguments":{}}}]},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:52:25.655451Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":31219243500,"load_duration":297562375,"prompt_eval_count":253,"prompt_eval_duration":720474042,"eval_count":15,"eval_duration":506783416} ---- -when: - path: /api/chat - method: POST - json_body_str: >- - { - "model": "qwen3.5:9b", - "messages": [ - { - "role": "user", - "content": "Please run the tool, providing whatever arguments you want.", - "tool_calls": [], - "thinking": null - }, - { - "role": "assistant", - "content": "", - "tool_calls": [ - { - "function": { - "name": "run_me", - "arguments": {} - } - } - ], - "thinking": null - }, - { - "role": "tool", - "content": "working!", - "tool_calls": [], - "thinking": null - } - ], - "options": {}, - "stream": true, - "think": false - } -then: - status: 200 - header: - - name: content-type - value: application/x-ndjson - body: | - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.113361Z","message":{"role":"assistant","content":"The"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.151291Z","message":{"role":"assistant","content":" tool"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.189773Z","message":{"role":"assistant","content":" ran"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.227847Z","message":{"role":"assistant","content":" successfully"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.263722Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.301454Z","message":{"role":"assistant","content":" It"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.338364Z","message":{"role":"assistant","content":" output"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.375853Z","message":{"role":"assistant","content":":"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.413524Z","message":{"role":"assistant","content":" `"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.451132Z","message":{"role":"assistant","content":"working"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.488651Z","message":{"role":"assistant","content":"!"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.526291Z","message":{"role":"assistant","content":"`."},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.601407Z","message":{"role":"assistant","content":" \n\nIs"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.639158Z","message":{"role":"assistant","content":" there"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.676622Z","message":{"role":"assistant","content":" a"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.713976Z","message":{"role":"assistant","content":" specific"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.751552Z","message":{"role":"assistant","content":" task"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.789227Z","message":{"role":"assistant","content":" or"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.826771Z","message":{"role":"assistant","content":" calculation"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.864244Z","message":{"role":"assistant","content":" you"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.901938Z","message":{"role":"assistant","content":"'d"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.93872Z","message":{"role":"assistant","content":" like"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:00.976413Z","message":{"role":"assistant","content":" me"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:01.014098Z","message":{"role":"assistant","content":" to"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:01.051778Z","message":{"role":"assistant","content":" try"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:01.08944Z","message":{"role":"assistant","content":" next"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:01.127356Z","message":{"role":"assistant","content":"?"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:01.20299Z","message":{"role":"assistant","content":" 😊"},"done":false} - {"model":"qwen3.5:9b","created_at":"2026-03-06T14:53:01.240788Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":35579007250,"load_duration":118539875,"prompt_eval_count":53,"prompt_eval_duration":246718208,"eval_count":31,"eval_duration":1081688374} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.497317Z","message":{"role":"assistant","content":"I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.521123Z","message":{"role":"assistant","content":" will"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.543773Z","message":{"role":"assistant","content":" use"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.566214Z","message":{"role":"assistant","content":" default"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.588622Z","message":{"role":"assistant","content":" parameters"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.611004Z","message":{"role":"assistant","content":" to"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.633947Z","message":{"role":"assistant","content":" run"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.657099Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.680746Z","message":{"role":"assistant","content":" tool"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.703819Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.727396Z","message":{"role":"assistant","content":" I"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.750673Z","message":{"role":"assistant","content":"'ll"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.774481Z","message":{"role":"assistant","content":" select"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.798621Z","message":{"role":"assistant","content":" '"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.822269Z","message":{"role":"assistant","content":"foo"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.845948Z","message":{"role":"assistant","content":"'"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.869156Z","message":{"role":"assistant","content":" from"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.892948Z","message":{"role":"assistant","content":" the"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.916392Z","message":{"role":"assistant","content":" allowed"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.9392Z","message":{"role":"assistant","content":" options"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.961799Z","message":{"role":"assistant","content":" for"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:16.984953Z","message":{"role":"assistant","content":" both"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.008034Z","message":{"role":"assistant","content":" arguments"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.031615Z","message":{"role":"assistant","content":","},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.054815Z","message":{"role":"assistant","content":" with"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.078506Z","message":{"role":"assistant","content":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.101703Z","message":{"role":"assistant","content":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.12524Z","message":{"role":"assistant","content":" a"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.148005Z","message":{"role":"assistant","content":" string"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.171389Z","message":{"role":"assistant","content":" and"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.194713Z","message":{"role":"assistant","content":" one"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.21792Z","message":{"role":"assistant","content":" as"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.241507Z","message":{"role":"assistant","content":" an"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.264622Z","message":{"role":"assistant","content":" array"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.288285Z","message":{"role":"assistant","content":" containing"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.311537Z","message":{"role":"assistant","content":" that"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.335338Z","message":{"role":"assistant","content":" same"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.358641Z","message":{"role":"assistant","content":" option"},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:17.38239Z","message":{"role":"assistant","content":"."},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:18.335011Z","message":{"role":"assistant","content":"","tool_calls":[{"id":"call_9t1uu00k","function":{"index":0,"name":"run_me","arguments":{"bar":["foo"],"foo":"foo"}}}]},"done":false} + {"model":"qwen3.5:9b","created_at":"2026-08-21T10:17:18.357621Z","message":{"role":"assistant","content":""},"done":true,"done_reason":"stop","total_duration":30182249250,"load_duration":7033416708,"prompt_eval_count":306,"prompt_eval_duration":87276000,"eval_count":81,"eval_duration":1860224000} diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__conversation_stream.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__conversation_stream.snap index 5a1e57629..02dc42d89 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__conversation_stream.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__conversation_stream.snap @@ -223,19 +223,17 @@ expression: v "type": "tool_call_request", "id": "run_me_2", "name": "run_me", - "arguments": {} - }, - { - "timestamp": "2020-01-01 00:00:00.0", - "type": "tool_call_response", - "id": "run_me_2", - "content": "d29ya2luZyE=", - "is_error": false + "arguments": { + "bar": [ + "Zm9v" + ], + "foo": "Zm9v" + } }, { "timestamp": "2020-01-01 00:00:00.0", "type": "chat_response", - "message": "The tool ran successfully! It output: `working!`. \n\nIs there a specific task or calculation you'd like me to try next? 😊" + "message": "I will use default parameters to run the tool. I'll select 'foo' from the allowed options for both arguments, with one as a string and one as an array containing that same option." } ] } diff --git a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__raw_events.snap b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__raw_events.snap index 2122dfce7..c113f0fc7 100644 --- a/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__raw_events.snap +++ b/crates/jp_llm/tests/fixtures/ollama/test_tool_call_stream__raw_events.snap @@ -9,45 +9,58 @@ expression: v metadata: {}, }, Part { - index: 2, - part: ToolCall( - Start { - id: "run_me_2", - name: "run_me", - }, + index: 1, + part: Message( + "I", ), metadata: {}, }, Part { - index: 2, - part: ToolCall( - ArgumentChunk( - "{}", - ), + index: 1, + part: Message( + " will", ), metadata: {}, }, - Flush { - index: 2, + Part { + index: 1, + part: Message( + " use", + ), metadata: {}, }, - Flush { + Part { index: 1, + part: Message( + " default", + ), metadata: {}, }, - Finished( - Completed, - ), - ], - [ - Flush { - index: 0, + Part { + index: 1, + part: Message( + " parameters", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " to", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " run", + ), metadata: {}, }, Part { index: 1, part: Message( - "The", + " the", ), metadata: {}, }, @@ -61,185 +74,236 @@ expression: v Part { index: 1, part: Message( - " ran", + ".", ), metadata: {}, }, Part { index: 1, part: Message( - " successfully", + " I", ), metadata: {}, }, Part { index: 1, part: Message( - "!", + "'ll", ), metadata: {}, }, Part { index: 1, part: Message( - " It", + " select", ), metadata: {}, }, Part { index: 1, part: Message( - " output", + " '", ), metadata: {}, }, Part { index: 1, part: Message( - ":", + "foo", ), metadata: {}, }, Part { index: 1, part: Message( - " `", + "'", ), metadata: {}, }, Part { index: 1, part: Message( - "working", + " from", ), metadata: {}, }, Part { index: 1, part: Message( - "!", + " the", ), metadata: {}, }, Part { index: 1, part: Message( - "`.", + " allowed", ), metadata: {}, }, Part { index: 1, part: Message( - " \n\nIs", + " options", ), metadata: {}, }, Part { index: 1, part: Message( - " there", + " for", ), metadata: {}, }, Part { index: 1, part: Message( - " a", + " both", ), metadata: {}, }, Part { index: 1, part: Message( - " specific", + " arguments", ), metadata: {}, }, Part { index: 1, part: Message( - " task", + ",", ), metadata: {}, }, Part { index: 1, part: Message( - " or", + " with", ), metadata: {}, }, Part { index: 1, part: Message( - " calculation", + " one", ), metadata: {}, }, Part { index: 1, part: Message( - " you", + " as", ), metadata: {}, }, Part { index: 1, part: Message( - "'d", + " a", ), metadata: {}, }, Part { index: 1, part: Message( - " like", + " string", ), metadata: {}, }, Part { index: 1, part: Message( - " me", + " and", ), metadata: {}, }, Part { index: 1, part: Message( - " to", + " one", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " as", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " an", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " array", + ), + metadata: {}, + }, + Part { + index: 1, + part: Message( + " containing", ), metadata: {}, }, Part { index: 1, part: Message( - " try", + " that", ), metadata: {}, }, Part { index: 1, part: Message( - " next", + " same", ), metadata: {}, }, Part { index: 1, part: Message( - "?", + " option", ), metadata: {}, }, Part { index: 1, part: Message( - " 😊", + ".", + ), + metadata: {}, + }, + Part { + index: 2, + part: ToolCall( + Start { + id: "run_me_2", + name: "run_me", + }, ), metadata: {}, }, + Part { + index: 2, + part: ToolCall( + ArgumentChunk( + "{\"bar\":[\"foo\"],\"foo\":\"foo\"}", + ), + ), + metadata: {}, + }, + Flush { + index: 2, + metadata: {}, + }, Flush { index: 1, metadata: {}, @@ -248,4 +312,5 @@ expression: v Completed, ), ], + [], ] diff --git a/docs/features/tools.md b/docs/features/tools.md index 3669de044..e0f9b7a90 100644 --- a/docs/features/tools.md +++ b/docs/features/tools.md @@ -1 +1,342 @@ # Workspace Tools + +Tools let the assistant call programs and services while working on a +conversation. +Each tool is configured under `conversation.tools.`, where `` is the +name sent to the model. + +Tool configuration follows the normal [configuration loading and ordering +rules]. +A later layer can override one field without repeating the rest of the tool +definition. + +## Tool Sources + +Every tool has a `source`: + +| Source | Definition | +| --------------------- | ------------------------------------------------------------------------------- | +| `builtin` | Implemented inside JP. | +| `local` | Runs a configured command. JP configuration defines its parameters. | +| `mcp.` | Uses the same-named tool from an MCP server. The server defines its parameters. | +| `mcp..` | Uses a differently named tool from an MCP server. This allows a local alias. | + +For example, a local tool starts with a complete definition: + +```toml +[conversation.tools.word_count] +source = "local" +command = "word-count {{tool.arguments.path}}" +summary = "Count the words in a file." + +[conversation.tools.word_count.parameters.path] +type = "string" +required = true +summary = "File to count." +``` + +An MCP tool points at a configured server: + +```toml +[conversation.tools.create_note] +source = "mcp.notes.create_note" +``` + +JP fetches the MCP tool definition from the server when resolving the tools for +a query. + +## Parameter Schemas + +A parameter schema describes one argument the model may send in a tool call. +Local tool definitions need complete parameter schemas. +JP supplies schemas for built-in tools. +MCP tools inherit their schemas from the server and use configuration only for +overrides. + +Supported JSON types are: + +- `array` +- `boolean` +- `integer` +- `null` +- `number` +- `object` +- `string` + +The available settings are: + +| Setting | Meaning | +| ------------- | ------------------------------------------------------------------------------------------------------------------ | +| `type` | Accepted JSON type, or an array of accepted types. | +| `required` | Whether the argument must be present. | +| `default` | Default advertised to the model. JP fills omitted local-tool arguments; MCP servers handle omitted MCP arguments. | +| `enum` | Complete values accepted by this schema node. | +| `summary` | Short description included in the schema sent to the model. | +| `description` | Detailed documentation available through `describe_tools`. Used as the schema description when `summary` is unset. | +| `examples` | Usage examples available through `describe_tools`. | +| `items` | Schema applied to every element of an array. | +| `properties` | Schemas for fields of an object. | + +### Arrays + +An array must define `items`: + +```toml +[conversation.tools.my_tool.parameters.tags] +type = "array" +required = true +summary = "Tags to attach." + +[conversation.tools.my_tool.parameters.tags.items] +type = "string" +``` + +The dotted form is equivalent and is convenient for short schemas: + +```toml +[conversation.tools.my_tool.parameters.tags] +type = "array" +items.type = "string" +``` + +### Objects + +Object fields live under `properties` and may contain their own arrays or +objects: + +```toml +[conversation.tools.my_tool.parameters.target] +type = "object" +required = true + +[conversation.tools.my_tool.parameters.target.properties.path] +type = "string" +required = true + +[conversation.tools.my_tool.parameters.target.properties.labels] +type = "array" +items.type = "string" +``` + +## MCP Parameter Overrides + +MCP configuration is an overlay on the server schema. +The server's schema is the source of truth: JP keeps it as written and applies +only the fields configuration sets, so anything left unset is inherited. + +For example, suppose an MCP server defines `tags` as an array of strings. +JP can restrict the allowed tags without repeating either type: + +```toml +[conversation.tools.bear_note_create] +source = "mcp.grizzly" + +[conversation.tools.bear_note_create.parameters.tags.items] +enum = ["projects/jp", "task", "idea"] +``` + +The effective schema is: + +```json +{ + "type": "array", + "items": { + "type": "string", + "enum": ["projects/jp", "task", "idea"] + } +} +``` + +Repeating inherited types is accepted when they match the server: + +```toml +[conversation.tools.bear_note_create.parameters.tags] +type = "array" + +[conversation.tools.bear_note_create.parameters.tags.items] +type = "string" +enum = ["projects/jp", "task", "idea"] +``` + +The override rules are: + +- `type` may be omitted. + If set, it must declare the same type set as the MCP schema. + Order does not matter, and a single-element array is equivalent to the bare + string, so `["null", "string"]`, `["string", "null"]`, and `"string"` are + interchangeable. +- `required = true` may make an optional server parameter required. +- `required = false` cannot make a server-required parameter optional. +- An unset `enum` inherits the server enum. +- `enum = []` removes an inherited enum. +- `items` and `properties` merge recursively, so a nested override does not + replace the rest of the inherited shape. + +### Referenced Types + +Servers usually send named types by reference. +An enum parameter arrives as `{"$ref": "#/$defs/EntryType"}`, with the +definition in a `$defs` block at the root of the tool's schema, and an optional +nested struct arrives as `anyOf` with a `$ref` branch and a `null` branch. + +The schema reaches the model provider as the server wrote it, references +included. +JP reads through same-document pointers when it validates and when it checks +arguments, so a referenced enum constrains values exactly as an inline one +would, and nothing has to be restated in configuration. + +An override may narrow a referenced parameter without expanding it. +Setting `items.enum` on an array whose item type is a reference adds the enum +next to the reference and leaves the definition alone. + +A reference JP cannot resolve, meaning anything that does not point into the +tool's own document, leaves that node without a usable type. +Describe the parameter in configuration when that happens. + +### Provider Differences + +Providers accept different subsets of JSON Schema, and each one adapts the +schema itself. +OpenAI, Google, Anthropic, Cerebras, OpenRouter, and llama.cpp all accept +references and definitions. +Ollama does not, so its schemas are expanded before the request is sent. +It also ignores keywords outside a small set, keeping `type`, `description`, +`enum`, `items`, `anyOf`, `properties` and `required`, so constraints such as +`default` or `pattern` do not reach a model served through it. + +Recursive types, where a definition refers to itself, are forwarded as written. +Anthropic and Cerebras reject them, and the error comes from the API rather than +from JP, so no configuration change is needed if they add support later. +Expanding one for Ollama is not possible either, so its innermost reference is +left in place. + +## Enum Scope + +`enum` always constrains the value at the location where it appears. + +For a scalar parameter, put it on the parameter: + +```toml +[conversation.tools.my_tool.parameters.action] +type = "string" +enum = ["create", "update", "delete"] +``` + +For array elements, put it under `items`: + +```toml +[conversation.tools.my_tool.parameters.tags] +type = "array" +items.type = "string" +items.enum = ["task", "idea"] +``` + +An enum directly on an array constrains complete arrays. +Every enum value must therefore be an array: + +```toml +[conversation.tools.my_tool.parameters.tags] +type = "array" +items.type = "string" +enum = [ + ["task"], + ["task", "idea"], +] +``` + +This accepts exactly `["task"]` and `["task", "idea"]`. +It does not mean that `"task"` and `"idea"` are independently valid elements. + +A single enum value can force one exact value: + +```toml +[conversation.tools.my_tool.parameters.format] +type = "string" +enum = ["json"] +``` + +## Parameters And Options + +Parameters are controlled by the model and appear in tool call arguments. +Options are static user configuration passed to the tool at runtime. + +Each tool defines which options it accepts. +For example, a tool that documents a `mode` option could be configured as: + +```toml +[conversation.tools.my_tool.options] +mode = "strict" +``` + +Use `parameters` for the model-facing interface. +Use `options` for behavior that the user selects and the model must not change. + +## Schema Validation + +JP validates the effective schema after local configuration or MCP overrides +have been resolved and before sending a request to a model provider. +Validation rejects: + +- Unsupported or duplicate type names. +- Local and built-in parameters without a type. +- Arrays without an item schema. +- `items` on a non-array type. +- `properties` on a non-object type. +- Duplicate or type-incompatible enum values. +- Defaults that the parameter, item, or property schema rejects, including a + default outside an `enum`. +- MCP type overrides that disagree with the server. + +Errors include the tool and parameter path: + +```text +Invalid schema at `conversation.tools.bear_note_create.parameters.tags.enum`: +enum value "projects/jp" has type string, but the schema requires array; use +`conversation.tools.bear_note_create.parameters.tags.items.enum` to constrain +array elements +``` + +The path is a full configuration key, so it can be pasted into a TOML table +header or a `--cfg` assignment. + +This validation happens before the provider request, so a bad schema does not +become an HTTP error from the model provider. + +A tool whose schema fails validation is dropped from the request and the rest of +the query proceeds, the same way a tool backed by an unavailable MCP server is +dropped. +The reason is logged at warning level, which the terminal does not show by +default, so run with `-v` when a tool you expect is missing. + +Naming that tool with `--tool` is the exception. +Asking for a tool explicitly and receiving a request without it is worse than an +error, so JP fails the query instead. + +## Compatibility Notes + +Existing scalar parameters and complete local schemas keep the same syntax. +Existing MCP overrides that repeat matching types also remain valid. + +Configurations need attention when they rely on one of these forms: + +- A scalar enum placed directly on an array. + Move it to `items.enum`. +- An MCP override that changes a server-declared type. + Match the server type or remove the redundant override. +- An array without `items`, or a local parameter without `type`. + Complete the schema so JP can validate it locally. +- An array enum containing complete arrays that depended on provider-specific + flattening. + Complete-array enums retain their JSON Schema meaning; use `items.enum` to + constrain individual elements. +- `enum = []` on an MCP parameter. + This explicitly removes the inherited enum; omit the setting to inherit it. +- An override that exists only to restate a referenced type, such as an + `items.type` added because JP could not read `$defs`. + Referenced types now resolve on their own, and dropping the override lets the + server's allowed values through as a real `enum`. +- A narrowed `enum` on a parameter whose inherited `default` falls outside the + narrowed set. + Override `default` as well, or widen the `enum` to include it. + +[configuration loading and ordering rules]: ../configuration.md