Run the full compaction process using LLM summarization. Mirrors TS `SessionCompaction.process`. Creates an assistant message with full metadata, fires the `experimental.session.compacting` plugin hook (with context injection), converts messages via `to_model_messages()`, runs the LLM, and handles auto-continue.
(
&self,
input: CompactionInput,
provider: Arc<dyn Provider>,
session_ops: Option<&S>,
)
| 402 | /// hook (with context injection), converts messages via |
| 403 | /// `to_model_messages()`, runs the LLM, and handles auto-continue. |
| 404 | pub async fn process<S: SessionOps>( |
| 405 | &self, |
| 406 | input: CompactionInput, |
| 407 | provider: Arc<dyn Provider>, |
| 408 | session_ops: Option<&S>, |
| 409 | ) -> anyhow::Result<CompactionResult> { |
| 410 | tracing::info!( |
| 411 | session_id = %input.session_id, |
| 412 | parent_id = %input.parent_id, |
| 413 | auto = input.auto, |
| 414 | "Starting compaction process" |
| 415 | ); |
| 416 | |
| 417 | let now_ms = Utc::now().timestamp_millis(); |
| 418 | |
| 419 | // TS: const msg = await Session.updateMessage({ ... role: "assistant", summary: true, ... }) |
| 420 | // Create the assistant message with full metadata. |
| 421 | let assistant_id = |
| 422 | opencode_core::id::create(opencode_core::id::Prefix::Message, false, None); |
| 423 | let assistant_info = MessageInfo::Assistant { |
| 424 | id: assistant_id.clone(), |
| 425 | session_id: input.session_id.clone(), |
| 426 | time: AssistantTime { |
| 427 | created: now_ms, |
| 428 | completed: None, |
| 429 | }, |
| 430 | parent_id: input.parent_id.clone(), |
| 431 | model_id: input.model.model_id.clone(), |
| 432 | provider_id: input.model.provider_id.clone(), |
| 433 | mode: "compaction".to_string(), |
| 434 | agent: "compaction".to_string(), |
| 435 | path: MessagePath { |
| 436 | cwd: input.cwd.clone().unwrap_or_default(), |
| 437 | root: input.root.clone().unwrap_or_default(), |
| 438 | }, |
| 439 | summary: Some(true), |
| 440 | cost: 0.0, |
| 441 | tokens: AssistantTokens { |
| 442 | total: None, |
| 443 | input: 0, |
| 444 | output: 0, |
| 445 | reasoning: 0, |
| 446 | cache: CacheTokens { read: 0, write: 0 }, |
| 447 | }, |
| 448 | error: None, |
| 449 | structured: None, |
| 450 | variant: input.variant.clone(), |
| 451 | finish: None, |
| 452 | }; |
| 453 | |
| 454 | // Persist the assistant message if session ops are available. |
| 455 | if let Some(ops) = session_ops { |
| 456 | let _ = ops.update_message(assistant_info.clone()).await; |
| 457 | } |
| 458 | |
| 459 | // TS: const compacting = await Plugin.trigger("experimental.session.compacting", ...) |
| 460 | // Fire the plugin hook and collect context / prompt override. |
| 461 | let hook_ctx = HookContext::new(HookEvent::SessionCompacting) |