Process a single model-type queue item: build prompt, call LLM, update row.
(item: &QueueItem)
| 167 | |
| 168 | /// Process a single model-type queue item: build prompt, call LLM, update row. |
| 169 | fn process_model_queue_item(item: &QueueItem) -> Result<(), String> { |
| 170 | let api_key = crate::GUC_API_KEY |
| 171 | .get() |
| 172 | .ok_or("pgclaw.api_key not set")? |
| 173 | .to_str() |
| 174 | .map_err(|_| "pgclaw.api_key is not valid UTF-8")? |
| 175 | .to_string(); |
| 176 | |
| 177 | let provider = crate::get_provider(); |
| 178 | let api_url = crate::get_api_url(); |
| 179 | |
| 180 | // Resolve agent config |
| 181 | let (model, system_prompt) = resolve_agent_config(item)?; |
| 182 | |
| 183 | // Load conversation history |
| 184 | let history = load_row_history(item); |
| 185 | |
| 186 | // Build user message with row context |
| 187 | let user_content = format!( |
| 188 | "Event: {} on table (oid={}), row pk={}.\n\nCurrent row state:\n{}\n\nRespond with a JSON object of columns to update, e.g. {{\"column\": \"value\"}}.\nOr {{}} if no changes needed.\nTo update agent memory, include {{\"__memory\": {{...}}}}.", |
| 189 | item.event, item.table_oid.as_u32(), item.pk_value, item.row_data |
| 190 | ); |
| 191 | |
| 192 | // Build messages array |
| 193 | let mut messages: Vec<http::Message> = Vec::new(); |
| 194 | for h in &history { |
| 195 | messages.push(h.clone()); |
| 196 | } |
| 197 | messages.push(http::Message { |
| 198 | role: "user".to_string(), |
| 199 | content: user_content.clone(), |
| 200 | }); |
| 201 | |
| 202 | // Call LLM |
| 203 | let response = http::call_llm(&provider, &api_key, api_url.as_deref(), &model, &system_prompt, &messages, 1024)?; |
| 204 | |
| 205 | // Record in history |
| 206 | BackgroundWorker::transaction(|| { |
| 207 | Spi::run(&format!( |
| 208 | "INSERT INTO claw.history (table_oid, pk_value, claw_col, role, content) |
| 209 | VALUES ({}, '{}', '{}', 'user', '{}')", |
| 210 | item.table_oid.as_u32(), |
| 211 | item.pk_value.replace('\'', "''"), |
| 212 | item.claw_col.replace('\'', "''"), |
| 213 | user_content.replace('\'', "''") |
| 214 | )) |
| 215 | .expect("SPI failed"); |
| 216 | |
| 217 | Spi::run(&format!( |
| 218 | "INSERT INTO claw.history (table_oid, pk_value, claw_col, role, content) |
| 219 | VALUES ({}, '{}', '{}', 'assistant', '{}')", |
| 220 | item.table_oid.as_u32(), |
| 221 | item.pk_value.replace('\'', "''"), |
| 222 | item.claw_col.replace('\'', "''"), |
| 223 | response.replace('\'', "''") |
| 224 | )) |
| 225 | .expect("SPI failed"); |
| 226 | }); |
no test coverage detected